*** empty log message ***

This commit is contained in:
Mark Mine 2000-12-08 03:29:26 +00:00
parent be2b62c779
commit 9b44311ec2
7 changed files with 1770 additions and 1772 deletions

View File

@ -1,449 +1,448 @@
from PandaObject import * from PandaObject import *
CAM_MOVE_DURATION = 1.0 CAM_MOVE_DURATION = 1.0
Y_AXIS = Vec3(0,1,0) Y_AXIS = Vec3(0,1,0)
class DirectCameraControl(PandaObject): class DirectCameraControl(PandaObject):
def __init__(self, direct): def __init__(self):
# Create the grid # Create the grid
self.direct = direct self.chan = direct.chan
self.chan = direct.chan self.camera = self.chan.camera
self.camera = self.chan.camera self.orthoViewRoll = 0.0
self.orthoViewRoll = 0.0 self.lastView = 0
self.lastView = 0 self.coa = Point3(0)
self.coa = Point3(0) self.coaMarker = loader.loadModel('models/misc/sphere')
self.coaMarker = loader.loadModel('models/misc/sphere') self.coaMarker.setColor(1,0,0)
self.coaMarker.setColor(1,0,0) self.coaMarkerPos = Point3(0)
self.coaMarkerPos = Point3(0) self.relNodePath = render.attachNewNode(NamedNode('targetNode'))
self.relNodePath = render.attachNewNode(NamedNode('targetNode')) self.zeroBaseVec = VBase3(0)
self.zeroBaseVec = VBase3(0) self.zeroVector = Vec3(0)
self.zeroVector = Vec3(0) self.centerVec = Vec3(0, 1, 0)
self.centerVec = Vec3(0, 1, 0) self.zeroPoint = Point3(0)
self.zeroPoint = Point3(0)
def mouseFlyStart(self, chan):
def mouseFlyStart(self, chan): # Record starting mouse positions
# Record starting mouse positions self.initMouseX = chan.mouseX
self.initMouseX = chan.mouseX self.initMouseY = chan.mouseY
self.initMouseY = chan.mouseY # Where are we in the channel?
# Where are we in the channel? if ((abs(self.initMouseX) < 0.9) & (abs(self.initMouseY) < 0.9)):
if ((abs(self.initMouseX) < 0.9) & (abs(self.initMouseY) < 0.9)): # MOUSE IS IN CENTRAL REGION
# MOUSE IS IN CENTRAL REGION # Hide the marker for this kind of motion
# Hide the marker for this kind of motion self.coaMarker.hide()
self.coaMarker.hide() # See if the shift key is pressed
# See if the shift key is pressed if (direct.fShift):
if (self.direct.fShift): # If shift key is pressed, just perform horiz and vert pan:
# If shift key is pressed, just perform horiz and vert pan: self.spawnHPPan()
self.spawnHPPan() else:
else: # Otherwise, check for a hit point based on
# Otherwise, check for a hit point based on # current mouse position
# current mouse position # And then spawn task to determine mouse mode
# And then spawn task to determine mouse mode numEntries = direct.iRay.pickGeom(
numEntries = self.direct.iRay.pickGeom( render,chan.mouseX,chan.mouseY)
render,chan.mouseX,chan.mouseY) # Filter out hidden nodes from entry list
# Filter out hidden nodes from entry list indexList = []
indexList = [] for i in range(0,numEntries):
for i in range(0,numEntries): entry = direct.iRay.cq.getEntry(i)
entry = self.direct.iRay.cq.getEntry(i) node = entry.getIntoNode()
node = entry.getIntoNode() if node.isHidden():
if node.isHidden(): pass
pass else:
else: # Not one of the widgets, use it
# Not one of the widgets, use it indexList.append(i)
indexList.append(i) coa = Point3(0)
coa = Point3(0) if(indexList):
if(indexList): # Start off with first point
# Start off with first point minPt = indexList[0]
minPt = indexList[0] # Find hit point in camera's space
# Find hit point in camera's space hitPt = direct.iRay.camToHitPt(minPt)
hitPt = self.direct.iRay.camToHitPt(minPt) coa.set(hitPt[0],hitPt[1],hitPt[2])
coa.set(hitPt[0],hitPt[1],hitPt[2]) coaDist = Vec3(coa - self.zeroPoint).length()
coaDist = Vec3(coa - self.zeroPoint).length() # Check other intersection points, sorting them
# Check other intersection points, sorting them # TBD: Use TBS C++ function to do this
# TBD: Use TBS C++ function to do this if len(indexList) > 1:
if len(indexList) > 1: for i in range(1,len(indexList)):
for i in range(1,len(indexList)): entryNum = indexList[i]
entryNum = indexList[i] hitPt = direct.iRay.camToHitPt(entryNum)
hitPt = self.direct.iRay.camToHitPt(entryNum) dist = Vec3(hitPt - self.zeroPoint).length()
dist = Vec3(hitPt - self.zeroPoint).length() if (dist < coaDist):
if (dist < coaDist): coaDist = dist
coaDist = dist coa.set(hitPt[0],hitPt[1],hitPt[2])
coa.set(hitPt[0],hitPt[1],hitPt[2]) minPt = i
minPt = i
# Handle case of bad coa point (too close or too far)
# Handle case of bad coa point (too close or too far) if ((coaDist < (1.1 * self.chan.near)) |
if ((coaDist < (1.1 * self.chan.near)) | (coaDist > self.chan.far)):
(coaDist > self.chan.far)): # Put it out in front of the camera
# Put it out in front of the camera coa.set(0,100,0)
coa.set(0,100,0) coaDist = 100
coaDist = 100 else:
else: # If no intersection point:
# If no intersection point: # Put coa out in front of the camera
# Put coa out in front of the camera coa.set(0,100,0)
coa.set(0,100,0) coaDist = 100
coaDist = 100
# Update coa and marker
# Update coa and marker self.updateCoa(coa, coaDist)
self.updateCoa(coa, coaDist) # Now spawn task to determine mouse fly mode
# Now spawn task to determine mouse fly mode self.determineMouseFlyMode()
self.determineMouseFlyMode() # END MOUSE IN CENTRAL REGION
# END MOUSE IN CENTRAL REGION else:
else: # Mouse is in outer frame, spawn mouseRotateTask
# Mouse is in outer frame, spawn mouseRotateTask self.spawnMouseRotateTask()
self.spawnMouseRotateTask()
def mouseFlyStop(self):
def mouseFlyStop(self): taskMgr.removeTasksNamed('determineMouseFlyMode')
taskMgr.removeTasksNamed('determineMouseFlyMode') taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Show the marker
# Show the marker self.coaMarker.show()
self.coaMarker.show() # Resize it
# Resize it self.updateCoaMarkerSize()
self.updateCoaMarkerSize()
def determineMouseFlyMode(self):
def determineMouseFlyMode(self): # Otherwise, determine mouse fly mode
# Otherwise, determine mouse fly mode t = Task.Task(self.determineMouseFlyModeTask)
t = Task.Task(self.determineMouseFlyModeTask) taskMgr.spawnTaskNamed(t, 'determineMouseFlyMode')
taskMgr.spawnTaskNamed(t, 'determineMouseFlyMode')
def determineMouseFlyModeTask(self, state):
def determineMouseFlyModeTask(self, state): deltaX = self.chan.mouseX - self.initMouseX
deltaX = self.chan.mouseX - self.initMouseX deltaY = self.chan.mouseY - self.initMouseY
deltaY = self.chan.mouseY - self.initMouseY if ((abs(deltaX) < 0.1) & (abs(deltaY) < 0.1)):
if ((abs(deltaX) < 0.1) & (abs(deltaY) < 0.1)): return Task.cont
return Task.cont else:
else: if (abs(deltaY) > 0.1):
if (abs(deltaY) > 0.1): self.spawnHPanYZoom()
self.spawnHPanYZoom() else:
else: self.spawnXZTranslate()
self.spawnXZTranslate() return Task.done
return Task.done
def updateCoa(self, cam2point, coaDist = None):
def updateCoa(self, cam2point, coaDist = None): self.coa.set(cam2point[0], cam2point[1], cam2point[2])
self.coa.set(cam2point[0], cam2point[1], cam2point[2]) if coaDist:
if coaDist: self.coaDist = coaDist
self.coaDist = coaDist else:
else: self.coaDist = Vec3(self.coa - self.zeroPoint).length()
self.coaDist = Vec3(self.coa - self.zeroPoint).length() # Place the marker in render space
# Place the marker in render space self.coaMarker.setPos(self.camera,self.coa)
self.coaMarker.setPos(self.camera,self.coa) # Resize it
# Resize it self.updateCoaMarkerSize(coaDist)
self.updateCoaMarkerSize(coaDist) # Record marker pos in render space
# Record marker pos in render space self.coaMarkerPos.assign(self.coaMarker.getPos())
self.coaMarkerPos.assign(self.coaMarker.getPos())
def updateCoaMarkerSize(self, coaDist = None):
def updateCoaMarkerSize(self, coaDist = None): if not coaDist:
if not coaDist: coaDist = Vec3(self.coaMarker.getPos( self.chan.camera )).length()
coaDist = Vec3(self.coaMarker.getPos( self.chan.camera )).length() self.coaMarker.setScale(0.01 * coaDist *
self.coaMarker.setScale(0.01 * coaDist * math.tan(deg2Rad(self.chan.fovV)))
math.tan(deg2Rad(self.chan.fovV)))
def homeCam(self, chan):
def homeCam(self, chan): chan.camera.setMat(Mat4.identMat())
chan.camera.setMat(Mat4.identMat())
def uprightCam(self, chan):
def uprightCam(self, chan): taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') currH = chan.camera.getH()
currH = chan.camera.getH() chan.camera.lerpHpr(currH, 0, 0,
chan.camera.lerpHpr(currH, 0, 0, CAM_MOVE_DURATION,
CAM_MOVE_DURATION, other = render,
other = render, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera')
def centerCam(self, chan):
def centerCam(self, chan): # Chan is a display region context
# Chan is a display region context self.centerCamIn(chan, 1.0)
self.centerCamIn(chan, 1.0)
def centerCamNow(self, chan):
def centerCamNow(self, chan): self.centerCamIn(chan, 0.)
self.centerCamIn(chan, 0.)
def centerCamIn(self, chan, t):
def centerCamIn(self, chan, t): # Chan is a display region context
# Chan is a display region context taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') markerToCam = self.coaMarker.getPos( chan.camera )
markerToCam = self.coaMarker.getPos( chan.camera ) dist = Vec3(markerToCam - self.zeroPoint).length()
dist = Vec3(markerToCam - self.zeroPoint).length() scaledCenterVec = self.centerVec * dist
scaledCenterVec = self.centerVec * dist delta = markerToCam - scaledCenterVec
delta = markerToCam - scaledCenterVec self.relNodePath.setPosHpr(chan.camera, Point3(0), Point3(0))
self.relNodePath.setPosHpr(chan.camera, Point3(0), Point3(0)) chan.camera.lerpPos(Point3(delta),
chan.camera.lerpPos(Point3(delta), CAM_MOVE_DURATION,
CAM_MOVE_DURATION, other = self.relNodePath,
other = self.relNodePath, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera')
def zoomCam(self, chan, zoomFactor, t):
def zoomCam(self, chan, zoomFactor, t): taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Find a point zoom factor times the current separation
# Find a point zoom factor times the current separation # of the widget and cam
# of the widget and cam zoomPtToCam = self.coaMarker.getPos(chan.camera) * zoomFactor
zoomPtToCam = self.coaMarker.getPos(chan.camera) * zoomFactor # Put a target nodePath there
# Put a target nodePath there self.relNodePath.setPos(chan.camera, zoomPtToCam)
self.relNodePath.setPos(chan.camera, zoomPtToCam) # Move to that point
# Move to that point chan.camera.lerpPos(self.zeroPoint,
chan.camera.lerpPos(self.zeroPoint, CAM_MOVE_DURATION,
CAM_MOVE_DURATION, other = self.relNodePath,
other = self.relNodePath, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera')
def SpawnMoveToView(self, chan, view):
def SpawnMoveToView(self, chan, view): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Calc hprOffset
# Calc hprOffset hprOffset = VBase3()
hprOffset = VBase3() if view == 8:
if view == 8: # Try the next roll angle
# Try the next roll angle self.orthoViewRoll = (self.orthoViewRoll + 90.0) % 360.0
self.orthoViewRoll = (self.orthoViewRoll + 90.0) % 360.0 # but use the last view
# but use the last view view = self.lastView
view = self.lastView else:
else: self.orthoViewRoll = 0.0
self.orthoViewRoll = 0.0 # Adjust offset based on specified view
# Adjust offset based on specified view if view == 1:
if view == 1: hprOffset.set(180., 0., 0.)
hprOffset.set(180., 0., 0.) elif view == 2:
elif view == 2: hprOffset.set(0., 0., 0.)
hprOffset.set(0., 0., 0.) elif view == 3:
elif view == 3: hprOffset.set(90., 0., 0.)
hprOffset.set(90., 0., 0.) elif view == 4:
elif view == 4: hprOffset.set(-90., 0., 0.)
hprOffset.set(-90., 0., 0.) elif view == 5:
elif view == 5: hprOffset.set(0., -90., 0.)
hprOffset.set(0., -90., 0.) elif view == 6:
elif view == 6: hprOffset.set(0., 90., 0.)
hprOffset.set(0., 90., 0.) elif view == 7:
elif view == 7: hprOffset.set(135., -35.264, 0.)
hprOffset.set(135., -35.264, 0.) # Position target
# Position target self.relNodePath.setPosHpr(self.coaMarker, self.zeroBaseVec,
self.relNodePath.setPosHpr(self.coaMarker, self.zeroBaseVec, hprOffset)
hprOffset) # Scale center vec by current distance to target
# Scale center vec by current distance to target offsetDistance = Vec3(chan.camera.getPos(self.relNodePath) -
offsetDistance = Vec3(chan.camera.getPos(self.relNodePath) - self.zeroPoint).length()
self.zeroPoint).length() scaledCenterVec = self.centerVec * (-1.0 * offsetDistance)
scaledCenterVec = self.centerVec * (-1.0 * offsetDistance) # Now put the relNodePath at that point
# Now put the relNodePath at that point self.relNodePath.setPosHpr(self.relNodePath,
self.relNodePath.setPosHpr(self.relNodePath, scaledCenterVec,
scaledCenterVec, self.zeroBaseVec)
self.zeroBaseVec) # Record view for next time around
# Record view for next time around self.lastView = view
self.lastView = view chan.camera.lerpPosHpr(self.zeroPoint,
chan.camera.lerpPosHpr(self.zeroPoint, VBase3(0,0,self.orthoViewRoll),
VBase3(0,0,self.orthoViewRoll), CAM_MOVE_DURATION,
CAM_MOVE_DURATION, other = self.relNodePath,
other = self.relNodePath, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera')
def swingCamAboutWidget(self, chan, degrees, t):
def swingCamAboutWidget(self, chan, degrees, t): # Remove existing camera manipulation task
# Remove existing camera manipulation task taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera')
# Coincident with widget
# Coincident with widget self.relNodePath.setPos(self.coaMarker, self.zeroPoint)
self.relNodePath.setPos(self.coaMarker, self.zeroPoint) # But aligned with render space
# But aligned with render space self.relNodePath.setHpr(self.zeroPoint)
self.relNodePath.setHpr(self.zeroPoint)
parent = self.camera.getParent()
parent = self.camera.getParent() self.camera.wrtReparentTo(self.relNodePath)
self.camera.wrtReparentTo(self.relNodePath)
manipTask = self.relNodePath.lerpHpr(VBase3(degrees,0,0),
manipTask = self.relNodePath.lerpHpr(VBase3(degrees,0,0), CAM_MOVE_DURATION,
CAM_MOVE_DURATION, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera') # Upon death, reparent Cam to parent
# Upon death, reparent Cam to parent manipTask.parent = parent
manipTask.parent = parent manipTask.uponDeath = self.reparentCam
manipTask.uponDeath = self.reparentCam
def reparentCam(self, state):
def reparentCam(self, state): self.camera.wrtReparentTo(state.parent)
self.camera.wrtReparentTo(state.parent)
def spawnHPanYZoom(self):
def spawnHPanYZoom(self): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # hide the marker
# hide the marker self.coaMarker.hide()
self.coaMarker.hide() # Negate vec to give it the correct sense for mouse motion below
# Negate vec to give it the correct sense for mouse motion below targetVector = self.coa * -1
targetVector = self.coa * -1 t = Task.Task(self.HPanYZoomTask)
t = Task.Task(self.HPanYZoomTask) t.targetVector = targetVector
t.targetVector = targetVector taskMgr.spawnTaskNamed(t, 'manipulateCamera')
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
def HPanYZoomTask(self,state):
def HPanYZoomTask(self,state): targetVector = state.targetVector
targetVector = state.targetVector distToMove = targetVector * self.chan.mouseDeltaY
distToMove = targetVector * self.chan.mouseDeltaY self.camera.setPosHpr(self.camera,
self.camera.setPosHpr(self.camera, distToMove[0],
distToMove[0], distToMove[1],
distToMove[1], distToMove[2],
distToMove[2], (0.5 * self.chan.mouseDeltaX *
(0.5 * self.chan.mouseDeltaX * self.chan.fovH),
self.chan.fovH), 0.0, 0.0)
0.0, 0.0) return Task.cont
return Task.cont
def spawnXZTranslateOrHPPan(self):
def spawnXZTranslateOrHPPan(self): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Hide the marker
# Hide the marker self.coaMarker.hide()
self.coaMarker.hide() t = Task.Task(self.XZTranslateOrHPPanTask)
t = Task.Task(self.XZTranslateOrHPPanTask) t.scaleFactor = (self.coaDist / self.chan.near)
t.scaleFactor = (self.coaDist / self.chan.near) taskMgr.spawnTaskNamed(t, 'manipulateCamera')
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
def XZTranslateOrHPPanTask(self, state):
def XZTranslateOrHPPanTask(self, state): if direct.fShift:
if self.direct.fShift: self.camera.setHpr(self.camera,
self.camera.setHpr(self.camera, (0.5 * self.chan.mouseDeltaX *
(0.5 * self.chan.mouseDeltaX * self.chan.fovH),
self.chan.fovH), (-0.5 * self.chan.mouseDeltaY *
(-0.5 * self.chan.mouseDeltaY * self.chan.fovV),
self.chan.fovV), 0.0)
0.0) else:
else: self.camera.setPos(self.camera,
self.camera.setPos(self.camera, (-0.5 * self.chan.mouseDeltaX *
(-0.5 * self.chan.mouseDeltaX * self.chan.nearWidth *
self.chan.nearWidth * state.scaleFactor),
state.scaleFactor), 0.0,
0.0, (-0.5 * self.chan.mouseDeltaY *
(-0.5 * self.chan.mouseDeltaY * self.chan.nearHeight *
self.chan.nearHeight * state.scaleFactor))
state.scaleFactor)) return Task.cont
return Task.cont
def spawnXZTranslate(self):
def spawnXZTranslate(self): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Hide the marker
# Hide the marker self.coaMarker.hide()
self.coaMarker.hide() t = Task.Task(self.XZTranslateTask)
t = Task.Task(self.XZTranslateTask) t.scaleFactor = (self.coaDist / self.chan.near)
t.scaleFactor = (self.coaDist / self.chan.near) taskMgr.spawnTaskNamed(t, 'manipulateCamera')
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
def XZTranslateTask(self,state):
def XZTranslateTask(self,state): self.camera.setPos(self.camera,
self.camera.setPos(self.camera, (-0.5 * self.chan.mouseDeltaX *
(-0.5 * self.chan.mouseDeltaX * self.chan.nearWidth *
self.chan.nearWidth * state.scaleFactor),
state.scaleFactor), 0.0,
0.0, (-0.5 * self.chan.mouseDeltaY *
(-0.5 * self.chan.mouseDeltaY * self.chan.nearHeight *
self.chan.nearHeight * state.scaleFactor))
state.scaleFactor)) return Task.cont
return Task.cont
def spawnMouseRotateTask(self):
def spawnMouseRotateTask(self): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Set at markers position in render coordinates
# Set at markers position in render coordinates self.relNodePath.setPos(self.coaMarkerPos)
self.relNodePath.setPos(self.coaMarkerPos) self.relNodePath.setHpr(self.camera, self.zeroPoint)
self.relNodePath.setHpr(self.camera, self.zeroPoint) t = Task.Task(self.mouseRotateTask)
t = Task.Task(self.mouseRotateTask) t.wrtMat = self.camera.getMat( self.relNodePath )
t.wrtMat = self.camera.getMat( self.relNodePath ) taskMgr.spawnTaskNamed(t, 'manipulateCamera')
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
def mouseRotateTask(self, state):
def mouseRotateTask(self, state): wrtMat = state.wrtMat
wrtMat = state.wrtMat self.relNodePath.setHpr(self.relNodePath,
self.relNodePath.setHpr(self.relNodePath, (-0.5 * self.chan.mouseDeltaX * 180.0),
(-0.5 * self.chan.mouseDeltaX * 180.0), (0.5 * self.chan.mouseDeltaY * 180.0),
(0.5 * self.chan.mouseDeltaY * 180.0), 0.0)
0.0) self.camera.setMat(self.relNodePath, wrtMat)
self.camera.setMat(self.relNodePath, wrtMat) return Task.cont
return Task.cont
def spawnHPPan(self):
def spawnHPPan(self): # Kill any existing tasks
# Kill any existing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera') # Hide the marker
# Hide the marker self.coaMarker.hide()
self.coaMarker.hide() t = Task.Task(self.HPPanTask)
t = Task.Task(self.HPPanTask) taskMgr.spawnTaskNamed(t, 'manipulateCamera')
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
def HPPanTask(self, state):
def HPPanTask(self, state): self.camera.setHpr(self.camera,
self.camera.setHpr(self.camera, (0.5 * self.chan.mouseDeltaX *
(0.5 * self.chan.mouseDeltaX * self.chan.fovH),
self.chan.fovH), (-0.5 * self.chan.mouseDeltaY *
(-0.5 * self.chan.mouseDeltaY * self.chan.fovV),
self.chan.fovV), 0.0)
0.0) return Task.cont
return Task.cont
def fitOnWidget(self):
def fitOnWidget(self): # Fit the node on the screen
# Fit the node on the screen
# stop any ongoing tasks
# stop any ongoing tasks taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera')
# How big is the node?
# How big is the node? nodeScale = direct.widget.scalingNode.getScale(render)
nodeScale = self.direct.widget.scalingNode.getScale(render) maxScale = max(nodeScale[0],nodeScale[1],nodeScale[2])
maxScale = max(nodeScale[0],nodeScale[1],nodeScale[2]) maxDim = min(self.chan.nearWidth, self.chan.nearHeight)
maxDim = min(self.chan.nearWidth, self.chan.nearHeight)
# At what distance does the object fill 30% of the screen?
# At what distance does the object fill 30% of the screen? # Assuming radius of 1 on widget
# Assuming radius of 1 on widget camY = self.chan.near * (2.0 * maxScale)/(0.3 * maxDim)
camY = self.chan.near * (2.0 * maxScale)/(0.3 * maxDim)
# What is the vector through the center of the screen?
# What is the vector through the center of the screen? centerVec = Y_AXIS * camY
centerVec = Y_AXIS * camY
# Where is the node relative to the viewpoint
# Where is the node relative to the viewpoint vWidget2Camera = direct.widget.getPos(self.camera)
vWidget2Camera = self.direct.widget.getPos(self.camera)
# How far do you move the camera to be this distance from the node?
# How far do you move the camera to be this distance from the node? deltaMove = vWidget2Camera - centerVec
deltaMove = vWidget2Camera - centerVec
# Move a target there
# Move a target there self.relNodePath.setPos(self.camera, deltaMove)
self.relNodePath.setPos(self.camera, deltaMove)
parent = self.camera.getParent()
parent = self.camera.getParent() self.camera.wrtReparentTo(self.relNodePath)
self.camera.wrtReparentTo(self.relNodePath) fitTask = self.camera.lerpPos(Point3(0,0,0),
fitTask = self.camera.lerpPos(Point3(0,0,0), CAM_MOVE_DURATION,
CAM_MOVE_DURATION, blendType = 'easeInOut',
blendType = 'easeInOut', task = 'manipulateCamera')
task = 'manipulateCamera') # Upon death, reparent Cam to parent
# Upon death, reparent Cam to parent fitTask.parent = parent
fitTask.parent = parent fitTask.uponDeath = self.reparentCam
fitTask.uponDeath = self.reparentCam
def enableMouseFly(self):
def enableMouseFly(self): self.enableMouseInteraction()
self.enableMouseInteraction() self.enableHotKeys()
self.enableHotKeys() self.coaMarker.reparentTo(render)
self.coaMarker.reparentTo(render)
def enableMouseInteraction(self):
def enableMouseInteraction(self): # disable C++ fly interface
# disable C++ fly interface base.disableMouse()
base.disableMouse() # Accept middle mouse events
# Accept middle mouse events self.accept('handleMouse2', self.mouseFlyStart, [self.chan])
self.accept('handleMouse2', self.mouseFlyStart, [self.chan]) self.accept('handleMouse2Up', self.mouseFlyStop)
self.accept('handleMouse2Up', self.mouseFlyStop)
def enableHotKeys(self):
def enableHotKeys(self): t = CAM_MOVE_DURATION
t = CAM_MOVE_DURATION self.accept('u', self.uprightCam, [self.chan])
self.accept('u', self.uprightCam, [self.chan]) self.accept('c', self.centerCamIn, [self.chan, 0.5])
self.accept('c', self.centerCamIn, [self.chan, 0.5]) self.accept('h', self.homeCam, [self.chan])
self.accept('h', self.homeCam, [self.chan]) self.accept('f', self.fitOnWidget)
self.accept('f', self.fitOnWidget) for i in range(1,9):
for i in range(1,9): self.accept(`i`, self.SpawnMoveToView, [self.chan, i])
self.accept(`i`, self.SpawnMoveToView, [self.chan, i]) self.accept('9', self.swingCamAboutWidget, [self.chan, -90.0, t])
self.accept('9', self.swingCamAboutWidget, [self.chan, -90.0, t]) self.accept('0', self.swingCamAboutWidget, [self.chan, 90.0, t])
self.accept('0', self.swingCamAboutWidget, [self.chan, 90.0, t]) self.accept('`', self.removeManipulateCameraTask)
self.accept('`', self.removeManipulateCameraTask) self.accept('=', self.zoomCam, [self.chan, 0.5, t])
self.accept('=', self.zoomCam, [self.chan, 0.5, t]) self.accept('+', self.zoomCam, [self.chan, 0.5, t])
self.accept('+', self.zoomCam, [self.chan, 0.5, t]) self.accept('-', self.zoomCam, [self.chan, -2.0, t])
self.accept('-', self.zoomCam, [self.chan, -2.0, t]) self.accept('_', self.zoomCam, [self.chan, -2.0, t])
self.accept('_', self.zoomCam, [self.chan, -2.0, t])
def disableMouseFly(self):
def disableMouseFly(self): # Hide the marker
# Hide the marker self.coaMarker.reparentTo(hidden)
self.coaMarker.reparentTo(hidden) # Ignore middle mouse events
# Ignore middle mouse events self.ignore('handleMouse2')
self.ignore('handleMouse2') self.ignore('handleMouse2Up')
self.ignore('handleMouse2Up') self.ignore('u')
self.ignore('u') self.ignore('c')
self.ignore('c') self.ignore('h')
self.ignore('h') self.ignore('f')
self.ignore('f') for i in range(0,10):
for i in range(0,10): self.ignore(`i`)
self.ignore(`i`) self.ignore('=')
self.ignore('=') self.ignore('+')
self.ignore('+') self.ignore('-')
self.ignore('-') self.ignore('_')
self.ignore('_') self.ignore('`')
self.ignore('`')
def removeManipulateCameraTask(self):
def removeManipulateCameraTask(self): taskMgr.removeTasksNamed('manipulateCamera')
taskMgr.removeTasksNamed('manipulateCamera')

View File

@ -2,14 +2,11 @@ from PandaObject import *
from DirectGeometry import * from DirectGeometry import *
class DirectGrid(NodePath,PandaObject): class DirectGrid(NodePath,PandaObject):
def __init__(self, direct): def __init__(self):
# Initialize superclass # Initialize superclass
NodePath.__init__(self) NodePath.__init__(self)
self.assign(hidden.attachNewNode( NamedNode('DirectGrid'))) self.assign(hidden.attachNewNode( NamedNode('DirectGrid')))
# Record handle to direct session
self.direct = direct
# Load up grid parts to initialize grid object # Load up grid parts to initialize grid object
# Polygon used to mark grid plane # Polygon used to mark grid plane
self.gridBack = loader.loadModel('models/misc/gridBack') self.gridBack = loader.loadModel('models/misc/gridBack')
@ -60,7 +57,7 @@ class DirectGrid(NodePath,PandaObject):
def selectGridBackParent(self, nodePath): def selectGridBackParent(self, nodePath):
if nodePath.getName() == 'GridBack': if nodePath.getName() == 'GridBack':
self.direct.select(self) direct.select(self)
def updateGrid(self): def updateGrid(self):
# Update grid lines based upon current grid spacing and grid size # Update grid lines based upon current grid spacing and grid size

File diff suppressed because it is too large Load Diff

View File

@ -1,380 +1,379 @@
from PandaObject import * from PandaObject import *
from DirectGeometry import * from DirectGeometry import *
from DirectSelection import * from DirectSelection import *
class DirectNodePath(NodePath): class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods # A node path augmented with info, bounding box, and utility methods
def __init__(self, nodePath): def __init__(self, nodePath):
# Initialize the superclass # Initialize the superclass
NodePath.__init__(self) NodePath.__init__(self)
self.assign(nodePath) self.assign(nodePath)
# Get a reasonable name # Get a reasonable name
self.name = self.getName() self.name = self.getName()
# Create a bounding box # Create a bounding box
self.bbox = DirectBoundingBox(self) self.bbox = DirectBoundingBox(self)
center = self.bbox.getCenter() center = self.bbox.getCenter()
# Create matrix to hold the offset between the nodepath # Create matrix to hold the offset between the nodepath
# and its center of action (COA) # and its center of action (COA)
self.mCoa2Dnp = Mat4() self.mCoa2Dnp = Mat4()
self.mCoa2Dnp.assign(Mat4.identMat()) self.mCoa2Dnp.assign(Mat4.identMat())
# self.mCoa2Dnp.setRow(3, Vec4(center[0], center[1], center[2], 1)) # self.mCoa2Dnp.setRow(3, Vec4(center[0], center[1], center[2], 1))
# Transform from nodePath to widget # Transform from nodePath to widget
self.mDnp2Widget = Mat4() self.mDnp2Widget = Mat4()
self.mDnp2Widget.assign(Mat4.identMat()) self.mDnp2Widget.assign(Mat4.identMat())
def highlight(self): def highlight(self):
self.bbox.show() self.bbox.show()
def dehighlight(self): def dehighlight(self):
self.bbox.hide() self.bbox.hide()
def getCenter(self): def getCenter(self):
return self.bbox.getCenter() return self.bbox.getCenter()
def getRadius(self): def getRadius(self):
return self.bbox.getRadius() return self.bbox.getRadius()
def getMin(self): def getMin(self):
return self.bbox.getMin() return self.bbox.getMin()
def getMax(self): def getMax(self):
return self.bbox.getMax() return self.bbox.getMax()
def __repr__(self): def __repr__(self):
return ('NodePath:\t%s\n' % self.name) return ('NodePath:\t%s\n' % self.name)
class SelectedNodePaths(PandaObject): class SelectedNodePaths(PandaObject):
def __init__(self,direct): def __init__(self):
self.direct = direct self.selectedDict = {}
self.selectedDict = {} self.deselectedDict = {}
self.deselectedDict = {} self.last = None
self.last = None
def select(self, nodePath, fMultiSelect = 0):
def select(self, nodePath, fMultiSelect = 0): # Do nothing if nothing selected
# Do nothing if nothing selected if not nodePath:
if not nodePath: print 'Nothing selected!!'
print 'Nothing selected!!' return None
return None
# Reset selected objects and highlight if multiSelect is false
# Reset selected objects and highlight if multiSelect is false if not fMultiSelect:
if not fMultiSelect: self.deselectAll()
self.deselectAll()
# Get this pointer
# Get this pointer id = nodePath.id()
id = nodePath.id() # First see if its already in the selected dictionary
# First see if its already in the selected dictionary dnp = self.selectedDict.get(id, None)
dnp = self.selectedDict.get(id, None) # If so, we're done
# If so, we're done if not dnp:
if not dnp: # See if it is in the deselected dictionary
# See if it is in the deselected dictionary dnp = self.deselectedDict.get(id, None)
dnp = self.deselectedDict.get(id, None) if dnp:
if dnp: # It has been previously selected:
# It has been previously selected: # Show its bounding box
# Show its bounding box dnp.highlight()
dnp.highlight() # Remove it from the deselected dictionary
# Remove it from the deselected dictionary del(self.deselectedDict[id])
del(self.deselectedDict[id]) else:
else: # Didn't find it, create a new selectedNodePath instance
# Didn't find it, create a new selectedNodePath instance dnp = DirectNodePath(nodePath)
dnp = DirectNodePath(nodePath) # Show its bounding box
# Show its bounding box dnp.highlight()
dnp.highlight() # Add it to the selected dictionary
# Add it to the selected dictionary self.selectedDict[dnp.id()] = dnp
self.selectedDict[dnp.id()] = dnp # And update last
# And update last self.last = dnp
self.last = dnp return dnp
return dnp
def deselect(self, nodePath):
def deselect(self, nodePath): # Get this pointer
# Get this pointer id = nodePath.id()
id = nodePath.id() # See if it is in the selected dictionary
# See if it is in the selected dictionary dnp = self.selectedDict.get(id, None)
dnp = self.selectedDict.get(id, None) if dnp:
if dnp: # It was selected:
# It was selected: # Hide its bounding box
# Hide its bounding box dnp.dehighlight()
dnp.dehighlight() # Remove it from the selected dictionary
# Remove it from the selected dictionary del(self.selectedDict[id])
del(self.selectedDict[id]) # And keep track of it in the deselected dictionary
# And keep track of it in the deselected dictionary self.deselectedDict[id] = dnp
self.deselectedDict[id] = dnp return dnp
return dnp
def selectedAsList(self):
def selectedAsList(self): list = []
list = [] for key in self.selectedDict.keys():
for key in self.selectedDict.keys(): list.append(self.selectedDict[key])
list.append(self.selectedDict[key]) return list
return list
def __getitem__(self,index):
def __getitem__(self,index): return self.selectedAsList()[index]
return self.selectedAsList()[index]
def deselectedAsList(self):
def deselectedAsList(self): list = []
list = [] for key in self.deselectedDict.keys():
for key in self.deselectedDict.keys(): list.append(self.deselectedDict[key])
list.append(self.deselectedDict[key]) return list
return list
def forEachSelectedNodePathDo(self, func):
def forEachSelectedNodePathDo(self, func): duplicateKeys = self.selectedDict.keys()[:]
duplicateKeys = self.selectedDict.keys()[:] for key in duplicateKeys:
for key in duplicateKeys: func(self.selectedDict[key])
func(self.selectedDict[key])
def forEachDeselectedNodePathDo(self, func):
def forEachDeselectedNodePathDo(self, func): duplicateKeys = self.deselectedDict.keys()[:]
duplicateKeys = self.deselectedDict.keys()[:] for key in duplicateKeys:
for key in duplicateKeys: func(self.deselectedDict[key])
func(self.deselectedDict[key])
def getWrtAll(self):
def getWrtAll(self): self.forEachSelectedNodePathDo(self.getWrt)
self.forEachSelectedNodePathDo(self.getWrt)
def getWrt(self, nodePath):
def getWrt(self, nodePath): nodePath.mDnp2Widget.assign(nodePath.getMat(direct.widget))
nodePath.mDnp2Widget.assign(nodePath.getMat(self.direct.widget))
def moveWrtWidgetAll(self):
def moveWrtWidgetAll(self): self.forEachSelectedNodePathDo(self.moveWrtWidget)
self.forEachSelectedNodePathDo(self.moveWrtWidget)
def moveWrtWidget(self, nodePath):
def moveWrtWidget(self, nodePath): nodePath.setMat(direct.widget, nodePath.mDnp2Widget)
nodePath.setMat(self.direct.widget, nodePath.mDnp2Widget)
def deselectAll(self):
def deselectAll(self): self.forEachSelectedNodePathDo(self.deselect)
self.forEachSelectedNodePathDo(self.deselect)
def highlightAll(self):
def highlightAll(self): self.forEachSelectedNodePathDo(DirectNodePath.highlight)
self.forEachSelectedNodePathDo(DirectNodePath.highlight)
def dehighlightAll(self):
def dehighlightAll(self): self.forEachSelectedNodePathDo(DirectNodePath.dehighlight)
self.forEachSelectedNodePathDo(DirectNodePath.dehighlight)
def removeSelected(self):
def removeSelected(self): selected = self.dnp.last
selected = self.dnp.last if selected:
if selected: selected.remove()
selected.remove()
def removeAll(self):
def removeAll(self): # Remove all selected nodePaths from the Scene Graph
# Remove all selected nodePaths from the Scene Graph self.forEachSelectedNodePathDo(NodePath.remove)
self.forEachSelectedNodePathDo(NodePath.remove)
def toggleVizSelected(self):
def toggleVizSelected(self): selected = self.dnp.last
selected = self.dnp.last # Toggle visibility of selected node paths
# Toggle visibility of selected node paths if selected:
if selected: selected.toggleViz()
selected.toggleViz()
def toggleVizAll(self):
def toggleVizAll(self): # Toggle viz for all selected node paths
# Toggle viz for all selected node paths self.forEachSelectedNodePathDo(NodePath.toggleViz)
self.forEachSelectedNodePathDo(NodePath.toggleViz)
def isolateSelected(self):
def isolateSelected(self): selected = self.dnp.last
selected = self.dnp.last if selected:
if selected: selected.isolate()
selected.isolate()
def getDirectNodePath(self, nodePath):
def getDirectNodePath(self, nodePath): # Get this pointer
# Get this pointer id = nodePath.id()
id = nodePath.id() # First check selected dict
# First check selected dict dnp = self.selectedDict.get(id, None)
dnp = self.selectedDict.get(id, None) if dnp:
if dnp: return dnp
return dnp # Otherwise return result of deselected search
# Otherwise return result of deselected search return self.selectedDict.get(id, None)
return self.selectedDict.get(id, None)
def getNumSelected(self):
def getNumSelected(self): return len(self.selectedDict.keys())
return len(self.selectedDict.keys())
class DirectBoundingBox:
class DirectBoundingBox: def __init__(self, nodePath):
def __init__(self, nodePath): # Record the node path
# Record the node path self.nodePath = nodePath
self.nodePath = nodePath # Compute bounds, min, max, etc.
# Compute bounds, min, max, etc. self.computeBounds()
self.computeBounds() # Generate the bounding box
# Generate the bounding box self.lines = self.createBBoxLines()
self.lines = self.createBBoxLines()
def computeBounds(self):
def computeBounds(self): self.bounds = self.nodePath.getBounds()
self.bounds = self.nodePath.getBounds() if self.bounds.isEmpty():
if self.bounds.isEmpty(): self.center = Point3(0)
self.center = Point3(0) self.radius = 1.0
self.radius = 1.0 else:
else: self.center = self.bounds.getCenter()
self.center = self.bounds.getCenter() self.radius = self.bounds.getRadius()
self.radius = self.bounds.getRadius() self.min = Point3(self.center - Point3(self.radius))
self.min = Point3(self.center - Point3(self.radius)) self.max = Point3(self.center + Point3(self.radius))
self.max = Point3(self.center + Point3(self.radius))
def createBBoxLines(self):
def createBBoxLines(self): # Create a line segments object for the bbox
# Create a line segments object for the bbox lines = LineNodePath(hidden)
lines = LineNodePath(hidden) lines.node().setName('bboxLines')
lines.node().setName('bboxLines') lines.setColor( VBase4( 1., 0., 0., 1. ) )
lines.setColor( VBase4( 1., 0., 0., 1. ) ) lines.setThickness( 0.5 )
lines.setThickness( 0.5 )
minX = self.min[0]
minX = self.min[0] minY = self.min[1]
minY = self.min[1] minZ = self.min[2]
minZ = self.min[2] maxX = self.max[0]
maxX = self.max[0] maxY = self.max[1]
maxY = self.max[1] maxZ = self.max[2]
maxZ = self.max[2]
# Bottom face
# Bottom face lines.moveTo( minX, minY, minZ )
lines.moveTo( minX, minY, minZ ) lines.drawTo( maxX, minY, minZ )
lines.drawTo( maxX, minY, minZ ) lines.drawTo( maxX, maxY, minZ )
lines.drawTo( maxX, maxY, minZ ) lines.drawTo( minX, maxY, minZ )
lines.drawTo( minX, maxY, minZ ) lines.drawTo( minX, minY, minZ )
lines.drawTo( minX, minY, minZ )
# Front Edge/Top face
# Front Edge/Top face lines.drawTo( minX, minY, maxZ )
lines.drawTo( minX, minY, maxZ ) lines.drawTo( maxX, minY, maxZ )
lines.drawTo( maxX, minY, maxZ ) lines.drawTo( maxX, maxY, maxZ )
lines.drawTo( maxX, maxY, maxZ ) lines.drawTo( minX, maxY, maxZ )
lines.drawTo( minX, maxY, maxZ ) lines.drawTo( minX, minY, maxZ )
lines.drawTo( minX, minY, maxZ )
# Three remaining edges
# Three remaining edges lines.moveTo( maxX, minY, minZ )
lines.moveTo( maxX, minY, minZ ) lines.drawTo( maxX, minY, maxZ )
lines.drawTo( maxX, minY, maxZ ) lines.moveTo( maxX, maxY, minZ )
lines.moveTo( maxX, maxY, minZ ) lines.drawTo( maxX, maxY, maxZ )
lines.drawTo( maxX, maxY, maxZ ) lines.moveTo( minX, maxY, minZ )
lines.moveTo( minX, maxY, minZ ) lines.drawTo( minX, maxY, maxZ )
lines.drawTo( minX, maxY, maxZ )
# Create and return bbox lines
# Create and return bbox lines lines.create()
lines.create() return lines
return lines
def updateBBoxLines(self):
def updateBBoxLines(self): ls = self.lines.lineSegs
ls = self.lines.lineSegs
minX = self.min[0]
minX = self.min[0] minY = self.min[1]
minY = self.min[1] minZ = self.min[2]
minZ = self.min[2] maxX = self.max[0]
maxX = self.max[0] maxY = self.max[1]
maxY = self.max[1] maxZ = self.max[2]
maxZ = self.max[2]
# Bottom face
# Bottom face ls.setVertex( 0, minX, minY, minZ )
ls.setVertex( 0, minX, minY, minZ ) ls.setVertex( 1, maxX, minY, minZ )
ls.setVertex( 1, maxX, minY, minZ ) ls.setVertex( 2, maxX, maxY, minZ )
ls.setVertex( 2, maxX, maxY, minZ ) ls.setVertex( 3, minX, maxY, minZ )
ls.setVertex( 3, minX, maxY, minZ ) ls.setVertex( 4, minX, minY, minZ )
ls.setVertex( 4, minX, minY, minZ )
# Front Edge/Top face
# Front Edge/Top face ls.setVertex( 5, minX, minY, maxZ )
ls.setVertex( 5, minX, minY, maxZ ) ls.setVertex( 6, maxX, minY, maxZ )
ls.setVertex( 6, maxX, minY, maxZ ) ls.setVertex( 7, maxX, maxY, maxZ )
ls.setVertex( 7, maxX, maxY, maxZ ) ls.setVertex( 8, minX, maxY, maxZ )
ls.setVertex( 8, minX, maxY, maxZ ) ls.setVertex( 9, minX, minY, maxZ )
ls.setVertex( 9, minX, minY, maxZ )
# Three remaining edges
# Three remaining edges ls.setVertex( 10, maxX, minY, minZ )
ls.setVertex( 10, maxX, minY, minZ ) ls.setVertex( 11, maxX, minY, maxZ )
ls.setVertex( 11, maxX, minY, maxZ ) ls.setVertex( 12, maxX, maxY, minZ )
ls.setVertex( 12, maxX, maxY, minZ ) ls.setVertex( 13, maxX, maxY, maxZ )
ls.setVertex( 13, maxX, maxY, maxZ ) ls.setVertex( 14, minX, maxY, minZ )
ls.setVertex( 14, minX, maxY, minZ ) ls.setVertex( 15, minX, maxY, maxZ )
ls.setVertex( 15, minX, maxY, maxZ )
def getBounds(self):
def getBounds(self): # Get a node path's bounds
# Get a node path's bounds nodeBounds = self.nodePath.node().getBound()
nodeBounds = self.nodePath.node().getBound() for child in self.nodePath.getChildrenAsList():
for child in self.nodePath.getChildrenAsList(): nodeBounds.extendBy(child.getBottomArc().getBound())
nodeBounds.extendBy(child.getBottomArc().getBound()) return nodeBounds.makeCopy()
return nodeBounds.makeCopy()
def show(self):
def show(self): self.lines.reparentTo(self.nodePath)
self.lines.reparentTo(self.nodePath)
def hide(self):
def hide(self): self.lines.reparentTo(hidden)
self.lines.reparentTo(hidden)
def getCenter(self):
def getCenter(self): return self.center
return self.center
def getRadius(self):
def getRadius(self): return self.radius
return self.radius
def getMin(self):
def getMin(self): return self.min
return self.min
def getMax(self):
def getMax(self): return self.max
return self.max
def vecAsString(self, vec):
def vecAsString(self, vec): return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
def __repr__(self):
def __repr__(self): return (`self.__class__` +
return (`self.__class__` + '\nNodePath:\t%s\n' % self.nodePath.getName() +
'\nNodePath:\t%s\n' % self.nodePath.getName() + 'Min:\t\t%s\n' % self.vecAsString(self.min) +
'Min:\t\t%s\n' % self.vecAsString(self.min) + 'Max:\t\t%s\n' % self.vecAsString(self.max) +
'Max:\t\t%s\n' % self.vecAsString(self.max) + 'Center:\t\t%s\n' % self.vecAsString(self.center) +
'Center:\t\t%s\n' % self.vecAsString(self.center) + 'Radius:\t\t%.2f' % self.radius
'Radius:\t\t%.2f' % self.radius )
)
class SelectionRay:
class SelectionRay: def __init__(self, camera):
def __init__(self, camera): # Record the camera associated with this selection ray
# Record the camera associated with this selection ray self.camera = camera
self.camera = camera # Create a collision node
# Create a collision node self.rayCollisionNodePath = camera.attachNewNode( CollisionNode() )
self.rayCollisionNodePath = camera.attachNewNode( CollisionNode() ) # Don't pay the penalty of drawing this collision ray
# Don't pay the penalty of drawing this collision ray self.rayCollisionNodePath.hide()
self.rayCollisionNodePath.hide() self.rayCollisionNode = self.rayCollisionNodePath.node()
self.rayCollisionNode = self.rayCollisionNodePath.node() # Intersect with geometry to begin with
# Intersect with geometry to begin with self.collideWithGeom()
self.collideWithGeom() # Create a collision ray
# Create a collision ray self.ray = CollisionRay()
self.ray = CollisionRay() # Add the ray to the collision Node
# Add the ray to the collision Node self.rayCollisionNode.addSolid( self.ray )
self.rayCollisionNode.addSolid( self.ray ) # Create a queue to hold the collision results
# Create a queue to hold the collision results self.cq = CollisionHandlerQueue()
self.cq = CollisionHandlerQueue() self.numEntries = 0
self.numEntries = 0 # And a traverser to do the actual collision tests
# And a traverser to do the actual collision tests self.ct = CollisionTraverser( RenderRelation.getClassType() )
self.ct = CollisionTraverser( RenderRelation.getClassType() ) # Let the traverser know about the queue and the collision node
# Let the traverser know about the queue and the collision node self.ct.addCollider(self.rayCollisionNode, self.cq )
self.ct.addCollider(self.rayCollisionNode, self.cq )
def pickGeom(self, targetNodePath, mouseX, mouseY):
def pickGeom(self, targetNodePath, mouseX, mouseY): self.collideWithGeom()
self.collideWithGeom() return self.pick(targetNodePath, mouseX, mouseY)
return self.pick(targetNodePath, mouseX, mouseY)
def pickWidget(self, targetNodePath, mouseX, mouseY):
def pickWidget(self, targetNodePath, mouseX, mouseY): self.collideWithWidget()
self.collideWithWidget() return self.pick(targetNodePath, mouseX, mouseY)
return self.pick(targetNodePath, mouseX, mouseY)
def pick(self, targetNodePath, mouseX, mouseY):
def pick(self, targetNodePath, mouseX, mouseY): # Determine ray direction based upon the mouse coordinates
# Determine ray direction based upon the mouse coordinates # Note! This has to be a cam object (of type ProjectionNode)
# Note! This has to be a cam object (of type ProjectionNode) self.ray.setProjection( base.cam.node(), mouseX, mouseY )
self.ray.setProjection( base.cam.node(), mouseX, mouseY ) self.ct.traverse( targetNodePath.node() )
self.ct.traverse( targetNodePath.node() ) self.numEntries = self.cq.getNumEntries()
self.numEntries = self.cq.getNumEntries() self.cq.sortEntries()
self.cq.sortEntries() return self.numEntries
return self.numEntries
def collideWithGeom(self):
def collideWithGeom(self): self.rayCollisionNode.setIntoCollideMask(BitMask32().allOff())
self.rayCollisionNode.setIntoCollideMask(BitMask32().allOff()) self.rayCollisionNode.setFromCollideMask(BitMask32().allOff())
self.rayCollisionNode.setFromCollideMask(BitMask32().allOff()) self.rayCollisionNode.setCollideGeom(1)
self.rayCollisionNode.setCollideGeom(1)
def collideWithWidget(self):
def collideWithWidget(self): self.rayCollisionNode.setIntoCollideMask(BitMask32().allOff())
self.rayCollisionNode.setIntoCollideMask(BitMask32().allOff()) mask = BitMask32()
mask = BitMask32() mask.setWord(0x80000000)
mask.setWord(0x80000000) self.rayCollisionNode.setFromCollideMask(mask)
self.rayCollisionNode.setFromCollideMask(mask) self.rayCollisionNode.setCollideGeom(0)
self.rayCollisionNode.setCollideGeom(0)
def objectToHitPt(self, index):
def objectToHitPt(self, index): return self.cq.getEntry(index).getIntoIntersectionPoint()
return self.cq.getEntry(index).getIntoIntersectionPoint()
def camToHitPt(self, index):
def camToHitPt(self, index): # Get the specified entry
# Get the specified entry entry = self.cq.getEntry(index)
entry = self.cq.getEntry(index) hitPt = entry.getIntoIntersectionPoint()
hitPt = entry.getIntoIntersectionPoint() # Convert point from object local space to camera space
# Convert point from object local space to camera space return entry.getInvWrtSpace().xformPoint(hitPt)
return entry.getInvWrtSpace().xformPoint(hitPt)

View File

@ -5,10 +5,14 @@ from DirectSelection import *
from DirectGrid import * from DirectGrid import *
from DirectGeometry import * from DirectGeometry import *
import OnscreenText import OnscreenText
import __builtin__
class DirectSession(PandaObject): class DirectSession(PandaObject):
def __init__(self): def __init__(self):
# Establish a global pointer to the direct object early on
# so dependant classes can access it in their code
__builtin__.direct = self
self.contextList = [] self.contextList = []
self.iRayList = [] self.iRayList = []
for camera in base.cameraList: for camera in base.cameraList:
@ -17,14 +21,14 @@ class DirectSession(PandaObject):
self.chan = self.getChanData(0) self.chan = self.getChanData(0)
self.camera = base.cameraList[0] self.camera = base.cameraList[0]
self.cameraControl = DirectCameraControl(self) self.cameraControl = DirectCameraControl()
self.manipulationControl = DirectManipulationControl(self) self.manipulationControl = DirectManipulationControl()
self.useObjectHandles() self.useObjectHandles()
self.grid = DirectGrid(self) self.grid = DirectGrid()
self.grid.disable() self.grid.disable()
# Initialize the collection of selected nodePaths # Initialize the collection of selected nodePaths
self.selected = SelectedNodePaths(self) self.selected = SelectedNodePaths()
self.readout = OnscreenText.OnscreenText( '', 0.1, -0.95 ) self.readout = OnscreenText.OnscreenText( '', 0.1, -0.95 )
# self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5) # self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5)

View File

@ -1,10 +1,11 @@
from ShowBaseGlobal import * from ShowBaseGlobal import *
import __builtin__
# If specified in the user's Configrc, create the direct session
if base.wantDIRECT: # If specified in the user's Configrc, create the direct session
from DirectSession import * if base.wantDIRECT:
direct = base.direct = DirectSession() from DirectSession import *
else: __builtin__.direct = base.direct = DirectSession()
# Otherwise set the values to None else:
direct = base.direct = None # Otherwise set the values to None
__builtin__.direct = base.direct = None

View File

@ -1,15 +1,16 @@
"""instantiate global ShowBase object""" """instantiate global ShowBase object"""
from ShowBase import * from ShowBase import *
import __builtin__
base = ShowBase() __builtin__.base = ShowBase()
# Make some global aliases for convenience # Make some global aliases for convenience
render2d = base.render2d __builtin__.render2d = base.render2d
render = base.render __builtin__.render = base.render
hidden = base.hidden __builtin__.hidden = base.hidden
camera = base.camera __builtin__.camera = base.camera
loader = base.loader __builtin__.loader = base.loader
ostream = Notify.out() __builtin__.ostream = Notify.out()
run = base.run __builtin__.run = base.run
tkroot = base.tkroot __builtin__.tkroot = base.tkroot