Использование SurfaceTool
SurfaceTool предоставляет удобный интерфейс для создания геометрии. Этот интерфейс похож на класс ImmediateMesh. Вы задаёте атрибуты для каждой вершины (например, нормаль, UV-координаты, цвет), а при добавлении вершины она захватывает эти атрибуты.
SurfaceTool также предоставляет некоторые полезные вспомогательные функции, такие как index() и generate_normals().
Атрибуты добавляются перед добавлением каждой вершины:
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(), чтобы завершить генерацию сетки. Если ArrayMesh передается в commit(), то он добавляет новую поверхность в конец ArrayMesh. В то время как, если ничего не передано, commit() возвращает ArrayMesh.
st.commit(mesh)
# Or:
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(), который сжимает массив вершин для удаления повторяющихся вершин.
# Creates a quad from four corner vertices.
# add_index does not need to be called before add_vertex.
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:
st.index()
// 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:
st.Index();
Аналогично, если у вас есть массив индексов, но вы хотите, чтобы каждая вершина была уникальной (например, потому что вы хотите использовать уникальные нормали или цвета для каждой грани, а не для каждой вершины), вы можете вызвать deindex().
st.deindex()
st.Deindex();
Если вы не добавляете пользовательские нормали самостоятельно, вы можете добавить их с помощью generate_normals(0), который следует вызывать после генерации геометрии и перед фиксацией сетки с помощью commit() или commit_to_arrays(). Вызов generate_normals(true) перевернет результирующие нормали. В качестве дополнительного примечания, generate_normals() работает только в том случае, если для примитивного типа задано значение "Mesh.PRIMITIVE_TRIANGLES`.
Вы можете заметить, что нормалмаппинг или другие свойства материала выглядят некорректно на сгенерированной сетке. Это происходит потому, что нормалмаппинг требует наличия касательных в сетке, которые отличаются от нормалей. Вы можете либо добавить пользовательские касательные вручную, либо автоматически сгенерировать их с помощью generate_tangents(). Этот метод требует, чтобы для каждой вершины уже были заданы UV-координаты и нормали.
st.generate_normals()
st.generate_tangents()
st.GenerateNormals();
st.GenerateTangents();
По умолчанию, при генерации нормалей, они будут вычисляться для каждого лица. Если вы хотите получить гладкие вершинные нормали, при добавлении вершин вызовите add_smooth_group(). add_smooth_group() нужно вызывать во время построения геометрии, например, перед вызовом add_vertex() (если он не индексирован) или add_index() (если индексирован).