I’ve been interested in Panda3D for a few years now and finally got the motivation to dive in.
I know this isn’t what Panda is intended for, but I’m trying to do some low level geometry operations. The code pasted below:
- defines a set of planes
- finds the lines of intersections of these planes
- finds the points of intersections of the generated lines with the original planes
- draws a box from these points
There are a few things I want to improve:
- How do I draw finite and infinite planes in 3D space? Currently I’m forming the box faces by drawing triangles from each vertex, which is awkward. Is there a 3D equivalent class to the 2D CardMaker?
- How do I set the camera view position? I tried setPos(-100, -100, -100) with lookAt(0, 0, 0) but I still start within the box which only has dimension 10.
Here is the code:
import math import direct.directbase.DirectStart from pandac.PandaModules import * def boxPlanes(minX=-2, minY=-1, maxX=2, maxY=1, minZ=-1, maxZ=1): """ Create the planes to form a 3D box """ point1 = Point3(minX, minY, minZ) point2 = Point3(minX, minY, maxZ) point3 = Point3(minX, maxY, minZ) point4 = Point3(minX, maxY, maxZ) point5 = Point3(maxX, minY, minZ) point6 = Point3(maxX, minY, maxZ) point7 = Point3(maxX, maxY, minZ) point8 = Point3(maxX, maxY, maxZ) plane1 = Plane(point1, point2, point5) plane2 = Plane(point3, point4, point7) plane3 = Plane(point1, point3, point5) plane4 = Plane(point5, point7, point6) plane5 = Plane(point2, point4, point6) plane6 = Plane(point1, point2, point3) return [plane1, plane2, plane3, plane4, plane5, plane6] def planeLines(planes): """ Extract the line intersections from the planes """ lines =  for i, p1 in enumerate(planes): for j, p2 in enumerate(planes): c = Point3() X = Vec3() if p1.intersectsPlane(c, X, p2): lines.append((X, c)) return lines def drawLines(lines, lineThickness=1, min=-10, max=10): """ Render line vectors """ ls = LineSegs() ls.setThickness(1) ls.setColor(1.0, 1.0, 1.0, 0.1) for X, c in lines: ls.moveTo(X*(-10) + c) ls.drawTo(X*10 + c) NodePath(ls.create()).reparentTo(render) def planePoints(planes, lines): """ Extract points of intersection between planes """ intersectionPoints =  for plane in planes: for X, c in lines: point = Point3() if plane.intersectsLine(point, Point3(X + c), Point3(X*2 + c)): if point not in intersectionPoints: intersectionPoints.append(point) return intersectionPoints def drawContainer(planes, points, color=(0.5, 0.5, 0.5, 0.5)): """ Draw the container defined by the points on the plane """ format = GeomVertexFormat.getV3cp() vdata = GeomVertexData("box", format, Geom.UHStatic) gvwV = GeomVertexWriter(vdata, 'vertex') gvwC = GeomVertexWriter(vdata, 'color') # need to draw points on plane, so group by plane by looking for zero distance points count = 0 for plane in planes: planePoints =  for point in points: if plane.distToPlane(point) == 0: # point on plane planePoints.append(point) for ps in permutations3(planePoints): for p in ps: gvwV.addData3f(p.getX(), p.getY(), p.getZ()) gvwC.addData4f(color, color, color, color) count += 1 # can only draw triangle primitives, so draw every combination of points to cover surface geom = Geom(vdata) for i in range(count): if i % 3 == 0: if i > 0: tris.closePrimitive() geom.addPrimitive(tris) tris = GeomTriangles(Geom.UHStatic) tris.addVertex(i) node = GeomNode("box") node.addGeom(geom) NodePath(node).reparentTo(render) def permutations3(l): """ Create length 3 permutations of the list for drawing triangles """ newL =  maxL = len(l) for i in range(-maxL, maxL): for j in range(i+1, maxL): for k in range(j+1, maxL): newL.append((l[i], l[j], l[k])) return newL planes = boxPlanes() lines = planeLines(planes) drawLines(lines) points = planePoints(planes, lines) drawContainer(planes, points) # shift so looking at origin from y axis - doesn't seem to work?? base.camera.setPos(-100, -100, -100) base.camera.lookAt(0, 0, 0) run()
thanks for your time!