hello,
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[0], color[1], color[2], color[3])
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!
Richard