Why can't I see my procedural Geom?

I’m just getting started with Panda3D (and with 3D in general, in fact) and have hit a wall generating a cube Geom. When running my script, nothing at all appears in the render window (blank grey, as if the scene graph were empty) and no errors appear in the console.

I’m using spinCameraTask from the tutorial and the Geom code is based on that section of the manual. I’ve triple-checked that I’m defining the vertices in the correct (counter-clockwise) order, but have tried reversing them as well to no effect. Any ideas what I’m doing wrong? For future reference, how can I best troubleshoot this kind of “no feedback” problem in Panda3D?

import math

from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from panda3d.core import Geom, GeomNode, GeomTristrips, GeomVertexData, GeomVertexFormat, GeomVertexWriter

def cube(coords, color, size=1):
	x = coords[0]
	y = coords[1]
	z = coords[2]

	xx = x + size
	yy = y + size
	zz = z + size

	r = color[0]
	g = color[1]
	b = color[2]
	a = color[3]

	data = GeomVertexData("cube", GeomVertexFormat.getV3c4(), Geom.UHStatic)

	vertices = vertices = GeomVertexWriter(data, "vertex")
	colors = vertices = GeomVertexWriter(data, "color")

	# bottom, left, top
	vertices.addData3f(x, y, z)
	vertices.addData3f(x, yy, z)
	vertices.addData3f(xx, y, z)
	vertices.addData3f(xx, yy, z)
	vertices.addData3f(xx, y, zz)
	vertices.addData3f(xx, yy, zz)
	vertices.addData3f(x, y, zz)
	vertices.addData3f(x, yy, zz)

	# front, right, back
	vertices.addData3f(xx, y, zz)
	vertices.addData3f(xx, y, z)
	vertices.addData3f(x, y, zz)
	vertices.addData3f(x, y, z)
	vertices.addData3f(x, yy, zz)
	vertices.addData3f(x, yy, z)
	vertices.addData3f(xx, yy, zz)
	vertices.addData3f(xx, yy, z)

	# all vertices are the same color
	for i in xrange(16):
		colors.addData4f(r, g, b, a)

	primitive = GeomTristrips(Geom.UHStatic)
	primitive.addNextVertices(8)
	primitive.closePrimitive()
	primitive.addNextVertices(8)
	primitive.closePrimitive()

	geometry = Geom(data)
	geometry.addPrimitive(primitive)

	node = GeomNode("cube")
	node.addGeom(geometry)

	return node

class CubeDemo(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)

		self.setFrameRateMeter(True)

		self.render.attachNewNode(cube((0, 0, 0), (.5, 1, 1, 1)))

		self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

	def spinCameraTask(self, task):
		angleDegrees = task.time * 6
		angleRadians = angleDegrees * math.pi / 180

		self.camera.setPos(20 * math.sin(angleRadians), -20 * math.cos(angleRadians), 3)
		self.camera.setHpr(angleDegrees, 0, 0)

		return Task.cont

cubedemo = CubeDemo()
cubedemo.run()

I don’t know what’s wrong, specifically, but I suspect your camera is simply not pointed at your geometry. Either that, or it’s too close, or too far away, or whatever.

To help you visualize the camera movement, try putting something that you know you can see (e.g. environment.egg) in the world. Then you can see that moving, and you’ll get a sense for which way your camera is moving.

Put your cube geometry in its own NodePath (for instance, save the result from render.attachNewNode(cube), which is the NodePath for your cube), and then use np.analyze() to prove that you’ve created vertices there, or “print np.getBounds()” to print the size of its volume. And then np.showBounds() to draw a green wireframe sphere around it to help you find it.

Or just use np.writeBamFile(‘np.bam’), and then quit Python and run “pview np.bam” to view your newly-created geometry in pview. You can press “c” in pview to automatically center the view around your geometry.

David

(Great tools/advice for troubleshooting! Thanks!)

Well, I’m definitely doing something wrong with the geometry; getBounds() appears to indicate that the cube takes up no space and analyze() shows twice as many vertices as I’m trying to create (32, with 16 unusued, rather than 16 total). Thinking that might mean I was appending my vertex data to already-initialized arrays, I tried changing all my addData*() calls to setData*(), but that just gets me “APPCRASH in ppython.exe”. :laughing:

Just to see what effect it would have, I also doubled up the addNextVertices()/closePrimitive() block. While it did consume the unreferenced vertices, I still didn’t get any visible geometry and the bounds were still empty.

1 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
1 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
32 vertices, 0 normals, 32 colors, 0 texture coordinates.
GeomVertexData arrays occupy 1K memory.
GeomPrimitive arrays occupy 1K memory.
16 vertices are unreferenced by any GeomPrimitives.
12 triangles:
  12 of these are on 2 tristrips (6 average tris per strip).
  0 of these are independent triangles.
0 textures, estimated minimum 0K texture memory required.

bsphere, c (0 0 0), r 0

This bit is weird:

   vertices = vertices = GeomVertexWriter(data, "vertex")
   colors = vertices = GeomVertexWriter(data, "color") 

Why the double assignment? The first double assignment does nothing, but the second one replaces vertices with the same GeomVertexWriter that you’re using for colors. So when you then added data to “color” and “vertices” below, they’re both actually getting added to the “color” column, and you never add anything to the “vertex” column.

David

double-take

Well spotted, that man.

Best I can figure, I lost my place while looking up GeomVertexWriter in the API ref and copy/pasted the mistake into the colors line, where it wrecked everything. After correcting that lovely little thinko, I have an ugly and malformed — but fixable! — cube spinning on my screen.

Many thanks for all your help! I feel much better armed to deal with future problems, even if this one was kind of embarrassing. :smiley: