Mentre gioco con Godot e le mesh (le mesh generate a livello di codice per essere precisi).
Ho trovato qualcosa che credo valga la pena condividere.
Devo dire che non ho trovato un uso della vita reale di questa tecnica, per esempio per generare un heightmap. Eppure credo che possa esistere un modo per farlo.
Come utilizzare SurfaceTool e MeshDataTool
Ho creato un semplice script che dovrebbe consentire di capirlo semplicemente leggendo il codice, è abbastanza semplice una volta che sai come usare questi strumenti.
strumento estende Spatial export (int, 1, 512) set di dimensioni var già esistenti _setPlaneSize func _setPlaneSize (_newval): dimensione = _nuovo stampare() var startt = float (OS.get_ticks_msec ()) var mdt = MeshDataTool.new () var st = SurfaceTool.new () var plane_mesh = PlaneMesh.new () plane_mesh.subdivide_width = _newval plane_mesh.subdivide_depth = _newval plane_mesh.size = Vector2 (_newval, _newval) st.create_from (plane_mesh, 0) var array_plane = st.commit () var error = mdt.create_from_surface (array_plane, 0) per i in range (mdt.get_vertex_count ()): var vtx = mdt.get_vertex (i) vtx.y = randf () * 1 mdt.set_vertex (i, vtx) per s in range (array_plane.get_surface_count ()): array_plane.surface_remove (s) mdt.commit_to_surface (array_plane) st.create_from (array_plane, 0) st.generate_normals () $ MeshInstance.mesh = st.commit () var endtt = float (OS.get_ticks_msec ()) print ("Tempo di esecuzione:% .2f"% ((endtt - startt) / 1000)) #func _ready (): # _setPlaneSize (dimensione)
Devi posizionare lo script in una scena con i seguenti elementi (stessi nomi o modificare il codice di conseguenza):
Spaziale (allegare script qui)
| – DirectionalLight
| – MeshInstance
Lo script dovrebbe essere collegato al nodo radice e, in realtà, la luce direzionale è necessaria solo per vedere la corretta creazione delle normali.
Una volta fatto dovresti vedere la nuova proprietà "size", quando la imposti il codice genererà una "heightmap", la dimensione che hai stabilito.
Si prega di notare che, a seconda della macchina, potrebbe essere necessario un po 'di tempo per andare oltre i 256 (sul mio PC ION lento ci vogliono in secondi per dimensione: 0,5 x 64, 2 x 128, 13 x 256).
Il ruolo di SurfaceTool
Quindi, per approfondire, st (lo strumento di superficie), può creare una mesh array a partire da una mesh precedentemente generata (può essere di qualsiasi tipo, in questo caso ho usato la mesh piana), in questo modo:
var st = SurfaceTool.new () # crea una mesh piana di _newval size # e la stessa quantità di sottodivisioni var plane_mesh = PlaneMesh.new () plane_mesh.subdivide_width = _newval plane_mesh.subdivide_depth = _newval plane_mesh.size = Vector2 (_newval, _newval) # crea un arrayMesh da utilizzare da MeshDataTool st.create_from (plane_mesh, 0) var array_plane = st.commit ()
Lo strumento Mesh Data
Una volta convertito in ArrayMesh, può essere utilizzato da MeshDataTool, in quanto l'altro PlaneTool non può modificare le mesh, ma solo crearle.
Ora che MeshDataTool può posizionare le sue mani sul piano, possiamo lavorare in questo modo per alterare un vertice (l'asse y in questo caso)
# In pratica copiamo la mesh della matrice in MeshDataTool var error = mdt.create_from_surface (array_plane, 0) per i in range (mdt.get_vertex_count ()): # Qui corriamo attraverso tutti i vertici dell'aereo var vtx = mdt.get_vertex (i) # Un valore casuale per modificare la posizione y del nostro vertice vtx.y = randf () * 1 # Diciamo al MeshDataTool di modificare il vertice di conseguenza mdt.set_vertex (i, vtx)
Generare le normali e posizionare la mesh nel nodetree
Bene, fatto, ora la parte successiva consiste nel rimuovere le mesh precedenti (se ce ne sono) e generare le normali per il nostro piano modificato.
Come crei le normali, beh, godot hanno questa bella caratteristica che ci permette di evitare l'uso della matematica vettoriale, l'annuncio fa tutto per noi, ma devi spostare la mesh sul SurfaceTool (sì, mi chiedo perché non è tutto nello stesso oggetto, invece di avere 2, ma bene) generate_normals () fa tutto.
Quindi, finalmente, prendiamo la mesh appena creata e vogliamo metterla da qualche parte, in modo che chiunque possa vederla, dato che siamo orgogliosi dei genitori (commit () restituisce la mesh finale):
# Per evitare di aggiungere nuove superfici all'istanza mesh # Ho dovuto scorrere tutte le superfici esistenti e rimuoverle per s in range (array_plane.get_surface_count ()): array_plane.surface_remove (s) # Quindi siamo pronti a posizionare il piano modificato # indietro nell'array originale mdt.commit_to_surface (array_plane) # Quest'ultima operazione è necessaria per generare le normali # senza la necessità di farlo manualmente st.create_from (array_plane, 0) st.generate_normals () #finalmente, collega la mesh al nodo MeshInstance $ MeshInstance.mesh = st.commit ()