I have a large procedural mesh that needs to be modified pretty much every frame.
While it takes very little time to construct the GeomVertexData for the vertices, it takes an unacceptably long time to construct the GeomTriangles structure. I can only assume that this is because of large overheads when calling each prim->add_vertices(a,b,c) and subsequent prim->close_primitive().
What mechanism is there to get low-level access to the fundamental list of vertex indices that makes up a GeomTriangles, such that it can be pre-allocated to the right size once, then rapidly filled with the indices, and the overheads minimised?
Okay, I figured it out.
I can write the vertex indices really quickly by side-stepping all the add_vertex calls, and instead using a GeomVertexRewriter with an appropriately formatted GeomVertexArrayData, then use set_vertices.
I’ve run into this nuisance recently myself, and used a similar workaround. I plan to introduce code to make this workaround unnecessary soon.
I thought you couldn’t use GeomVertexRewriter on a primitive object, only on vertexdata objects? At lease thats what I get from the Panda docs.
In fact, the GeomPrimitive uses a GeomVertexArrayData to store its list of vertex indices internally, and you can get a handle to this object with GeomPrimitive::modify_vertices() or related methods. This low-level access should be made only as a last resort, though; it’s better to use the high-level interface when possible.
I’ve just committed code to the CVS trunk over the weekend to (a) add a method GeomPrimitive::reserve_num_vertices(), which pre-allocates memory in the same way the vector::reserve() works, and (b) improve underlying performance of add_vertices() even if you never call reserve_num_vertices(). I think this solves the problem nicely.
Unfortunately, this new code isn’t available in 1.7.x (and probably shouldn’t be), so today you’ll have to get the latest code directly from CVS in order to pick it up. It may also be available on the buildbot release.
I’m also in need of faster way to reconstruct big mesh every frame, and using
on big mesh will slow things down.
So just to check if I understood right, you said you have optimized addVertices and ClosePrimitive and if I download latest build from buildbot which I did it should be safe and faster then before to still add indices using addVertices and closePrimitive methods?
Or is there another faster way? Why wouldn’t it be possible to fill an array with indices withouth calling those functions? Is there such a way I’d prefer using that, calling those functions over 1000 times in a frame maybe not such a good idea?
Please give me some advice, as its important that I get this right before I go further with my project!
Btw I am using python, not c++
Calling these functions in C++ is not expensive at all. Calling any functions 1000 times or more in Python is kind of expensive, so you should minimize this operation in Python. But, of course, if you are going to construct your array in Python somehow, you’re going to need to call some functions to do it, and it might as well be these.
But to answer your immediate question: for the case of GeomTriangles, you can get away with not calling closePrimitive() after each three vertices, at least with the current version of Panda. You do still have to add the vertices, though, but you can use other methods such as addVertices() which can add them three at a time or whatever.
You can also populate a GeomVertexArrayData separately with your array of vertices and store it on the primitive with setVertices(). You have to know what you’re doing here, though, and you still have to find a way to populate that object, which will be about as expensive as calling addVertices() repeatedly. So I don’t really recommend that approach.
thanks for your reply.
I just tested it and as you said triangles.closePrimitive() is not really needed on GeomTriangels, which is great.
I’ll stay with addVertices method and add 3 of them as I am doing currently, as you said even if I add them inside an array, I will still have to use a function like append, and that is as expensive as addVertices, so really no difference there.
btw if I add 4 vertices at once, am I constructing a quad or an triangle? If I am constructing a quad, is this really just 2 triangles I am making in calling one function?
Could I call addVertices(v1, v2, v3, v4) withouth closePrimitive?
No. You are adding three vertices of a triangle plus the first vertex of the next triangle. You will still need to add two more vertices to get the next triangle. addVertices() with four parameters doesn’t really make sense for a GeomTriangles.