Hello everyone! I am currently making a custom voxel engine using cpp module I'm aware of Godot voxel however I would like to make one myself. I've looked at the source code for Godot voxel and have not figured out how to make a mesh. I have the vertices, uvs, etc however I'm not sure how to use those arrays to spawn a mesh from the module in the game. Any help is appreciated thanks!
C++ Module Mesh
- Edited
I have not done mesh generation from C++ myself, so it is entirely possible that what I wrote below is wrong, but I looked at the source code for Godot Voxel and I think I have a loose idea of how it works.
Looking at the source code for Godot Voxel, it looks like the code there is using the ArrayMesh class and is passing in an array of arrays with the mesh data.
In the voxel_mesher.cpp class in Godot voxel, it looks like the requirements to use the add_surface_from_arrays
function is passing the primitive type and the arrays with the mesh data.
One thing I am not sure on is what needs to be passed in teh array of arrays containing the mesh data. In the voxel_mesher_blocky.cpp file, on line 70 there is code that clears the mesh array. Looking at that code, it seems the positions
, normals
, uv
, colors
, and indicies
of the mesh are all potentially needed to generate the mesh. However, in the mesh_builder.cpp
file in the DMC meshers folder, only the positions
, normals
, and indices
are part of the array, so I am not totally sure.
According to the documentation for the add_surface_from_arrays
function, only the first array needs to be an array of vertices, with the rest of the arrays (and the data within) being optional.
It might not be a bad idea to ask Zylann, or someone else with mesh creation experience in C++, for some pointers. I'm sure there is a common/known way to create meshes in C++.
Hopefully this helps! (Side note: Welcome to the forums!)
I'm not quite sure how to reply XD but thank you I have been using the array mesh but not sure how to pass it to Godot itself. I will contact Zylann for help thank you for the warm welcome and suggestion!
@Zylann any advice?
- Edited
I am doing the same, MueVoid. Currently looking through Zylann's voxel_mesher_blocky.cpp file to try to understand. Please let me know if you figure it out and I will do the same. All I really need is the code to render a single triangle and I can figure out the rest. @Zylann can you help please?
I'm just getting started with GDNative procedural meshes and came across your thread trying to figure it out. I managed to get a gray triangle to show up. Not to necropost or anthing, but if you or anyone else is still interested, here's where I'm at so far.
void MySpatialNode::_ready()
{
// Simple test code adapted from GDscript docs to native C++
// Might leak if called repeatedly (not sure how that's handled),
// but it gets a triangle on the screen.
PoolVector3Array vertices;
vertices.push_back(Vector3(0, 10, 0));
vertices.push_back(Vector3(10, 0, 0));
vertices.push_back(Vector3(0, 0, 0));
auto mySimpleMesh = ArrayMesh::_new();
godot::Array arrays; // kind of a struct-of-arrays approach to vertex attributes (or array of arrays with enumerated keys)
arrays.resize(ArrayMesh::ARRAY_MAX);
arrays[ArrayMesh::ARRAY_VERTEX] = vertices; // required
// Vertex colors don't show correctly, probably because there's no material/skin yet.
PoolColorArray colors; // optional...
colors.append(Color(1,0,0));
colors.append(Color(0,1,0));
colors.append(Color(0,0,1));
arrays[ArrayMesh::ARRAY_COLOR] = colors;
mySimpleMesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays);
// pMeshInstance = new MeshInstance; // NO! BAD! Will crash the game!
auto mySimpleMeshInstance = MeshInstance::_new(); // This is how we do things here.
mySimpleMeshInstance->set_mesh(mySimpleMesh);
add_child(mySimpleMeshInstance);
}
Note: engine uses dynamic_cast on game objects like MeshInstance* when you call the API, and it needs the boilerplate from Object::new() to set up the RTTI necessary to perform the conversions. Even if RTTI is disabled, there is a macro NO_SAFE_CAST (object.h) that uses static_cast instead, but it still checks types using template magic. If you use the C++ 'new' operator instead of Class::new() it will run into an access violation or nullptr when it tries to cast... beat my head against the desk for a while over that one.
Also, make sure you have a camera in the scene. ;) Good luck!