Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Використання SurfaceTool
SurfaceTool надає корисний інтерфейс для побудови геометрії. Інтерфейс подібний до класу ImmediateMesh. Ви встановлюєте кожен атрибут для кожної вершини (наприклад, normal, uv, color), а потім, коли ви додаєте вершину, вона фіксує атрибути.
SurfaceTool також має такі корисні функції як index() (використовувати індекс вершин) і generate_normals() (автоматично задати нормалі).
Атрибути потрібно додавати перед тим як додавати вершину:
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_normal() # Overwritten by normal below.
st.set_normal() # Added to next vertex.
st.set_color() # Added to next vertex.
st.add_vertex() # Captures normal and color above.
st.set_normal() # Normal never added to a vertex.
st.SetNormal(); // Overwritten by normal below.
st.SetNormal(); // Added to next vertex.
st.SetColor(); // Added to next vertex.
st.AddVertex(); // Captures normal and color above.
st.SetNormal(); // Normal never added to a vertex.
Після завершення генерації геометрії за допомогою SurfaceTool, викличте commit(), щоб завершити генерацію сітки. Якщо до commit() передається ArrayMesh, то він додає нову поверхню в кінець ArrayMesh. Якщо ж нічого не передається, commit() повертає ArrayMesh.
# Add surface to existing ArrayMesh.
st.commit(mesh)
# -- Or Alternatively --
# Create new ArrayMesh.
var mesh = st.commit()
st.Commit(mesh);
// Or:
var mesh = st.Commit();
Наведений нижче код створює трикутник без індексів.
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
st.add_vertex(Vector3(-1, -1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(0, 1))
st.add_vertex(Vector3(-1, 1, 0))
st.set_normal(Vector3(0, 0, 1))
st.set_uv(Vector2(1, 1))
st.add_vertex(Vector3(1, 1, 0))
# Commit to a mesh.
var mesh = st.commit()
var st = new SurfaceTool();
st.Begin(Mesh.PrimitiveType.Triangles);
// Prepare attributes for AddVertex.
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 0));
// Call last for each vertex, adds the above attributes.
st.AddVertex(new Vector3(-1, -1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(0, 1));
st.AddVertex(new Vector3(-1, 1, 0));
st.SetNormal(new Vector3(0, 0, 1));
st.SetUV(new Vector2(1, 1));
st.AddVertex(new Vector3(1, 1, 0));
// Commit to a mesh.
var mesh = st.Commit();
Ви можете додатково додати індексний масив, або викликавши add_index() та додавши вершини до індексного масиву вручну, або викликавши index() один раз, що автоматично генерує індексний масив та стискає масив вершин, щоб видалити дублікати вершин.
# Suppose we have a quad defined by 6 vertices as follows
st.add_vertex(Vector3(-1, 1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(-1, -1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(1, -1, 0))
st.add_vertex(Vector3(-1, -1, 0))
# We can make the quad more efficient by using an index array and only utilizing 4 vertices:
st.add_vertex(Vector3(-1, 1, 0))
st.add_vertex(Vector3(1, 1, 0))
st.add_vertex(Vector3(-1, -1, 0))
st.add_vertex(Vector3(1, -1, 0))
# Creates a quad from four corner vertices.
# add_index() can be called before or after add_vertex()
# since it's not an attribute of a vertex itself.
st.add_index(0)
st.add_index(1)
st.add_index(2)
st.add_index(1)
st.add_index(3)
st.add_index(2)
# Alternatively we can use ``st.index()`` which will create the quad for us and remove the duplicate vertices
st.index()
// Suppose we have a quad defined by 6 vertices as follows.
st.AddVertex(new Vector3(-1, 1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(1, -1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
// We can make the quad more efficient by using an index array and only utilizing 4 vertices:
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
st.AddVertex(new Vector3(-1, -1, 0));
st.AddVertex(new Vector3(1, 1, 0));
// Creates a quad from four corner vertices.
// AddIndex does not need to be called before AddVertex.
st.AddIndex(0);
st.AddIndex(1);
st.AddIndex(2);
st.AddIndex(1);
st.AddIndex(3);
st.AddIndex(2);
// Alternatively we can use `st.Index()` which will create the quad for us and remove the duplicate vertices.
st.Index();
Схожим чином, якщо у вас є список індексів вершин, але ви хочете щоб вершини кожного трикутника була окремими (бо ви хочете задавати нормалі та колір трикутникам а не вершинам), то ви можете використати deindex().
st.deindex()
st.Deindex();
Якщо ви не додали нормалей самостійно, то ви можете зробити це з функцією generate_normals(), яка повинна викликатись після того як геометрія була створена, але ще не записана до об'єкта функціями commit() чи commit_to_arrays(). Виклик generate_normals(true) виверне нормалі навиворіт. Між іншим, generate_normals() працює лише тоді, коли тип геометрії заданий як Mesh.PRIMITIVE_TRIANGLES.
Ви можете помітити, що звичайне відображення або інші властивості матеріалу виглядають порушеними на створеній сітці. Це тому, що нормальне відображення вимагає, щоб сітка мала дотичні, які є окремими від нормалей. Ви можете додати власні дотичні вручну або створити їх автоматично за допомогою generate_tangents(). Цей метод вимагає, щоб кожна вершина вже мала встановлені UV і нормалі.
st.generate_normals()
st.generate_tangents()
st.commit(mesh)
st.GenerateNormals();
st.GenerateTangents();
За замовчуванням, під час генерації нормалей, вони будуть обчислюватися для кожної вершини (тобто це будуть "гладкі нормалі"). Якщо вам потрібні плоскі вершинні нормалі (тобто один вектор нормалі на грань), під час додавання вершин викличте add_smooth_group(i), де i — це унікальне число на вершину. add_smooth_group() потрібно викликати під час побудови геометрії, наприклад, перед викликом add_vertex().