Accessing indexbuffer data

I would like to change some vertex indexes in a GeomPrimitive. There is addVertex, getVertex but no setVertex. Then the only method i found is to discard the hole indexbuffer with clearVertices and rebuild it entirely.

I’m checking in the source if this is feasible in C++

It is possible in C++, using GeomPrimitive::modify_vertices() in conjunction with a GeomVertexWriter. But it’s dangerous, unless you know what you’re doing, since some of the primitive types (e.g. GeomTristrip) implicitly add additional vertices, and/or operate on other internal structures like the ends array, based on the vertices you have add via add_vertex(). And all of them implicitly update the mins and maxs arrays.

For this reason, the public interface, and the interface provided to Python, discourage you from directly manipulating the vertex index numbers, providing the safer addVertex/clearVertices interfaces instead.

It’s unusual to need to manipulate these vertex indices, since most vertex animation is done by directly operating on the vertices themselves. Are you sure you need to?


Yes, I think so, I’m implementing some 3D trails (cylinders that follow a certain path) and each frame a new slice is replaced so that as few data as possible is modified.
The vertex data is easily replaced, I’m using setRow. But with index data, I can’t render the whole cylinder as it, because the geometry is not cyclic.

The only way that could make me escape from implementing this in C++ would be to render the geom in 2 passes, without rendering the only slice that makes the junction between the first and the last.

Since I’m using triangles, I think I can modify the indexbuffer directly, I’ll try to do that in C++. I’m porting a DirectX code that worked pretty well.

Thanks for answering so quickly !

raytaller, I may be off base here, but would it possibly be simpler just to create a new Geom for every sline in the trail? This would lead to a lot of geoms, but unless it demonstrably hurts performance this seems like it would be the easiest way.

Even if performance is hurt by having too many geoms, you could do something like make each geom store a small number of slices, say 4 or less, so that the interior geoms would not change, while the end geoms would be deleted and reconstructed each frame.

Interesting idea.
Actually I was planning to try something like this in the case where there are a lot of displayed trails : each geom would contain, say 4 slices of ALL the trails.

Then it would first save me from transferring all the data each frame, the amount of data sent to the graphic card, because the previously sent geomNodes stay unchanged.

David, I ported my code to C++ and everything is working. I’d like to create the writer to write the index buffer, but I can’t find which vertexformat pass to the GeomVertexData constructor.

Checking the index type (s16 or s32) it could be quite easy to write directly raw bytes to the buffer but I don’t think it’s really advised.

Wait–are you creating a new index array from scratch? If you do, then you will need to construct a GeomVertexFormat with something like this:

CPT(GeomVertexFormat) format = GeomVertexArrayFormat::register_format
    (new GeomVertexArrayFormat(InternalName::get_index(), 1, 
                               Geom::NT_uint16, Geom::C_index));

You can see this being done in the GeomPrimitive code, for instance in GeomPrimitive::get_index_format().

If you are creating a new array like this, you should use GeomPrimitive::set_vertices() to set it. Read the internal documentation carefully (that is, read the code, and the comments therein).

If, on the other hand, you are modifying indices in an existing array, then you don’t need to invoke the GeomVertexArrayData constructor, since you’ve already got a GeomVertexArrayData (that’s what modify_vertices() gives you). In this case, just use the GeomVertexWriter to modify it in-place. Use the GeomVertexWriter constructor of the form:

GeomVertexWriter writer(array, 0);


Thank you David, this works like a charm.
Soon, the result of this work in the snippets section. I still have to solve a small “deallocating None” python fatal Error, but my first real Panda extension in C++ is a success.