Usando SurfaceTool

El SurfaceTool proporciona una interfaz útil para construir geometría. La interfaz es similar al nodo ImmediateGeometry. Configuras cada atributo por vértice (por ejemplo, normal, uv, color) y luego, cuando agregas un vértice, captura los atributos.

El SurfaceTool también proporciona algunas funciones auxiliares útiles como index() y generate_normals().

Los atributos se agregan antes de agregar cada vértice:

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.

Cuando hayas terminado de generar tu geometría con el SurfaceTool, llama a commit() para finalizar la generación de la malla. Si se pasa un ArrayMesh a commit(), se agregará una nueva superficie al final del ArrayMesh. Si no se pasa nada, commit() devolverá un ArrayMesh.

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

El código crea un triángulo con índices

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()

Opcionalmente, puedes agregar un array de índices, ya sea llamando a add_index() y agregando vértices al arreglo de índices, o llamando a index(), lo cual reduce el tamaño del array de vértices para eliminar vértices duplicados.

# 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()

De manera similar, si tienes un array de índices pero deseas que cada vértice sea único (por ejemplo, porque deseas utilizar normales o colores únicos por cara en lugar de por vértice), puedes llamar a deindex().

st.deindex()

Si no agregas normales personalizadas tú mismo, puedes añadirlas usando generate_normals(), que debe ser llamado después de generar la geometría y antes de confirmar la malla utilizando commit() o commit_to_arrays(). Llamar a generate_normals(true) invertirá las normales resultantes. Como nota adicional, generate_normals() solo funciona si el tipo primitivo está establecido en Mesh.PRIMITIVE_TRIANGLES.

Puede que notes que el mapeado de normales u otras propiedades de material se vean incorrectos en la malla generada. Esto se debe a que el mapeado de normales requiere que la malla tenga tangentes, las cuales son diferentes de las normales. Puedes agregar tangentes personalizadas manualmente o generarlas automáticamente con generate_tangents(). Este método requiere que cada vértice ya tenga establecidas las coordenadas UV y las normales.

st.generate_normals()
st.generate_tangents()

De forma predeterminada, al generar normales, se calculan en función de cada cara. Si deseas obtener normales suavizadas por vértice, debes llamar a add_smooth_group() al agregar vértices. add_smooth_group() debe ser llamado mientras construyes la geometría, por ejemplo, antes de llamar a add_vertex() (si no está indexado) o add_index() (si está indexado).