Dynamic Mesh Editing on CPU in Godot 4.2.1

Godot Version

4.2.1

Question

Greetings,

I’m currently evaluating Godot’s capabilities for our project, specifically its suitability for straightforward dynamic mesh editing. I’ve invested some time into exploring this functionality, but I’ve encountered some challenges regarding mesh types. Would appreciate some guidance on the following:

1. Mesh Data Tool Compatibility:

  • I’ve attempted to utilize MeshDataTool, but it appears to exclusively accept ArrayMeshes.
  • Is it possible to convert other mesh types (such as SurfaceTool-generated or MeshInstance3D meshes) into ArrayMeshes to enable dynamic editing? If so, could you outline the necessary steps involved?
  • Alternatively, are there other viable methods for dynamically editing meshes of different types(on the CPU)? Preferably something simple interface-wise.

2. Additional Considerations:
Are there specific best practices or techniques that you could recommend for optimizing dynamic CPU mesh operations within Godot?

3. Comparison to Unity’s Approach:
In Unity, for example, direct vertex manipulation is possible via mesh.vertices . Does Godot offer a similar mechanism?

I’d greatly appreciate any insights or recommendations you can offer. Thank you for your time and expertise.

You can edit everything about a mesh with the ArrayMesh API and the RenderingServer API.

Every primitive mesh in Godot is basically an “ArrayMesh” internally. They all have functions to get the mesh arrays. The more simpler and specialised looking Mesh resource classes limit the API and user input options hiding away the complexity from users. Internally they build the same arrays required for the RenderingServer as you would with a manual ArrayMesh.

For a lot of the mesh primitives their usefulness is therefor limited to prototyping. They can not support many of the more sophisticated mesh features like skeletons or updating small array regions instead of the entire mesh.

So if you want to work with more complex procedual meshes you can basically ignore all Mesh resource classes except for the ArrayMesh.

MeshDataTools is just a slow convenience class, it is required for nothing. You can do the same more efficiently with just plain arrays or SurfaceTool. SurfaceTool on the other hand is a more useful helper class for mesh surface creation. It has functionality like recalculating normals and tangents or doing the mesh indexing and cache optimizations.

Note that as soon as you commit to a mesh all the mesh data is stored on the GPU. This means calling getters to receive mesh data will stall the rendering. So keep a copy of your mesh arrays so you have it on the CPU to update your mesh.

Since you are working with just pure data arrays most of the time you can throw as many threads at the mesh problem as you need. Just make sure that you commit your arrays on the main thread and don’t call getters that require GPU data.

1 Like

Appreciate the reply. I was able to get the mesh arrays from a primitive(MeshInstance3D). Mesh data can indeed be modified as direct arrays, which is quite nice. Here’s the test code on a sphere mesh(C#) for posterity:

public override void _Ready(){
	var meshData = this.meshInstance3D.Mesh.SurfaceGetArrays(0);
	var positions = meshData[(int)Mesh.ArrayType.Vertex].AsVector3Array();
	GD.Print(positions.Length);
	for(var index=0;index<positions.Length;index++){
		positions[index].Y *= Mathf.Sin(positions[index].Y*50);
	}
	meshData[(int)Mesh.ArrayType.Vertex] = positions;
	var newMesh = new ArrayMesh();
	newMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles,meshData);
	this.meshInstance3D.Mesh = newMesh;
}

I’d appreciate feedback regarding any bad/sub-optimal Godot practices in there, will update the snippet.
I haven’t looked much at SurfaceTool yet, but will take a deeper look at it next – thanks for the pointer.

Understood. It is refreshing to see support for multi-threading and newer .NET versions.