Open Shaac opened 2 years ago
What happens when you try adding indices for the ArrayMesh? My understanding is that the PRIMITIVE_TRIANGLES type requires, at minimum, a list of vertices and a list of indices for the triangles; when constructing a procedural mesh in this way, I haven't had any issues on 3.4.2 or the 4.0 master.
(As an aside, I've also found that constructing extensive procedural meshes like this incurs a huge performance hit from constructing Pool__Arrays as you go, likely due to how Godot is allocating memory for them. I was able to achieve a tenfold performance increase just by STL vectors of Vector3s and then copying them to Godot PoolVector3Arrays in one go.)
Hello, I took me a while to wrap my head again around this issue, but I had a complete look at it again.
Adding indices does not change anything. I have indices in my real scenario, here I just wanted to give a minimal reproduction. Even if the mesh would not be very relevant without indices, the real problem here is that godot crashes, which should not happen in any case.
I updated godot-cpp to 3.4.3 and the issue is still here (my godot is now 3.4.4).
You said you have some code that work constructing procedural mesh like this from gdnative? Do you have public code that I can check to see if it works on my machine? Did you try the minimal example from my post to see if you have an issue as well?
And thanks for the performance tips. I just used a append for now, but noted that I needed to check what was the fastest. Other options are resizing the array first, or use a writer.
@Shaac Here's an annotated example of what I use inside a helper class for constructing procedural meshes in my project. The data is populated elsewhere, but it's important to note that, if you have X vertices forming Y triangles, you need exactly:
Anything else produces undefined behavior, from what I've found.
Array ProceduralMeshData::get_mesh_for_ArrayMesh(bool color_to_srgb) {
Array data = Array();
PoolVector3Array verts, norms;
PoolRealArray tangs;
PoolColorArray cols;
PoolIntArray inds;
// The DataConverstion::copy_vector* functions just copy a std::vector<X> to a corresponding PoolXArray object.
// I'm using this because in profiling, I found that using STL containers for calculating mesh values and then copying
// them over to Godot containers in one step led to a significant (10x+) performance improvement.
DataConversion::copy_vector3(verts, vertices);
DataConversion::copy_vector3(norms, normals);
DataConversion::copy_vector_float(tangs, tangents);
DataConversion::copy_vector_color(cols, colors);
DataConversion::copy_vector_int(inds, indices);
data.resize(ArrayMesh::ARRAY_MAX);
data[ArrayMesh::ARRAY_VERTEX] = verts;
data[ArrayMesh::ARRAY_NORMAL] = norms;
data[ArrayMesh::ARRAY_INDEX] = inds;
data[ArrayMesh::ARRAY_TANGENT] = tangs;
data[ArrayMesh::ARRAY_COLOR] = cols;
return data;
}
When returning an ArrayMesh, it uses the following function in the same helper object:
Ref<ArrayMesh> ProceduralMeshData::get_array_mesh() {
Ref<ArrayMesh> new_mesh = nullptr;
new_mesh.instance();
new_mesh->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, get_mesh_for_ArrayMesh());
return new_mesh;
}
Thank you for the quick response. I tried your snippet and it worked!
The only difference from what I used to do is the use of a Ref<ArrayMesh>
instead of an ArrayMesh
.
Most of the time it makes more sense to use a Ref<ArrayMesh>
so I guess that is why no one noticed the issue. I myself will be better off using a Ref
anyway so I guess this issue is fixed for me, but maybe this ticket should be kept open since godot crashing should not happen. Unless add_surface_from_arrays
is only meant to be called from a reference, but then it should say so in the function documentation.
Thanks again
Hello, when trying to call
ArrayMesh::add_surface_from_arrays
from gdnative, I get a crash. Doing the exact same call from GDscript (with the array computed by gdnative) works well.My setup
11.1.0
3.4.2.stable.arch_linux
(also tested with binary fromgodotengine.org 3.4.2.stable.official.45eaa2daf
)godot-3.4.1-stable
(also tested 3.3.4 and 3.1.1)Minimal reproduction
I suggest to use
gdnative_cpp_example
because it is a good minimal reference, but really any gdnative plugin should do. It is just about writing 9 lines of codes, that make godot crashes at runtime.scons platform=linux generate_bindings=yes
ingdnative_cpp_example/godot-cpp
)GDExample::_process
implementation insrc/gdexample.cpp
(you need to#include <ArrayMesh.hpp>
as well):scons platform=linux
ingdnative_cpp_example
folderThe crash
Godot crashes with the following:
gdb gives a little more info. It says it comes from a
SIGSEGV
, but in my other project (too cumbersome to share here) it is aSIGBUS
. Callstack for the minimal reproduction is:Note
I don't know what is happening here or how to circonvent the issue. I have made some interesting finds though:
add_surface_from_arrays
does not always crash: