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...
Utilizzo di SurfaceTool
La classe SurfaceTool fornisce un'interfaccia utile per costruire la geometria. L'interfaccia è simile a quella della classe ImmediateMesh. Si impostano gli attributi per ogni vertice (ad esempio, normale, coordinate UV, colore) e poi, quando si aggiunge un vertice, questi attributi vengono catturati.
SurfaceTool fornisce anche alcune utili funzioni ausiliari come index() e generate_normals().
Gli attributi si aggiungono prima di aggiungere ciascun vertice:
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.
Una volta generata la geometria con SurfaceTool, chiama commit() per completare la generazione della mesh. Se a commit() viene passato un ArrayMesh, aggiunge una nuova superficie alla fine dell'ArrayMesh. Se invece nulla viene passato, commit() restituisce un 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();
Il codice seguente crea un triangolo senza indici.
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();
È possibile aggiungere facoltativamente un array di indici, chiamando add_index() e aggiungendo manualmente i vertici all'array di indici, oppure chiamando index() una sola volta, il che genera automaticamente l'array di indici e riduce l'array di vertici rimuovendo i vertici duplicati.
# 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();
In modo simile, se hai un array di indici, ma vuoi che ogni vertice sia univoco (ad esempio, perché vorresti utilizzare normali o colori univoci per ogni faccia anziché per ogni vertice), puoi chiamare deindex().
st.deindex()
st.Deindex();
Se non aggiungi manualmente le normali personalizzate, puoi aggiungerle usando generate_normals(), che bisognerebbe chiamare dopo aver generato la geometria e prima di confermare la mesh con commit() o commit_to_arrays(). Chiamando generate_normals(true) si invertono le normali risultanti. Nota in più, generate_normals() funziona solo se il tipo di primitiva è impostato su Mesh.PRIMITIVE_TRIANGLES.
Potresti notare che la mappatura normale o altre proprietà del materiale appaiono distorte sulla mesh generata. Questo perché la mappatura normale richiede che la mesh presenti tangenti, che sono separate dalle normali. Puoi aggiungere tangenti personalizzate manualmente oppure generarle automaticamente con generate_tangents(). Questo metodo richiede che ogni vertice abbia già gli UV e le normali impostate.
st.generate_normals()
st.generate_tangents()
st.commit(mesh)
st.GenerateNormals();
st.GenerateTangents();
Normalmente, durante la generazione delle normali, queste vengono calcolate vertice per vertice (ovvero, saranno "normali uniformi"). Se vuoi normali piatte per ogni vertice (ovvero, un singolo vettore normale per faccia), durante l'aggiunta dei vertici, chiamare add_smooth_group(i), dove i è un numero univoco per ogni vertice. Bisogna chiamare add_smooth_group() durante la costruzione della geometria, ad esempio prima di chiamare add_vertex().