Использование SurfaceTool

SurfaceTool предоставляет полезный интерфейс для построения геометрии. Интерфейс аналогичен узлу ImmediateGeometry. Вы устанавливаете каждый атрибут для каждой вершины (например: нормаль, uv-координаты, цвет), а затем, когда вы добавляете вершину, она захватывает атрибуты.

SurfaceTool также предоставляет некоторые полезные вспомогательные функции, такие как index() и generate_normals().

Атрибуты добавляются перед добавлением каждой вершины:

st.add_normal() # Overwritten by normal below.
st.add_normal() # Added to next vertex.
st.add_color() # Added to next vertex.
st.add_vertex() # Captures normal and color above.
st.add_normal() # Normal never added to a vertex.

Когда вы закончите генерировать свою геометрию с помощью SurfaceTool, вызовите commit(), чтобы завершить генерацию сетки. Если ArrayMesh передается в commit(), то он добавляет новую поверхность в конец ArrayMesh. В то время как, если ничего не передано, commit() возвращает ArrayMesh.

st.commit(mesh)
# Or:
var mesh = st.commit()

Код создает треугольник с индексами

var st = SurfaceTool.new()

st.begin(Mesh.PRIMITIVE_TRIANGLES)

# Prepare attributes for add_vertex.
st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
st.add_vertex(Vector3(-1, -1, 0))

st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(0, 1))
st.add_vertex(Vector3(-1, 1, 0))

st.add_normal(Vector3(0, 0, 1))
st.add_uv(Vector2(1, 1))
st.add_vertex(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()

Аналогично, если у вас есть массив индексов, но вы хотите, чтобы каждая вершина была уникальной (например, потому что вы хотите использовать уникальные нормали или цвета для каждой грани, а не для каждой вершины), вы можете вызвать 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()

По умолчанию, при генерации нормалей, они будут вычисляться для каждого лица. Если вы хотите получить гладкие вершинные нормали, при добавлении вершин вызовите add_smooth_group(). add_smooth_group() нужно вызывать во время построения геометрии, например, перед вызовом add_vertex() (если он не индексирован) или add_index() (если индексирован).