Using the 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`.

You may notice that normal mapping or other material properties look broken on the generated mesh. This is because normal mapping requires the mesh to feature tangents, which are separate from normals. You can either add custom tangents manually, or generate them automatically with with generate_tangents(). This method requires that each vertex have UVs and normals set already.

st.generate_normals()
st.generate_tangents()

By default, when generating normals, they will be calculated on a per-face basis. If you want smooth vertex normals, when adding vertices, call add_smooth_group(). add_smooth_group() needs to be called while building the geometry, e.g. before the call to add_vertex() (if non-indexed) or add_index() (if indexed).