Real-time polygons

Would there be a way to generate a model in real-time instead of loading it from a file? I’m trying to make a terrain-based level that changes itself.

You can build up an in-memory egg file by constructing an EggData, and populating it with an EggVertexPool and a series of EggPolygons, then calling loadEggFile() with your EggData.

That will work fine, though it’s not blazingly fast; but if you’re building terrain in Python code you probably don’t expect blazingly fast. The next step in performance tweaking is to get cozy with the C++ code, which is a pretty big step.

David

Hmm… Well, I just made a grid in Blender, would there be a way to modify the vertices at real-time?

Hmm, there is supposed to be an interface to do that sort of thing, but it looks like it isn’t working in Python right now for some reason. I’ll have to investigate. So the answer is no, not right now, but in a future version yes.

David

Ok, I’ve checked in the fix. When the fix makes its way to the released version, this is how you’ll do it.

First, edit your egg file and put the syntax:


<Scalar> indexed { 1 }

within the node that contains your polygons, or some parent group. This tells Panda to optimize the model for real-time changes to its vertices.

Then when you load up the egg file, you will need to find the GeomNode that corresponds to your geometry, get the first Geom out of that node, and then get the Coords array out of the Geom. This will be the list of vertex values, which you can inspect and modify as you wish.

Here’s an example. It recomputes the z value of each vertex, to bend the plane into a conical shape.

from direct.directbase.DirectStart import *
from pandac.PandaModules import *
import math

grid = loader.loadModel('grid.egg')
grid.reparentTo(render)

geomNode = grid.find('**/+GeomNode').node()
vertexArray = geomNode.getGeom(0).getCoordsArray()
print "%s vertices." % (vertexArray.size())

for i in range(vertexArray.size()):
    p = vertexArray.getElement(i)

    z = math.sqrt(p[0] * p[0] + p[1] * p[1])
    newP = Point3(p[0], p[1], z)

    print "%s. %s -> %s" % (i, repr(p), repr(newP))

    vertexArray.setElement(i, newP)

grid.forceRecomputeBounds()

Note that it’s a good idea to call forceRecomputeBounds() after you have monkeyed with the vertex positions. Otherwise, Panda might not cull the object correctly (and it might appear to disappear when it should be right in front of you).

David

Three questions:

  1. Is the fix the 05-01-26A version?
  2. Is there any way to control the vertices with a LERP interval?(I want a dramatic morphing effect)
  3. Is this CPU consuming?
  1. Not sure. You can try it and see. Before the fix, the getElement() returned None, and setElement() didn’t exist; after the fix, both functions exist and do the right thing.

  2. You can use a LerpFunctionInterval to call a function each time with a different value of t, and your function can then move the vertices according to t.

  3. It’s not too bad. You’re just paying for the cost of doing all that work in Python, which can be a lot of work if you have a lot of vertices.

David