I’ve had limited experience with Panda’s low-level procedural geometry features: enough to get somewhere by myself–but, I worry, maybe no enough to avoid doing something unsafe.
In particular, I primarily have experience with static procedural geometry–and now want to work on dynamic geometry. Specifically, on geometry that’s updated every frame.
As such, I’d appreciate it if someone better-versed in such matters would tell me whether the my approach to this is wise or not.
Specifically, what I currently do is this (in brief):
Initialisation:
Create a vertex-format, vertex-data, GeomNode, and a single GeomTriangles
Create a set of GeomVertexWriters (one per vertex-datum, of course)
Importantly, I store these as instance-variables. More on this below…
Write basic starting data with each of the GeomVertexWriters
This starting-data is irrelevant; it’s just there so that there will be something in place
Add the relevant indices to the GeomTriangles
Close the GeomTriangles
Add the GeomTriangles to the GeomNode
Update:
With each of the stored GeomVertexWriters, reset its row to 0
For each desired triangle:
With each of the stored GeomVertexWriters, call “setData<N>”, as appropriate, feeding it the relevant data
Is that… the correct way to go about this…? Is the re-use of the original GeomVertexWriters safe and wise? Is there anything that should be “closed” in the update process…? Any other problems with the above that you see…?
I’ll note that the above works–I’m just worried that it might do something untoward if I continue in this fashion…
I think you need to consider that it’s faster to change an existing geometry or create a new one. It may turn out that your method of changing the existing geometry does not make sense - there are no advantages in it.
I meant exactly the recreation of a new one, not the modification of an existing one. The change in the existing one must be due to something. It may well turn out that it is the change that makes no sense, for example, it is more expensive and so on.
I’m not sure of how that’s relevant, if it’s not what I’m doing?
Of course. I’m not doing it “just because”. But the reason that I’m modifying the geometry each frame is irrelevant–just assume that it’s something to be done.
I’ve looked at that, but it doesn’t seem to quite answer my uncertainties.
First of all, it talks about using methods such as “modifyGeom”, “modifyVertexData”, and “modifyPrimitive”.
But that seems to be intended for the case in which one is modifying a model loaded from disk. It’s not clear whether it applies in the case in which one is modifying geometry that one created oneself procedurally.
Second, it does mention what I’m doing–using a GeomVertexWriter to write over extant data.
But again, this seems to be written with the idea in mind of modifying a model loaded from disk, and furthermore, only seems to speak to a single modification. As such, it never clarifies whether one can just keep reusing the same GeomVertexWriter over multiple updates, or indeed the same GeomVertexWriter that one used to create the vertices in the first place–or whether one should create a new GeomVertexWriter each time that one updates the vertices.
Most of the rest then speaks to changing the format of the vertex-data, which isn’t relevant to me.
So what’s there is useful–but doesn’t quite address what precisely I’m doing, I feel. Or at least not unambiguously.
I mean, my game does have a “meteor” spell, so that happens fairly regularly.
Your approach is mostly sound. You don’t need to ever close a GeomTriangles, though. That’s just for primitives with a variable number of vertices, such as a GeomTristrips.
As for the GeomVertexWriters, they aren’t intended to be cached, but rather recreated on every update. Otherwise, your game will hang under the multi-threaded render pipeline, since the GeomVertexWriters “lock” access to the geometry while they are operating.
If you run into performance issues, a more efficient way to do geometry updates is via memoryview, this is described in the manual.
I’m guessing I saw an example that used a primitive with a variable number of vertices, and applied the methodology there to this.
Aahh, I wondered about that!
Is re-creating them expensive…?
(I know that keeping them around seems to perform fairly well. But of course, if it’s a potential problem, as you’ve noted, then that doesn’t help.)
Noted! We’ll see how the GeomVertexWriters do for now–it’ll only be when I get to what is likely to be my next use of the base-class that I’m working on that I’ll see how they work with multiple instances…
(I’m currently testing with just a single instance.)
And if they do prove too heavy, then I can look into memoryviews!
[edit]
Actually, it sounds like memoryviews may be the more “proper” way to do what I want to do–per-frame updates to geometry–so it may be worth my while just switching to them anyway.
[/edit]