Thanks for PandaSteer2, chombee.
Your code is clean, well commented and you make it look simple. Those are hallmarks of a good programmer. I am new to Python & learnt a few tricks from you.
Happened to glance at your draw.py module, thought it would be handy for positioning and suchlike, but could not resist tweaking.
Fixed a couple of trivial bugs :-
def drawAxes(..):
...
self.drawLine(Vec3(0,0,0), Vec3(0,size[1],0), color, thickness,np)
self.drawLine(Vec3(0,0,0), Vec3(0,0,size[2[]), color, thickness,np)
class World(DirectObject):
"""The test environment."""
import direct.directbase.DirectStart # to get global "base"
The “thickness” parameters are no good, because of the way setThickness() works. The last call before create() sets the thickness of ALL lines. You may as well use setThickness() directly.
d = Draw()
d.drawXYCircle(color=(0.667,0.33,0,1))
...
d.setThickness(3) # set thickness of ALL lines
node = d.create() # A special GeomNode that draws the shapes.
Implemented your idea for drawing relative to a given nodepath by using its transform matrix. But I suspect the drawing stays fixed if the nodepath moves. Proper way is probably to attach your Draw() object to the nodepath and let Panda take care of moving it.
def drawLine(self,startPoint,endPoint,color=defaultHue,thickness=None,np=None):
"""Draw a line from startPoint to endPoint using the given color.
color: 3-tuple of floats between 0 and 1: r,g,b (alpha is unused?)
thickness: float
np: nodepath to use for coordinate frame. Line will be draw relative to
this node. Default (None) uses render's global coords
"""
if np:
# change start & end points as if they were relative to np
mat=np.getNetTransform().getMat()
startPoint=mat.xformPoint(startPoint)
endPoint=mat.xformPoint(endPoint)
self.setColor(*color)
## self.setThickness(thickness) # wrong! LAST call sets thickness for ALL lines
self.moveTo(startPoint)
self.drawTo(endPoint)
(Naturally all other methods need to pass np to drawLine().)
Wrote a new method drawLattice().
Later realised that it could replace all of drawRectangle(), drawXYGrid() & drawCuboid(). Did not bother to change them, but added examples to your demo.
def drawLattice(self,xRange,yRange,zRange,color=(1,1,1),np=None):
'''draw 3 dimensional grid of lines
XRange,yRange,zRange are each a TUPLE of floats :
(10,17,22) draws grid lines at the three given coordinates
range(-10,11,5) draws regular grid lines at -10,-5,0,5,10
(0,) draws a flat grid, collapsing one dimension
Note the comma - tuple with 1 item only
First & last elements define endpoints of lines.
Interesting effects if points are out of order.
'''
for x in xRange:
for y in yRange: # draw lines in Z direction
self.drawLine(Vec3(x,y,zRange[0]),
Vec3(x,y,zRange[len(zRange)-1]), color, 1,np)
for z in zRange: # draw lines in Y direction
self.drawLine(Vec3(x,yRange[0],z),
Vec3(x,yRange[len(yRange)-1],z), color, 1,np)
for z in zRange:
for y in yRange: # draw lines in X direction
self.drawLine(Vec3(xRange[0],y,z),
Vec3(xRange[len(xRange)-1],y,z), color, 1,np)
class World(DirectObject):
"""The test environment."""
import direct.directbase.DirectStart # to get global "base"
def __init__(self):
...
# Draw some lattices .............................................
hue=(0,0.3,0.4)
# 3x3x3 cube at (0,-50,0)
d.drawLattice(range(0,11,5),range(-50,-39,5),range(0,11,5),hue)
# single flat YZ grid at x=-50 with uneven Y lines
d.drawLattice((-50,),(-10,-8,0,8,9,10),range(10,21),hue)
# box - same as drawCuboid()
d.drawLattice((-50,50),(-50,50),(-25,-1),hue)
# set of disconnected XY grids
d.drawLattice(xRange=range(-50,-29,2),
yRange=range(-50,-29,2),
zRange=(0,10,20,30,0), # repeat first number at end to suppress Z lines
color=hue)
# rotated & positioned as if under a nodepath
rot=render.attachNewNode('rotatedNP')
rot.setPosHpr(-10,-20,5, 120,0,45)
hue=(0.6,1,0.4)
d.drawAxes(size=(3,4,5),color=hue,np=rot)
d.drawLattice((2,4),range(2,7,2),range(2,9,2),color=hue,np=rot)
A hack for drawSphere() might be to draw a circle and attach it to a nodepath with setBillboardPointEye().
But I have not tried it – gotta start using PandaSteer2 !