Como estoy jugando con Godot y mallas (mallas generadas por programación para ser precisos).
He encontrado algo que creo que vale la pena compartir.
Tengo que mencionar que no he encontrado un uso de la vida real de esta técnica, por ejemplo, para generar un mapa. Sin embargo, creo que puede existir una manera de hacerlo.
Cómo usar SurfaceTool y MeshDataTool
He creado un script simple que debería permitir comprenderlo simplemente leyendo el código, es bastante simple una vez que sepas cómo usar esas herramientas.
herramienta extiende espacial export (int, 1, 512) onready var size setget _setPlaneSize func _setPlaneSize (_newval): tamaño = _newval impresión() 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) para i en rango (mdt.get_vertex_count ()): var vtx = mdt.get_vertex (i) vtx.y = randf () * 1 mdt.set_vertex (i, vtx) para s en rango (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 ("Tiempo de ejecución:% .2f"% ((endtt - startt) / 1000)) #func _ready (): # _setPlaneSize (tamaño)
Debe colocar el script en una escena con los siguientes elementos (los mismos nombres o cambiar el código en consecuencia):
Spatial (adjuntar script aquí)
| – DirectionalLight
| – MeshInstance
El script debe adjuntarse al nodo raíz, y en realidad, la luz direccional es necesaria solo para ver la creación correcta de las normales.
Una vez hecho esto, debería ver la nueva propiedad "tamaño", cuando la configure, el código generará un "mapa de alturas", el tamaño que ha establecido.
Tenga en cuenta que, dependiendo de su máquina, puede llevar un tiempo ir más allá de 256 (en mi PC lenta ION se tarda en segundos por tamaño: 0.5 x 64, 2 x 128, 13 x 256).
El papel de SurfaceTool
Entonces, para profundizar, st (la herramienta de superficie) puede crear una malla de matriz a partir de una malla generada previamente (puede ser de cualquier tipo, en este caso he usado la malla de plano), de esta manera:
var st = SurfaceTool.new () # crear una malla plana de _nuevo tamaño # y la misma cantidad de subdivisiones var plane_mesh = PlaneMesh.new () plane_mesh.subdivide_width = _newval plane_mesh.subdivide_depth = _newval plane_mesh.size = Vector2 (_newval, _newval) # crear un arrayMesh para ser utilizado por MeshDataTool st.create_from (plane_mesh, 0) var array_plane = st.commit ()
La herramienta de datos de malla
Una vez convertido en un ArrayMesh, puede ser utilizado por MeshDataTool, ya que el otro, el PlaneTool, no puede modificar mallas, simplemente créelos.
Ahora que MeshDataTool puede poner sus manos en el plano, podemos trabajar de esta manera para alterar algunos vértices (el eje y en este caso)
# En la práctica, copiamos la matriz de malla en MeshDataTool var error = mdt.create_from_surface (array_plane, 0) para i en rango (mdt.get_vertex_count ()): # Aquí corremos a través de todos los vértices del avión var vtx = mdt.get_vertex (i) # Un valor aleatorio para modificar la posición y de nuestro vértice vtx.y = randf () * 1 # Le decimos a MeshDataTool que modifique el vértice en consecuencia mdt.set_vertex (i, vtx)
Generando normales y colocando la malla en el árbol node
Bien, casi hecho, ahora la siguiente parte consiste en eliminar las mallas anteriores (si las hay) y generar las normales para nuestro plano modificado.
¿Cómo se crean las normales, bueno, Dios mío tiene esta buena característica que nos permite evitar el uso de vectores de matemáticas, ad lo hace todo por nosotros, pero tienes que mover la malla de nuevo a SurfaceTool (sí, me pregunto por qué no es todo en el mismo objeto, en lugar de tener 2, pero bueno) generate_normals () lo hace todo.
Luego, finalmente, tomamos nuestra malla recién creada y queremos ponerla en algún lugar, para que todos puedan verla, ya que somos padres orgullosos (commit () devuelve la malla final):
# Para evitar agregar nuevas superficies a la instancia de malla # Tuve que recorrer todas las superficies existentes y eliminarlas para s en rango (array_plane.get_surface_count ()): array_plane.surface_remove (s) # Entonces estamos listos para colocar el plano modificado # de vuelta a la matriz original mdt.commit_to_surface (array_plane) # Este último paso es necesario para generar las normales # sin la necesidad de hacerlo manualmente st.create_from (array_plane, 0) st.generate_normals () #finalmente, conecte la malla al nodo MeshInstance $ MeshInstance.mesh = st.commit ()