mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 15:53:55 -04:00
*** empty log message ***
This commit is contained in:
parent
ad0e86bc6f
commit
dc229aacb8
@ -3161,7 +3161,7 @@ These are Python temporary files awaiting execution."
|
|||||||
(end-of-buffer)
|
(end-of-buffer)
|
||||||
(insert "run()")
|
(insert "run()")
|
||||||
(newline 1)
|
(newline 1)
|
||||||
(py-execute-string "try:\n\trun()\nexcept:\n\tpass"))
|
(py-execute-string "try:\n\trun()\nexcept NameError,e:\n\tif e.__str__() == 'run':\n\t\tpass\n\telse:\n\t\traise\nexcept:\n\traise"))
|
||||||
|
|
||||||
(provide 'python-mode)
|
(provide 'python-mode)
|
||||||
;;; python-mode.el ends here
|
;;; python-mode.el ends here
|
||||||
|
328
direct/src/directutil/DirectCameraControl.py
Normal file
328
direct/src/directutil/DirectCameraControl.py
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
from PandaObject import *
|
||||||
|
|
||||||
|
CAM_MOVE_DURATION = 1.0
|
||||||
|
|
||||||
|
class DirectCameraControl(PandaObject):
|
||||||
|
def __init__(self, direct):
|
||||||
|
# Create the grid
|
||||||
|
self.direct = direct
|
||||||
|
self.defChan = direct.chanCenter
|
||||||
|
self.orthoViewRoll = 0.0
|
||||||
|
self.lastView = 0
|
||||||
|
self.coa = Point3(0)
|
||||||
|
self.relNodePath = render.attachNewNode(NamedNode('targetNode'))
|
||||||
|
self.zeroBaseVec = VBase3(0)
|
||||||
|
self.zeroVector = Vec3(0)
|
||||||
|
self.centerVec = Vec3(0, 1, 0)
|
||||||
|
self.zeroPoint = Point3(0)
|
||||||
|
|
||||||
|
def mouseFlyStart(self, chan):
|
||||||
|
# Record starting mouse positions
|
||||||
|
self.initMouseX = chan.mouseX
|
||||||
|
self.initMouseY = chan.mouseY
|
||||||
|
# Where are we in the channel?
|
||||||
|
if ((abs(self.initMouseX) < 0.9) & (abs(self.initMouseY) < 0.9)):
|
||||||
|
# Mouse is in central region
|
||||||
|
# First compute a hit point based on current mouse position
|
||||||
|
if(self.direct.iRay.pick(render, chan.mouseX, chan.mouseY)):
|
||||||
|
# Find hit point in camera's space
|
||||||
|
self.coa = self.direct.iRay.hitPt(0)
|
||||||
|
# Handle case of bad coa point (too close or too far)
|
||||||
|
self.coaDist = Vec3(self.coa - self.zeroPoint).length()
|
||||||
|
if ((self.coaDist < (1.1 * self.defChan.near)) |
|
||||||
|
(self.coaDist > self.defChan.far)):
|
||||||
|
# Put it out in front of the camera
|
||||||
|
self.coa.set(0,10,0)
|
||||||
|
self.coaDist = 10
|
||||||
|
else:
|
||||||
|
# If no intersection point:
|
||||||
|
# Put coa out in front of the camera
|
||||||
|
self.coa.set(0,10,0)
|
||||||
|
self.coaDist = 10
|
||||||
|
# Now spawn task to determine mouse fly mode
|
||||||
|
self.determineMouseFlyMode()
|
||||||
|
else:
|
||||||
|
# Mouse is in outer frame, spawn mouseRotateTask
|
||||||
|
self.spawnMouseRotateTask()
|
||||||
|
|
||||||
|
def mouseFlyStop(self):
|
||||||
|
taskMgr.removeTasksNamed('determineMouseFlyMode')
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
|
||||||
|
def determineMouseFlyMode(self):
|
||||||
|
if (self.direct.fShift):
|
||||||
|
# If shift key is pressed:
|
||||||
|
self.spawnHPPan()
|
||||||
|
else:
|
||||||
|
# Otherwise, determine mouse fly mode
|
||||||
|
t = Task.Task(self.determineMouseFlyModeTask)
|
||||||
|
taskMgr.spawnTaskNamed(t, 'determineMouseFlyMode')
|
||||||
|
|
||||||
|
def determineMouseFlyModeTask(self, state):
|
||||||
|
deltaX = self.defChan.mouseX - self.initMouseX
|
||||||
|
deltaY = self.defChan.mouseY - self.initMouseY
|
||||||
|
if ((abs(deltaX) < 0.1) & (abs(deltaY) < 0.1)):
|
||||||
|
return Task.cont
|
||||||
|
else:
|
||||||
|
if (abs(deltaY) > 0.1):
|
||||||
|
self.spawnHPanYZoom()
|
||||||
|
else:
|
||||||
|
self.spawnXZTranslate()
|
||||||
|
return Task.done
|
||||||
|
|
||||||
|
def homeCam(self, chan):
|
||||||
|
chan.camera.setMat(Mat4.identMat())
|
||||||
|
|
||||||
|
def uprightCam(self, chan):
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
currH = chan.camera.getH()
|
||||||
|
chan.camera.lerpHpr(currH, 0, 0,
|
||||||
|
CAM_MOVE_DURATION,
|
||||||
|
other = render,
|
||||||
|
blendType = 'easeInOut',
|
||||||
|
task = 'manipulateCamera')
|
||||||
|
|
||||||
|
def centerCam(self, chan):
|
||||||
|
# Chan is a display region context
|
||||||
|
self.centerCamIn(chan, 1.0)
|
||||||
|
|
||||||
|
def centerCamNow(self, chan):
|
||||||
|
self.centerCamIn(chan, 0.)
|
||||||
|
|
||||||
|
def centerCamIn(self, chan,t):
|
||||||
|
# Chan is a display region context
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
widgetToCam = self.direct.widget.getPos( chan.camera )
|
||||||
|
dist = Vec3(widgetToCam - self.zeroPoint).length()
|
||||||
|
scaledCenterVec = self.centerVec * dist
|
||||||
|
delta = widgetToCam - scaledCenterVec
|
||||||
|
self.relNodePath.setPosHpr(chan.camera, Point3(0), Point3(0))
|
||||||
|
chan.camera.lerpPos(self.relNodePath,
|
||||||
|
Point3(delta),
|
||||||
|
CAM_MOVE_DURATION,
|
||||||
|
blendType = 'easeInOut',
|
||||||
|
task = 'manipulateCamera')
|
||||||
|
|
||||||
|
def zoomCam(self, chan, zoomFactor, t):
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
# Find a point zoom factor times the current separation
|
||||||
|
# of the widget and cam
|
||||||
|
zoomPtToCam = self.direct.widget.getPos(chan.camera) * zoomFactor
|
||||||
|
# Put a target nodePath there
|
||||||
|
self.relNodePath.setPos(chan.camera, zoomPtToCam)
|
||||||
|
# Move to that point
|
||||||
|
chan.camera.lerpPos(self.zeroPoint,
|
||||||
|
CAM_MOVE_DURATION,
|
||||||
|
other = self.relNodePath,
|
||||||
|
blendType = 'easeInOut',
|
||||||
|
task = 'manipulateCamera')
|
||||||
|
|
||||||
|
def SpawnMoveToView(self, chan, view):
|
||||||
|
# Kill any existing tasks
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
# Calc hprOffset
|
||||||
|
hprOffset = VBase3()
|
||||||
|
if view == 1:
|
||||||
|
hprOffset.set(180., 0., 0.)
|
||||||
|
elif view == 2:
|
||||||
|
hprOffset.set(0., 0., 0.)
|
||||||
|
elif view == 3:
|
||||||
|
hprOffset.set(90., 0., 0.)
|
||||||
|
elif view == 4:
|
||||||
|
hprOffset.set(-90., 0., 0.)
|
||||||
|
elif view == 5:
|
||||||
|
hprOffset.set(0., -90., 0.)
|
||||||
|
elif view == 6:
|
||||||
|
hprOffset.set(0., 90., 0.)
|
||||||
|
elif view == 7:
|
||||||
|
hprOffset.set(135., -35.264, 0.)
|
||||||
|
# Position target
|
||||||
|
self.relNodePath.setPosHpr(self.direct.widget,
|
||||||
|
self.zeroBaseVec,
|
||||||
|
hprOffset)
|
||||||
|
# Scale center vec by current distance to target
|
||||||
|
offsetDistance = Vec3(chan.camera.getPos(self.relNodePath) -
|
||||||
|
self.zeroPoint).length()
|
||||||
|
scaledCenterVec = self.centerVec * (-1.0 * offsetDistance)
|
||||||
|
|
||||||
|
# Now put the relNodePath at that point
|
||||||
|
self.relNodePath.setPosHpr(self.relNodePath,
|
||||||
|
scaledCenterVec,
|
||||||
|
self.zeroBaseVec)
|
||||||
|
|
||||||
|
# Start off with best view if change is to new view
|
||||||
|
if (view != self.lastView):
|
||||||
|
self.orthoViewRoll = 0.0
|
||||||
|
self.lastView = view
|
||||||
|
chan.camera.lerpPosHpr(self.zeroPoint,
|
||||||
|
VBase3(0,0,self.orthoViewRoll),
|
||||||
|
CAM_MOVE_DURATION,
|
||||||
|
other = self.relNodePath,
|
||||||
|
blendType = 'easeInOut',
|
||||||
|
task = 'manipulateCamera')
|
||||||
|
|
||||||
|
# Try another roll next time
|
||||||
|
self.orthoViewRoll = (self.orthoViewRoll + 90.0) % 360.0
|
||||||
|
|
||||||
|
def swingCamAboutWidget(self, chan, degrees, t):
|
||||||
|
# Remove existing camera manipulation task
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
|
||||||
|
# Coincident with widget
|
||||||
|
self.relNodePath.setPos(self.direct.widget, self.zeroPoint)
|
||||||
|
# But aligned with render space
|
||||||
|
self.relNodePath.setHpr(self.zeroPoint)
|
||||||
|
|
||||||
|
parent = self.defChan.camera.getParent
|
||||||
|
self.defChan.camera.wrtReparentTo(self.relNodePath)
|
||||||
|
|
||||||
|
self.relNodePath.lerpHpr(VBase3(degrees,0,0),
|
||||||
|
CAM_MOVE_DURATION,
|
||||||
|
blendType = 'easeInOut',
|
||||||
|
task = 'manipulateCamera')
|
||||||
|
# TODO: Convert this to an upon death
|
||||||
|
reparentTask = Task.Task(self.reparentCam)
|
||||||
|
reparentTask.parent = parent
|
||||||
|
reparentLater = Task.doLater(CAM_MOVE_DURATION,
|
||||||
|
reparentTask,
|
||||||
|
'manipulateCamera')
|
||||||
|
taskMgr.spawnTaskNamed(reparentLater, 'manipulateCamera')
|
||||||
|
|
||||||
|
def reparentCam(self, state):
|
||||||
|
self.defChan.camera.wrtReparentTo(state.parent)
|
||||||
|
return Task.done
|
||||||
|
|
||||||
|
def spawnHPanYZoom(self):
|
||||||
|
# Negate vec to give it the correct sense for mouse motion below
|
||||||
|
targetVector = self.coa * -1
|
||||||
|
t = Task.Task(self.HPanYZoomTask)
|
||||||
|
t.targetVector = targetVector
|
||||||
|
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
|
||||||
|
|
||||||
|
def HPanYZoomTask(self,state):
|
||||||
|
targetVector = state.targetVector
|
||||||
|
distToMove = targetVector * self.defChan.mouseDeltaY
|
||||||
|
self.defChan.camera.setPosHpr(self.defChan.camera,
|
||||||
|
distToMove[0],
|
||||||
|
distToMove[1],
|
||||||
|
distToMove[2],
|
||||||
|
(0.5 * self.defChan.mouseDeltaX *
|
||||||
|
self.defChan.fovH),
|
||||||
|
0.0, 0.0)
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
|
||||||
|
def spawnXZTranslateOrHPPan(self):
|
||||||
|
t = Task.Task(self.XZTranslateOrHPPanTask)
|
||||||
|
t.scaleFactor = (self.coaDist / self.defChan.near)
|
||||||
|
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
|
||||||
|
|
||||||
|
def XZTranslateOrHPPanTask(self, state):
|
||||||
|
if self.direct.fShift:
|
||||||
|
self.defChan.camera.setHpr(self.defChan.camera,
|
||||||
|
(0.5 * self.defChan.mouseDeltaX *
|
||||||
|
self.defChan.fovH),
|
||||||
|
(-0.5 * self.defChan.mouseDeltaY *
|
||||||
|
self.defChan.fovV),
|
||||||
|
0.0)
|
||||||
|
else:
|
||||||
|
self.defChan.camera.setPos(self.defChan.camera,
|
||||||
|
(-0.5 * self.defChan.mouseDeltaX *
|
||||||
|
self.defChan.nearWidth *
|
||||||
|
state.scaleFactor),
|
||||||
|
0.0,
|
||||||
|
(-0.5 * self.defChan.mouseDeltaY *
|
||||||
|
self.defChan.nearHeight *
|
||||||
|
state.scaleFactor))
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def spawnXZTranslate(self):
|
||||||
|
t = Task.Task(self.XZTranslateTask)
|
||||||
|
t.scaleFactor = (self.coaDist / self.defChan.near)
|
||||||
|
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
|
||||||
|
|
||||||
|
def XZTranslateTask(self,state):
|
||||||
|
self.defChan.camera.setPos(self.defChan.camera,
|
||||||
|
(-0.5 * self.defChan.mouseDeltaX *
|
||||||
|
self.defChan.nearWidth *
|
||||||
|
state.scaleFactor),
|
||||||
|
0.0,
|
||||||
|
(-0.5 * self.defChan.mouseDeltaY *
|
||||||
|
self.defChan.nearHeight *
|
||||||
|
state.scaleFactor))
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def spawnMouseRotateTask(self):
|
||||||
|
self.relNodePath.setPos(self.coa)
|
||||||
|
self.relNodePath.setHpr(self.defChan.camera, self.zeroPoint)
|
||||||
|
t = Task.Task(self.mouseRotateTask)
|
||||||
|
t.wrtMat = self.defChan.camera.getMat( self.relNodePath )
|
||||||
|
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
|
||||||
|
|
||||||
|
def mouseRotateTask(self, state):
|
||||||
|
wrtMat = state.wrtMat
|
||||||
|
self.relNodePath.setHpr(self.relNodePath,
|
||||||
|
(-0.5 * self.defChan.mouseDeltaX * 180.0),
|
||||||
|
(0.5 * self.defChan.mouseDeltaY * 180.0),
|
||||||
|
0.0)
|
||||||
|
self.defChan.camera.setMat(self.relNodePath, wrtMat)
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def spawnHPPan(self):
|
||||||
|
t = Task.Task(self.HPPanTask)
|
||||||
|
taskMgr.spawnTaskNamed(t, 'manipulateCamera')
|
||||||
|
|
||||||
|
def HPPanTask(self, state):
|
||||||
|
self.defChan.camera.setHpr(self.defChan.camera,
|
||||||
|
(0.5 * self.defChan.mouseDeltaX *
|
||||||
|
self.defChan.fovH),
|
||||||
|
(-0.5 * self.defChan.mouseDeltaY *
|
||||||
|
self.defChan.fovV),
|
||||||
|
0.0)
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def enableMouseFly(self):
|
||||||
|
self.enableMouseInteraction()
|
||||||
|
self.enableHotKeys()
|
||||||
|
|
||||||
|
def enableMouseInteraction(self):
|
||||||
|
# disable C++ fly interface
|
||||||
|
base.disableMouse()
|
||||||
|
# Accept middle mouse events
|
||||||
|
self.accept('mouse2', self.mouseFlyStart, [self.defChan])
|
||||||
|
self.accept('mouse2-up', self.mouseFlyStop)
|
||||||
|
|
||||||
|
def enableHotKeys(self):
|
||||||
|
t = CAM_MOVE_DURATION
|
||||||
|
self.accept('u', self.uprightCam, [self.defChan])
|
||||||
|
self.accept('c', self.centerCamIn, [self.defChan, 0.5])
|
||||||
|
self.accept('h', self.homeCam, [self.defChan])
|
||||||
|
for i in range(1,8):
|
||||||
|
self.accept(`i`, self.SpawnMoveToView, [self.defChan, i])
|
||||||
|
self.accept('9', self.swingCamAboutWidget, [self.defChan, -90.0, t])
|
||||||
|
self.accept('0', self.swingCamAboutWidget, [self.defChan, 90.0, t])
|
||||||
|
self.accept('8', self.removeManipulateCameraTask)
|
||||||
|
self.accept('=', self.zoomCam, [self.defChan, 0.5, t])
|
||||||
|
self.accept('+', self.zoomCam, [self.defChan, 0.5, t])
|
||||||
|
self.accept('-', self.zoomCam, [self.defChan, -2.0, t])
|
||||||
|
self.accept('_', self.zoomCam, [self.defChan, -2.0, t])
|
||||||
|
|
||||||
|
def disableMouseFly(self):
|
||||||
|
# Accept middle mouse events
|
||||||
|
self.ignore('mouse2')
|
||||||
|
self.ignore('mouse2-up')
|
||||||
|
self.ignore('u')
|
||||||
|
self.ignore('c')
|
||||||
|
self.ignore('h')
|
||||||
|
for i in range(0,10):
|
||||||
|
self.ignore(`i`)
|
||||||
|
self.ignore('=')
|
||||||
|
self.ignore('+')
|
||||||
|
self.ignore('-')
|
||||||
|
self.ignore('=')
|
||||||
|
|
||||||
|
def removeManipulateCameraTask(self):
|
||||||
|
taskMgr.removeTasksNamed('manipulateCamera')
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,307 +0,0 @@
|
|||||||
from PandaObject import *
|
|
||||||
from DirectGrid import DirectGrid
|
|
||||||
|
|
||||||
class DirectCameraManipulation(PandaObject):
|
|
||||||
def __init__():
|
|
||||||
# Create the grid
|
|
||||||
self.grid = DirectGrid(render)
|
|
||||||
self.grid.hide()
|
|
||||||
self.hitPt = Point3(0)
|
|
||||||
self.iPoint = Point3(0)
|
|
||||||
self.centerOfRotation = render.attachNewNode( NamedNode() )
|
|
||||||
self.centerOfRotation.node().setName( 'centerOfRotation' )
|
|
||||||
self.centerOfRotation.setPosHpr(Vec3(0), Vec3(0))
|
|
||||||
self.orthoViewRoll = 0.0
|
|
||||||
self.lastView = 0
|
|
||||||
self.targetNodePath = render.attachNewNode(NamedNode('targetNode'))
|
|
||||||
self.zeroBaseVec = VBase3(0)
|
|
||||||
self.zeroVector = Vec3(0)
|
|
||||||
self.centerVec = Vec3(0., 1., 0.)
|
|
||||||
self.zeroPoint = Point3(0)
|
|
||||||
|
|
||||||
def centerCam(chan):
|
|
||||||
# Chan is a display region context
|
|
||||||
self.centerCamIn(chan, 1.0)
|
|
||||||
|
|
||||||
def centerCamNow(chan):
|
|
||||||
self.centerCamIn(chan, 0.)
|
|
||||||
|
|
||||||
def centerCamIn(chan,t):
|
|
||||||
# Chan is a display region context
|
|
||||||
taskMgr.removeTasksNamed('manipulateCamera')
|
|
||||||
widgetToCam = direct.widget.getPos( chan.camera )
|
|
||||||
dist = Vec3(widgetToCam - zeroPoint).length()
|
|
||||||
scaledCenterVec = centerVec * dist.
|
|
||||||
delta = widgetToCam - scaledCenterVec.
|
|
||||||
relNodePath = render.attachNewNode(Node())
|
|
||||||
relNodePath.setPosHpr(chan.camera, Point3(0), Point3(0))
|
|
||||||
###
|
|
||||||
[ chan camera setPos: relNodePath pos: delta t: t.
|
|
||||||
] spawnTaskNamed: 'manipulateCamera'
|
|
||||||
uponDeath: [ relNodePath removeNode. ]
|
|
||||||
###
|
|
||||||
|
|
||||||
def homeCam(chan):
|
|
||||||
chan.camera.setMat(Mat4.identMat())
|
|
||||||
|
|
||||||
|
|
||||||
def mouseFlyStart(chan):
|
|
||||||
# Record starting mouse positions
|
|
||||||
initMouseX = chan.mouseX
|
|
||||||
initMouseY = chan.mouseY
|
|
||||||
|
|
||||||
# Where are we in the channel?
|
|
||||||
if ((initMouseX abs < 0.9) & (initMouseY abs < 0.9)):
|
|
||||||
# Mouse is in central region
|
|
||||||
# spawn task to determine mouse fly mode"
|
|
||||||
self.determineMouseFlyMode()
|
|
||||||
else:
|
|
||||||
#Mouse is in outer frame, spawn mouseRotateTask
|
|
||||||
self.spawnMouseRotateTask()
|
|
||||||
|
|
||||||
def mouseFlyStop():
|
|
||||||
taskMgr.removeTasksNamed('determineMouseFlyMode')
|
|
||||||
taskMgr.removeTasksNamed('manipulateCamera')
|
|
||||||
|
|
||||||
def removeManipulateCameraTask():
|
|
||||||
taskMgr.removeTasksNamed('manipulateCamera')
|
|
||||||
|
|
||||||
def enableMouseFly():
|
|
||||||
self.enableMouseInteraction()
|
|
||||||
self.enableHotKeys()
|
|
||||||
|
|
||||||
def enableMouseInteraction():
|
|
||||||
# disable C++ fly interface
|
|
||||||
base.disableMouse()
|
|
||||||
# Accept middle mouse events
|
|
||||||
self.accept('mouse2', self.mouseFlyStart, [chanCenter])
|
|
||||||
self.accept('mouse2-up' self.mouseFlyStop)
|
|
||||||
|
|
||||||
def disableMouseFly():
|
|
||||||
# Accept middle mouse events
|
|
||||||
self.ignore('mouse2')
|
|
||||||
self.ignore:'mouse2-up')
|
|
||||||
self.ignore('u')
|
|
||||||
self.ignore('c')
|
|
||||||
self.ignore('h')
|
|
||||||
for i in range(0,10):
|
|
||||||
self.ignore(`i`)
|
|
||||||
self.ignore('=')
|
|
||||||
self.ignore('+')
|
|
||||||
self.ignore('-')
|
|
||||||
self.ignore('=')
|
|
||||||
|
|
||||||
def enableHotKeys():
|
|
||||||
self.accept('u', self.uprightCam, [chanCenter])
|
|
||||||
self.accept('c', self.centerCamIn, [chanCenter, 0.5])
|
|
||||||
self.accept('h', self.homeCam, [chanCenter])
|
|
||||||
for i in range(1,8):
|
|
||||||
self.accept(`i`, self.moveToView, [chanCenter, i])
|
|
||||||
self.accept('9', self.swingCamAboutWidget, [chanCenter, -90.0, 1.0])
|
|
||||||
self.accept('0', self.swingCamAboutWidget, [chanCenter, 90.0, 1.0])
|
|
||||||
self.accept('8', self.removeManipulateCameraTask)
|
|
||||||
self.accept('=', self.zoomCam, [chanCenter, 0.5, 1.0])
|
|
||||||
self.accept('+', self.zoomCam, [chanCenter, 0.5, 1.0])
|
|
||||||
self.accept('-', self.zoomCam, [chanCenter, -2.0, 1.0])
|
|
||||||
self.accept('=', self.zoomCam, [chanCenter, -2.0, 1.0])
|
|
||||||
|
|
||||||
def SpawnMoveToView(chan, view):
|
|
||||||
# Kill any existing tasks
|
|
||||||
taskMgr.removeTasksNamed('manipulateCamera')
|
|
||||||
# Calc hprOffset
|
|
||||||
hprOffset = VBase3()
|
|
||||||
if view = 1:
|
|
||||||
hprOffset.set(180., 0., 0.)
|
|
||||||
elif view = 2:
|
|
||||||
hprOffset set(0., 0., 0.)
|
|
||||||
elif view = 3:
|
|
||||||
hprOffset set(90., 0., 0.)
|
|
||||||
elif view = 4:
|
|
||||||
hprOffset set(-90., 0., 0.)
|
|
||||||
elif view = 5:
|
|
||||||
hprOffset set(0., -90., 0.)
|
|
||||||
elif view = 6:
|
|
||||||
hprOffset set(0., 90., 0.)
|
|
||||||
elif view = 7:
|
|
||||||
hprOffset set(135., -35.264, 0.)
|
|
||||||
# Position target
|
|
||||||
targetNodePath.setPosHpr(direct.widget,
|
|
||||||
self.zeroBaseVec,
|
|
||||||
hprOffset)
|
|
||||||
# Scale center vec by current distance to target
|
|
||||||
offsetDistance = Vec3(chan.camera.getPos(targetNodePath) - \
|
|
||||||
zeroPoint).length()
|
|
||||||
scaledCenterVec = centerVec * (-1.0 * offsetDistance).
|
|
||||||
|
|
||||||
# Now put the targetNodePath at that point
|
|
||||||
targetNodePath.setPosHpr(targetNodePath,
|
|
||||||
scaledCenterVec,
|
|
||||||
zeroBaseVec)
|
|
||||||
|
|
||||||
# Start off with best view if change is to new view
|
|
||||||
if (view != lastView):
|
|
||||||
orthoViewRoll = 0.0
|
|
||||||
lastView = view.
|
|
||||||
|
|
||||||
[ chan camera setPosHpr: targetNodePath pos: zeroBaseVec
|
|
||||||
hpr: (VBase3 new: 0.0 y: 0.0 z: orthoViewRoll)
|
|
||||||
t: 1.0.
|
|
||||||
"Try another roll next time"
|
|
||||||
orthoViewRoll = (orthoViewRoll + 90.0) rem: 360.0.]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
|
|
||||||
|
|
||||||
def determineMouseFlyMode():
|
|
||||||
# Get mouse intersection point
|
|
||||||
# TBS
|
|
||||||
|
|
||||||
# Find this point to camera space
|
|
||||||
gridToCamera = grid getMat: chanCenter camera.
|
|
||||||
hitPt operatorAssign: (gridToCamera xformPoint: iPoint).
|
|
||||||
"Make sure hitPt is in front of the camera"
|
|
||||||
hitPt setY: (hitPt at: 1) abs.
|
|
||||||
|
|
||||||
"Handle case of bad hit point (too close or too far)"
|
|
||||||
hitDistance = (hitPt - zeroPoint) length.
|
|
||||||
((hitDistance < (1.1 * chanCenter near)) | (hitDistance > chanCenter far)) ifTrue: [
|
|
||||||
"Just use grid origin"
|
|
||||||
"hitPt operatorAssign: centerVec * (0.5 * (chanCenter far + chanCenter near))"
|
|
||||||
hitPt operatorAssign: (grid getPos: chanCenter camera).
|
|
||||||
].
|
|
||||||
|
|
||||||
(direct fShift) ifTrue: [ self.spawnHPPan. ]
|
|
||||||
ifFalse: [
|
|
||||||
[[deltaX = chanCenter mouseX - initMouseX.
|
|
||||||
deltaY = chanCenter mouseY - initMouseY.
|
|
||||||
((deltaX abs < 0.1) & (deltaY abs < 0.1))] taskWhileTrue: [ nil ]
|
|
||||||
] spawnTaskNamed: #determineMouseFlyMode
|
|
||||||
uponDeath: [
|
|
||||||
(deltaY abs > 0.1) ifTrue: [
|
|
||||||
self.spawnHPanYZoom]
|
|
||||||
ifFalse: [
|
|
||||||
self.spawnXZTranslate ].
|
|
||||||
].
|
|
||||||
].
|
|
||||||
! !
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
spawnHPPan
|
|
||||||
[[true] taskWhileTrue:
|
|
||||||
[ chanCenter camera setHpr: chanCenter camera
|
|
||||||
h: (0.5 * chanCenter mouseDeltaX * chanCenter fovH)
|
|
||||||
p: (-0.5 * chanCenter mouseDeltaY * chanCenter fovV)
|
|
||||||
r: 0.0 ]]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
spawnHPanYZoom
|
|
||||||
| targetVector distToMove |
|
|
||||||
targetVector = Vec3 new: (hitPt at: 0) y: (hitPt at: 1) z: (hitPt at: 2).
|
|
||||||
[[true] taskWhileTrue:
|
|
||||||
[ distToMove = targetVector * (-1.0 * chanCenter mouseDeltaY).
|
|
||||||
chanCenter camera setPosHpr: chanCenter camera
|
|
||||||
x: (distToMove at: 0)
|
|
||||||
y: (distToMove at: 1)
|
|
||||||
z: (distToMove at: 2)
|
|
||||||
h: (0.5 * chanCenter mouseDeltaX * chanCenter fovH)
|
|
||||||
p: 0.0 r: 0.0. ]]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
spawnMouseRotateTask
|
|
||||||
| wrtMat |
|
|
||||||
centerOfRotation setPos: grid pos: iPoint.
|
|
||||||
centerOfRotation setHpr: chanCenter camera h: 0.0 p: 0.0 r: 0.0.
|
|
||||||
|
|
||||||
wrtMat = chanCenter camera getMat: centerOfRotation.
|
|
||||||
|
|
||||||
[[true] taskWhileTrue:
|
|
||||||
[ centerOfRotation setHpr: centerOfRotation
|
|
||||||
h: (-0.5 * chanCenter mouseDeltaX * 180.0)
|
|
||||||
p: (0.5 * chanCenter mouseDeltaY * 180.0)
|
|
||||||
r: 0.0.
|
|
||||||
chanCenter camera setMat: centerOfRotation mat: wrtMat. ]]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
spawnXZTranslate
|
|
||||||
| scaleFactor |
|
|
||||||
scaleFactor = ((hitPt at: 1) / chanCenter near).
|
|
||||||
[[true] taskWhileTrue:
|
|
||||||
[ chanCenter camera setPos: chanCenter camera
|
|
||||||
x: (-0.5 * chanCenter mouseDeltaX * chanCenter nearWidth * scaleFactor)
|
|
||||||
y: 0.0
|
|
||||||
z: (-0.5 * chanCenter mouseDeltaY * chanCenter nearHeight * scaleFactor) ] ]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
spawnXZTranslateOrHPPan
|
|
||||||
| scaleFactor |
|
|
||||||
scaleFactor = ((hitPt at: 1) / chanCenter near).
|
|
||||||
[[true] taskWhileTrue:
|
|
||||||
[ direct fShift
|
|
||||||
ifTrue: [ chanCenter camera setHpr: chanCenter camera
|
|
||||||
h: (0.5 * chanCenter mouseDeltaX * chanCenter fovH)
|
|
||||||
p: (-0.5 * chanCenter mouseDeltaY * chanCenter fovV)
|
|
||||||
r: 0.0 ]
|
|
||||||
ifFalse: [ chanCenter camera setPos: chanCenter camera
|
|
||||||
x: (-0.5 * chanCenter mouseDeltaX * chanCenter nearWidth * scaleFactor)
|
|
||||||
y: 0.0
|
|
||||||
z: (-0.5 * chanCenter mouseDeltaY * chanCenter nearHeight * scaleFactor)]
|
|
||||||
]]
|
|
||||||
spawnTaskNamed: #manipulateCamera.
|
|
||||||
! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
swingCamAboutWidget: chan deg: degrees in: t
|
|
||||||
| relNodePath parent |
|
|
||||||
|
|
||||||
Task removeTasksNamed: #manipulateCamera.
|
|
||||||
|
|
||||||
relNodePath = showBase render attachNewNode: (Node new).
|
|
||||||
"Coincident with widget"
|
|
||||||
relNodePath setPos: direct widget pos: (Point3 zero).
|
|
||||||
"But aligned with render space"
|
|
||||||
relNodePath setHpr: (Point3 zero).
|
|
||||||
|
|
||||||
parent = chanCenter camera getParent.
|
|
||||||
chanCenter camera wrtReparentTo: relNodePath.
|
|
||||||
|
|
||||||
[ relNodePath setHpr: (VBase3 new: degrees y: 0.0 z: 0.0) t: t. ]
|
|
||||||
spawnTaskNamed: #manipulateCamera
|
|
||||||
uponDeath: [
|
|
||||||
chanCenter camera wrtReparentTo: parent.
|
|
||||||
relNodePath reparentTo: showBase hidden.
|
|
||||||
relNodePath removeNode.
|
|
||||||
].! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
uprightCam: chan
|
|
||||||
| currH |
|
|
||||||
Task removeTasksNamed: #manipulateCamera.
|
|
||||||
currH = chan camera getH.
|
|
||||||
[ chan camera setHpr: showBase render h: currH p: 0.0 r: 0.0 t: 1.0.
|
|
||||||
] spawnTaskNamed: #manipulateCamera.! !
|
|
||||||
|
|
||||||
!DirectCameraManipulation methodsFor: 'event handling' stamp: 'panda 00/00/0000 00:00'!
|
|
||||||
zoomCam: chan zoom: zoom in: t
|
|
||||||
| relNodePath zoomPtToCam |
|
|
||||||
Task removeTasksNamed: #manipulateCamera.
|
|
||||||
"Find a point zoom factor times the current separation of the widget and cam"
|
|
||||||
zoomPtToCam = (direct widget getPos: chan camera) * zoom.
|
|
||||||
|
|
||||||
"Put a target nodePath there"
|
|
||||||
relNodePath = showBase render attachNewNode: (Node new).
|
|
||||||
relNodePath setPos: chanCenter camera pos: zoomPtToCam.
|
|
||||||
|
|
||||||
"Move to that point"
|
|
||||||
[ chan camera setPos: relNodePath pos: (Point3 zero) t: t. ]
|
|
||||||
spawnTaskNamed: #manipulateCamera
|
|
||||||
uponDeath: [ relNodePath removeNode. ].! !
|
|
||||||
|
|
@ -2,11 +2,14 @@ from PandaObject import *
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
class LineNodePath(NodePath):
|
class LineNodePath(NodePath):
|
||||||
def __init__(self, parent = hidden, **kw):
|
def __init__(self, parent = None, **kw):
|
||||||
|
|
||||||
# Initialize the superclass
|
# Initialize the superclass
|
||||||
NodePath.__init__(self)
|
NodePath.__init__(self)
|
||||||
|
|
||||||
|
if parent is None:
|
||||||
|
parent = hidden
|
||||||
|
|
||||||
# Attach a geomNode to the parent and set self to be
|
# Attach a geomNode to the parent and set self to be
|
||||||
# the resulting node path
|
# the resulting node path
|
||||||
self.lineNode = GeomNode()
|
self.lineNode = GeomNode()
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
from PandaObject import *
|
from PandaObject import *
|
||||||
|
|
||||||
class DirectGrid(NodePath):
|
class DirectGrid(NodePath):
|
||||||
def __init__(self, parent = hidden):
|
def __init__(self, parent = None):
|
||||||
NodePath.__init__(self)
|
NodePath.__init__(self)
|
||||||
|
if parent is None:
|
||||||
|
parent = hidden
|
||||||
self.assign(parent.attachNewNode( NamedNode('grid') ))
|
self.assign(parent.attachNewNode( NamedNode('grid') ))
|
||||||
|
|
||||||
|
@ -1,31 +1,58 @@
|
|||||||
|
from PandaObject import *
|
||||||
|
|
||||||
|
class SelectionRay:
|
||||||
|
def __init__(self, camera, fGeom = 1):
|
||||||
|
# Record the camera associated with this selection ray
|
||||||
|
self.camera = camera
|
||||||
|
# Create a collision node
|
||||||
|
self.rayCollisionNodePath = camera.attachNewNode( CollisionNode() )
|
||||||
|
rayCollisionNode = self.rayCollisionNodePath.node()
|
||||||
|
# Specify if this ray collides with geometry
|
||||||
|
rayCollisionNode.setCollideGeom(fGeom)
|
||||||
|
# Create a collision ray
|
||||||
|
self.ray = CollisionRay()
|
||||||
|
# Add the ray to the collision Node
|
||||||
|
rayCollisionNode.addSolid( self.ray )
|
||||||
|
# Create a queue to hold the collision results
|
||||||
|
self.cq = CollisionHandlerQueue()
|
||||||
|
self.numEntries = 0
|
||||||
|
# And a traverser to do the actual collision tests
|
||||||
|
self.ct = CollisionTraverser( RenderRelation.getClassType() )
|
||||||
|
# Let the traverser know about the queue and the collision node
|
||||||
|
self.ct.addCollider(rayCollisionNode, self.cq )
|
||||||
|
|
||||||
|
def pick(self, targetNodePath, mouseX, mouseY):
|
||||||
|
# Determine ray direction based upon the mouse coordinates
|
||||||
|
# Note! This has to be a cam object (of type ProjectionNode)
|
||||||
|
self.ray.setProjection( base.cam.node(), mouseX, mouseY )
|
||||||
|
self.ct.traverse( targetNodePath.node() )
|
||||||
|
self.numEntries = self.cq.getNumEntries()
|
||||||
|
return self.numEntries
|
||||||
|
|
||||||
|
def localHitPt(self, index):
|
||||||
|
return self.cq.getEntry(index).getIntoIntersectionPoint()
|
||||||
|
|
||||||
|
def hitPt(self, index):
|
||||||
|
entry = self.cq.getEntry(index)
|
||||||
|
hitPt = entry.getIntoIntersectionPoint()
|
||||||
|
return entry.getWrtSpace().xformPoint(hitPt)
|
||||||
|
|
||||||
|
"""
|
||||||
dd = loader.loadModel(r"I:\beta\toons\install\neighborhoods\donalds_dock")
|
dd = loader.loadModel(r"I:\beta\toons\install\neighborhoods\donalds_dock")
|
||||||
dd.reparentTo(render)
|
dd.reparentTo(render)
|
||||||
|
|
||||||
cam = base.cam.node()
|
|
||||||
rNode = camera.attachNewNode( CollisionNode() )
|
|
||||||
rNode.node().setCollideGeom(1)
|
|
||||||
ray = CollisionRay()
|
|
||||||
rNode.node().addSolid( ray )
|
|
||||||
cq = CollisionHandlerQueue()
|
|
||||||
ct = CollisionTraverser( )
|
|
||||||
# Optionally
|
|
||||||
# ct = CollisionTraverser( RenderRelation.getClassType() )
|
|
||||||
ct.addCollider(rNode.node(), cq )
|
|
||||||
# These are the mouse coordinates
|
|
||||||
ray.setProjection( cam, 0, 0 )
|
|
||||||
ct.traverse( render.node() )
|
|
||||||
|
|
||||||
# Operations on cq
|
# Operations on cq
|
||||||
cq.getNumEntries()
|
cq.getNumEntries()
|
||||||
cq.getEntry(0).getIntoNode()
|
cq.getEntry(0).getIntoNode()
|
||||||
cq.getEntry(0).getIntoNode().getName()
|
cq.getEntry(0).getIntoNode().getName()
|
||||||
print cq.getEntry(i).getIntoIntersectionPoint()
|
print cq.getEntry(i).getIntoIntersectionPoint()
|
||||||
|
|
||||||
for i in range(0,cq.getNumEntries()):
|
for i in range(0,bobo.cq.getNumEntries()):
|
||||||
name = cq.getEntry(i).getIntoNode().getName()
|
name = bobo.cq.getEntry(i).getIntoNode().getName()
|
||||||
if not name:
|
if not name:
|
||||||
name = "<noname>"
|
name = "<noname>"
|
||||||
print name
|
print name
|
||||||
print cq.getEntry(i).getIntoIntersectionPoint()[0],
|
print bobo.cq.getEntry(i).getIntoIntersectionPoint()[0],
|
||||||
print cq.getEntry(i).getIntoIntersectionPoint()[1],
|
print bobo.cq.getEntry(i).getIntoIntersectionPoint()[1],
|
||||||
print cq.getEntry(i).getIntoIntersectionPoint()[2]
|
print bobo.cq.getEntry(i).getIntoIntersectionPoint()[2]
|
||||||
|
"""
|
||||||
|
@ -1,83 +1,320 @@
|
|||||||
from PandaObject import *
|
from PandaObject import *
|
||||||
from DirectGeometry import *
|
from DirectGeometry import *
|
||||||
|
from DirectSelection import *
|
||||||
|
from DirectCameraControl import *
|
||||||
import OnscreenText
|
import OnscreenText
|
||||||
import math
|
import math
|
||||||
|
|
||||||
class DisplayRegionContext(PandaObject):
|
|
||||||
def __init__(self, win, camera):
|
|
||||||
self.win = win
|
|
||||||
self.camera = camera
|
|
||||||
self.cam = camera.getChild(0)
|
|
||||||
self.camNode = self.cam.getNode(0)
|
|
||||||
self.mouseData = win.getMouseData(0)
|
|
||||||
self.mouseX = 0.0
|
|
||||||
self.mouseY = 0.0
|
|
||||||
|
|
||||||
def __getitem__(self,key):
|
|
||||||
return self.__dict__[key]
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
# First shutdown any existing task
|
|
||||||
self.stop()
|
|
||||||
# Start a new context task
|
|
||||||
self.spawnContextTask()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
# Kill the existing context task
|
|
||||||
taskMgr.removeTasksNamed('DIRECTContextTask')
|
|
||||||
|
|
||||||
def spawnContextTask(self):
|
|
||||||
taskMgr.spawnTaskNamed(Task.Task(self.contextTask),
|
|
||||||
'DIRECTContextTask')
|
|
||||||
|
|
||||||
def contextTask(self, state):
|
|
||||||
# Window Data
|
|
||||||
self.width = self.win.getWidth()
|
|
||||||
self.height = self.win.getHeight()
|
|
||||||
self.near = self.camNode.getNear()
|
|
||||||
self.far = self.camNode.getFar()
|
|
||||||
self.fovH = self.camNode.getHfov()
|
|
||||||
self.fovV = self.camNode.getVfov()
|
|
||||||
self.nearWidth = math.tan(deg2Rad(self.fovH / 2.0)) * self.near * 2.0
|
|
||||||
self.nearHeight = math.tan(deg2Rad(self.fovV / 2.0)) * self.near * 2.0
|
|
||||||
# Mouse Data
|
|
||||||
# Last frame
|
|
||||||
self.mouseLastX = self.mouseX
|
|
||||||
self.mouseLastY = self.mouseY
|
|
||||||
# This frame
|
|
||||||
self.mousePixelX = self.mouseData.getX()
|
|
||||||
self.mousePixelY = self.mouseData.getY()
|
|
||||||
self.mouseX = ((self.mousePixelX / float(self.width)) * 2.0) - 1.0
|
|
||||||
self.mouseY = ((self.mousePixelY / float(self.height)) * -2.0) + 1.0
|
|
||||||
self.mouseDeltaX = self.mouseX - self.mouseLastX
|
|
||||||
self.mouseDeltaY = self.mouseY - self.mouseLastY
|
|
||||||
# Continue the task
|
|
||||||
return Task.cont
|
|
||||||
|
|
||||||
class DirectSession(PandaObject):
|
class DirectSession(PandaObject):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.contextList = []
|
self.contextList = []
|
||||||
|
self.iRayList = []
|
||||||
for camera in base.cameraList:
|
for camera in base.cameraList:
|
||||||
self.contextList.append(DisplayRegionContext(base.win, camera))
|
self.contextList.append(DisplayRegionContext(base.win, camera))
|
||||||
|
self.iRayList.append(SelectionRay(camera))
|
||||||
|
self.chanCenter = self.getChanData(0)
|
||||||
|
|
||||||
|
self.cameraControls = DirectCameraControl(self)
|
||||||
|
|
||||||
# Initialize the collection of selected nodePaths
|
# Initialize the collection of selected nodePaths
|
||||||
self.selectedNodePaths = {}
|
self.selectedNodePaths = {}
|
||||||
|
self.selectedNodePath = None
|
||||||
self.lastSelected = None
|
self.lastSelected = None
|
||||||
|
|
||||||
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)
|
||||||
self.readout.reparentTo( hidden )
|
self.readout.reparentTo( hidden )
|
||||||
|
|
||||||
|
self.createObjectHandles()
|
||||||
|
self.useObjectHandles()
|
||||||
|
|
||||||
self.createBBox()
|
self.createBBox()
|
||||||
|
|
||||||
# self.createObjectHandles()
|
|
||||||
# self.useObjectHandles()
|
|
||||||
|
|
||||||
self.bboxList = []
|
self.bboxList = []
|
||||||
|
|
||||||
self.fControl = 0
|
self.fControl = 0
|
||||||
self.fAlt = 0
|
self.fAlt = 0
|
||||||
self.fShift = 0
|
self.fShift = 0
|
||||||
|
self.in2DWidget = 0
|
||||||
|
|
||||||
|
self.iRay = self.iRayList[0]
|
||||||
|
self.hitPt = Point3(0.0)
|
||||||
|
|
||||||
|
self.actionEvents = [('selectNodePath', self.selectNodePath),
|
||||||
|
('deselectNodePath', self.deselectNodePath),
|
||||||
|
('deselectAll', self.deselectAll),
|
||||||
|
('highlightNodePath', self.highlightNodePath),
|
||||||
|
('removeNodePath', self.removeNodePath),
|
||||||
|
('in2DWidget', self.in2DWidget)]
|
||||||
|
self.keyEvents = ['left', 'right', 'up', 'down',
|
||||||
|
'escape', 'space', 'delete',
|
||||||
|
'shift', 'shift-up', 'alt', 'alt-up',
|
||||||
|
'control', 'control-up',
|
||||||
|
'b', 'c', 'f', 'l', 't', 'v', 'w']
|
||||||
|
|
||||||
|
self.mouseEvents = ['mouse1', 'mouse1-up',
|
||||||
|
'mouse2', 'mouse2-up',
|
||||||
|
'mouse3', 'mouse3-up']
|
||||||
|
|
||||||
|
def selectNodePath(self, aNodePath, multiSelect = 0):
|
||||||
|
self.lastSelected = aNodePath
|
||||||
|
|
||||||
|
# Do nothing if nothing selected
|
||||||
|
if not aNodePath:
|
||||||
|
print 'Nothing selected!!'
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Reset selected objects and highlight if multiSelect is false
|
||||||
|
if not multiSelect:
|
||||||
|
self.deselectAll()
|
||||||
|
|
||||||
|
# Record newly selected object
|
||||||
|
# Use this pointer as an index
|
||||||
|
self.selectedNodePaths[aNodePath.this] = aNodePath
|
||||||
|
self.highlightNodePath(aNodePath)
|
||||||
|
self.readout.reparentTo(render2d)
|
||||||
|
self.readout.setText(self.getNodeName(aNodePath))
|
||||||
|
|
||||||
|
def getNodeName(self, aNodePath):
|
||||||
|
node = aNodePath.node()
|
||||||
|
name = '<noname>'
|
||||||
|
if issubclass(node.__class__, NamedNode):
|
||||||
|
namableName = node.getName()
|
||||||
|
if len(namableName) != 0:
|
||||||
|
name = namableName
|
||||||
|
return name
|
||||||
|
|
||||||
|
def in2DWidget(self):
|
||||||
|
self.in2DWidget = 1
|
||||||
|
|
||||||
|
def deselectNodePath(self, aNodePath):
|
||||||
|
# remove nodePath from selectedNodePaths dictionary if it exists
|
||||||
|
key = aNodePath.this
|
||||||
|
if self.selectedNodePaths.has_key(key):
|
||||||
|
del self.selectedNodePaths[key]
|
||||||
|
# Hide the manipulation widget
|
||||||
|
self.objectHandles.reparentTo(hidden)
|
||||||
|
self.readout.reparentTo(hidden)
|
||||||
|
self.readout.setText(' ')
|
||||||
|
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||||
|
|
||||||
|
def deselectAll(self):
|
||||||
|
self.selectedNodePaths = {}
|
||||||
|
# Hide the manipulation widget
|
||||||
|
self.objectHandles.reparentTo(hidden)
|
||||||
|
self.readout.reparentTo(hidden)
|
||||||
|
self.readout.setText(' ')
|
||||||
|
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||||
|
|
||||||
|
def highlightNodePath(self, aNodePath):
|
||||||
|
selectedBounds = self.getBounds(aNodePath)
|
||||||
|
# Does this work?
|
||||||
|
radius = selectedBounds.getRadius()
|
||||||
|
# radius = 5.0.
|
||||||
|
# Place the manipulation widget on the object too
|
||||||
|
self.objectHandles.reparentTo(render)
|
||||||
|
self.objectHandles.setScale(radius)
|
||||||
|
# Spawn task to have object handles follow the selected object
|
||||||
|
taskMgr.removeTasksNamed('followSelectedNodePath')
|
||||||
|
t = Task.Task(self.followSelectedNodePathTask)
|
||||||
|
t.aNodePath = aNodePath
|
||||||
|
taskMgr.spawnTaskNamed(t, 'followSelectedNodePath')
|
||||||
|
|
||||||
|
def followSelectedNodePathTask(self, state):
|
||||||
|
aNodePath = state.aNodePath
|
||||||
|
pos = aNodePath.getPos(render)
|
||||||
|
self.objectHandles.setPos(pos)
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
def isolateSelected(self):
|
||||||
|
selected = self.selectedNodePath
|
||||||
|
if selected:
|
||||||
|
self.showAllDescendants(selected.getParent())
|
||||||
|
self.hideSiblings(selected)
|
||||||
|
|
||||||
|
def removeNodePath(self, aNodePath):
|
||||||
|
# Method to handle the remove event sent by the Scene Graph Explorer
|
||||||
|
# Remove highlight and deselect nodePath
|
||||||
|
self.deselectNodePath(aNodePath)
|
||||||
|
# Send message in case anyone needs to do something
|
||||||
|
# before node is deleted
|
||||||
|
messenger.send('preRemoveNodePath', [aNodePath])
|
||||||
|
# Remove nodePath
|
||||||
|
aNodePath.reparentTo(hidden)
|
||||||
|
aNodePath.removeNode()
|
||||||
|
|
||||||
|
def removeSelectedNodePaths(self):
|
||||||
|
# Remove all selected nodePaths from the Scene Graph
|
||||||
|
for key in self.selectedNodePaths.keys():
|
||||||
|
np = self.selectedNodePaths[key]
|
||||||
|
self.removeNodePath(np)
|
||||||
|
|
||||||
|
def toggleVizSelectedNodePaths(self):
|
||||||
|
# Toggle visibility of selected node paths
|
||||||
|
for key in self.selectedNodePaths.keys():
|
||||||
|
path = self.selectedNodePaths[key]
|
||||||
|
if path.isHidden():
|
||||||
|
path.show()
|
||||||
|
else:
|
||||||
|
path.hide()
|
||||||
|
|
||||||
|
def getBounds(self, aNodePath):
|
||||||
|
# Get a node path's bounds
|
||||||
|
nodeBounds = aNodePath.node().getBound()
|
||||||
|
for kid in aNodePath.getChildrenAsList():
|
||||||
|
nodeBounds.extendBy(kid.getBottomArc().getBound())
|
||||||
|
return nodeBounds.makeCopy()
|
||||||
|
|
||||||
|
def showAllDescendantsSelectedNodePath(self):
|
||||||
|
# Show the descendants of the selectedNodePath
|
||||||
|
selected = self.selectedNodePath
|
||||||
|
if selected:
|
||||||
|
self.showAllDescendants(selected)
|
||||||
|
|
||||||
|
def showAllDescendants(self, aNodePath):
|
||||||
|
aNodePath.show()
|
||||||
|
for child in aNodePath.getChildrenAsList():
|
||||||
|
self.showAllDescendants(child)
|
||||||
|
|
||||||
|
def showSelectedNodePathSiblings(self):
|
||||||
|
selected = self.selectedNodePath
|
||||||
|
if selected:
|
||||||
|
self.showSiblings(selected)
|
||||||
|
|
||||||
|
def showSiblings(self, aNodePath):
|
||||||
|
aNodePath.show()
|
||||||
|
for sib in aNodePath.getParent().getChildrenAsList():
|
||||||
|
if sib != aNodePath:
|
||||||
|
sib.hide()
|
||||||
|
|
||||||
|
def hideSelectedNodePathSiblings(self):
|
||||||
|
selected = self.selectedNodePath
|
||||||
|
if selected:
|
||||||
|
self.hideSiblings(selected)
|
||||||
|
|
||||||
|
def hideSiblings(self, aNodePath):
|
||||||
|
aNodePath.show()
|
||||||
|
for sib in aNodePath.getParent().getChildrenAsList():
|
||||||
|
if sib != aNodePath:
|
||||||
|
sib.hide()
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
# Start all display region context tasks
|
||||||
|
for context in self.contextList:
|
||||||
|
context.spawnContextTask()
|
||||||
|
# Turn on mouse Flying
|
||||||
|
self.cameraControls.enableMouseFly()
|
||||||
|
# Accept appropriate hooks
|
||||||
|
self.enableKeyEvents()
|
||||||
|
self.enableMouseEvents()
|
||||||
|
self.enableActionEvents()
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
# Shut down all display region context tasks
|
||||||
|
for context in self.contextList:
|
||||||
|
context.removeContextTask()
|
||||||
|
# Turn off camera fly
|
||||||
|
self.cameraControls.disableMouseFly()
|
||||||
|
self.disableKeyEvents()
|
||||||
|
self.disableMouseEvents()
|
||||||
|
self.disableActionEvents()
|
||||||
|
|
||||||
|
def minimumConfiguration(self):
|
||||||
|
# Remove context task
|
||||||
|
for context in self.contextList:
|
||||||
|
context.removeContextTask()
|
||||||
|
# Turn off camera fly
|
||||||
|
self.cameraControls.disableMouseFly()
|
||||||
|
# Ignore keyboard and action events
|
||||||
|
self.disableKeyEvents()
|
||||||
|
self.disableActionEvents()
|
||||||
|
# But let mouse events pass through
|
||||||
|
self.enableMouseEvents()
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
self.disable()
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
self.enable()
|
||||||
|
|
||||||
|
def enableActionEvents(self):
|
||||||
|
for event, method in self.actionEvents:
|
||||||
|
self.accept(event, method)
|
||||||
|
|
||||||
|
def enableKeyEvents(self):
|
||||||
|
for event in self.keyEvents:
|
||||||
|
self.accept(event, self.inputHandler, [event])
|
||||||
|
|
||||||
|
def enableMouseEvents(self):
|
||||||
|
for event in self.mouseEvents:
|
||||||
|
self.accept(event, self.inputHandler, [event])
|
||||||
|
|
||||||
|
def disableActionEvents(self):
|
||||||
|
for event in self.actionEvents:
|
||||||
|
self.ignore(event)
|
||||||
|
|
||||||
|
def disableKeyEvents(self):
|
||||||
|
for event in self.keyEvents:
|
||||||
|
self.ignore(event)
|
||||||
|
|
||||||
|
def disableMouseEvents(self):
|
||||||
|
for event in self.mouseEvents:
|
||||||
|
self.ignore(event)
|
||||||
|
|
||||||
|
def useObjectHandles(self):
|
||||||
|
self.widget = self.objectHandles
|
||||||
|
|
||||||
|
def hideReadout(self):
|
||||||
|
self.readout.reparentTo(hidden)
|
||||||
|
|
||||||
|
def getChanData(self, index):
|
||||||
|
return self.contextList[index]
|
||||||
|
|
||||||
|
def inputHandler(self, input):
|
||||||
|
# Deal with keyboard and mouse input
|
||||||
|
if ((input != 'mouse1-up') & (input != 'mouse2-up') &
|
||||||
|
(input != 'mouse3-up')):
|
||||||
|
self.in2DWidget = 0
|
||||||
|
|
||||||
|
if input == 'mouse1':
|
||||||
|
messenger.send('handle2DMouse1')
|
||||||
|
if not self.in2DWidget:
|
||||||
|
messenger.send('handleMouse1')
|
||||||
|
elif input == 'mouse1-up':
|
||||||
|
messenger.send('handle2DMouse1Up')
|
||||||
|
if not self.in2DWidget:
|
||||||
|
messenger.send('handleMouse1Up')
|
||||||
|
elif input == 'mouse3':
|
||||||
|
messenger.send('handleMouse3')
|
||||||
|
elif input == 'mouse3-up':
|
||||||
|
messenger.send('handleMouse3Up')
|
||||||
|
elif input == 'shift':
|
||||||
|
self.fShift = true
|
||||||
|
elif input == 'shift-up':
|
||||||
|
self.fShift = false
|
||||||
|
elif input == 'control':
|
||||||
|
self.fControl = true
|
||||||
|
elif input == 'control-up':
|
||||||
|
self.fControl = false
|
||||||
|
elif input == 'alt':
|
||||||
|
self.fAlt = true
|
||||||
|
elif input == 'alt-up':
|
||||||
|
self.fAlt = false
|
||||||
|
elif input == 'escape':
|
||||||
|
self.deselectAll()
|
||||||
|
elif input == 'l':
|
||||||
|
if not self.lastSelected:
|
||||||
|
self.selectNodePath(self.lastSelected)
|
||||||
|
elif input == 'delete':
|
||||||
|
self.removeSelectedNodePaths()
|
||||||
|
elif input == 'v':
|
||||||
|
self.toggleVizSelectedNodePaths()
|
||||||
|
elif input == 'b':
|
||||||
|
base.toggleBackface()
|
||||||
|
elif input == 't':
|
||||||
|
base.toggleTexture()
|
||||||
|
elif input == 'w':
|
||||||
|
base.toggleWireframe()
|
||||||
|
|
||||||
def createBBox(self, parent = hidden):
|
def createBBox(self, parent = hidden):
|
||||||
# Create a line segments object for the bbox
|
# Create a line segments object for the bbox
|
||||||
@ -111,19 +348,20 @@ class DirectSession(PandaObject):
|
|||||||
bbox.create()
|
bbox.create()
|
||||||
|
|
||||||
def createObjectHandles(self):
|
def createObjectHandles(self):
|
||||||
oh = self.objectHandles = hidden.attachNewNode( NamedNode('objectHandles') )
|
oh = self.objectHandles = hidden.attachNewNode(
|
||||||
|
NamedNode('objectHandles') )
|
||||||
ohLines = LineNodePath( oh )
|
ohLines = LineNodePath( oh )
|
||||||
ohLines.setColor( VBase4( 1.0, 0.0, 1.0, 1.0) )
|
ohLines.setColor( VBase4( 1.0, 0.0, 1.0, 1.0) )
|
||||||
ohLines.setThickness( 3.0 )
|
ohLines.setThickness( 3.0 )
|
||||||
|
|
||||||
"InnerRing"
|
# InnerRing
|
||||||
ohLines.moveTo( 0.8, 0.0, 0.0 )
|
ohLines.moveTo( 0.8, 0.0, 0.0 )
|
||||||
for ang in range(10, 360, 10):
|
for ang in range(10, 360, 10):
|
||||||
ohLines.drawTo( (0.8 * math.cos(deg2Rad(ang))),
|
ohLines.drawTo( (0.8 * math.cos(deg2Rad(ang))),
|
||||||
(0.8 * math.sin(deg2Rad(ang))),
|
(0.8 * math.sin(deg2Rad(ang))),
|
||||||
0.0 )
|
0.0 )
|
||||||
|
|
||||||
"Outer Ring"
|
# Outer Ring
|
||||||
ohLines.moveTo( 1.2, 0.0, 0.0 )
|
ohLines.moveTo( 1.2, 0.0, 0.0 )
|
||||||
for ang in range(0, 360, 10):
|
for ang in range(0, 360, 10):
|
||||||
ohLines.drawTo( (1.2 * math.cos(deg2Rad(ang))),
|
ohLines.drawTo( (1.2 * math.cos(deg2Rad(ang))),
|
||||||
@ -132,12 +370,61 @@ class DirectSession(PandaObject):
|
|||||||
|
|
||||||
ohLines.moveTo( 0.0, 0.0, 0.0 )
|
ohLines.moveTo( 0.0, 0.0, 0.0 )
|
||||||
ohLines.drawTo( 0.0, 0.0, 1.5 )
|
ohLines.drawTo( 0.0, 0.0, 1.5 )
|
||||||
|
# Create the line segments
|
||||||
ohLines.create()
|
ohLines.create()
|
||||||
|
|
||||||
|
class DisplayRegionContext(PandaObject):
|
||||||
|
def __init__(self, win, camera):
|
||||||
|
self.win = win
|
||||||
|
self.camera = camera
|
||||||
|
self.cam = camera.getChild(0)
|
||||||
|
self.camNode = self.cam.getNode(0)
|
||||||
|
self.mouseData = win.getMouseData(0)
|
||||||
|
self.mouseX = 0.0
|
||||||
|
self.mouseY = 0.0
|
||||||
|
|
||||||
|
def __getitem__(self,key):
|
||||||
|
return self.__dict__[key]
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
# First shutdown any existing task
|
||||||
|
self.stop()
|
||||||
|
# Start a new context task
|
||||||
|
self.spawnContextTask()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
# Kill the existing context task
|
||||||
|
taskMgr.removeTasksNamed('DIRECTContextTask')
|
||||||
|
|
||||||
|
def spawnContextTask(self):
|
||||||
|
taskMgr.spawnTaskNamed(Task.Task(self.contextTask),
|
||||||
|
'DIRECTContextTask')
|
||||||
|
|
||||||
|
def removeContextTask(self):
|
||||||
|
taskMgr.removeTasksNamed('DIRECTContextTask')
|
||||||
|
|
||||||
|
def contextTask(self, state):
|
||||||
|
# Window Data
|
||||||
|
self.width = self.win.getWidth()
|
||||||
|
self.height = self.win.getHeight()
|
||||||
|
self.near = self.camNode.getNear()
|
||||||
|
self.far = self.camNode.getFar()
|
||||||
|
self.fovH = self.camNode.getHfov()
|
||||||
|
self.fovV = self.camNode.getVfov()
|
||||||
|
self.nearWidth = math.tan(deg2Rad(self.fovH / 2.0)) * self.near * 2.0
|
||||||
|
self.nearHeight = math.tan(deg2Rad(self.fovV / 2.0)) * self.near * 2.0
|
||||||
|
# Mouse Data
|
||||||
|
# Last frame
|
||||||
|
self.mouseLastX = self.mouseX
|
||||||
|
self.mouseLastY = self.mouseY
|
||||||
|
# This frame
|
||||||
|
self.mousePixelX = self.mouseData.getX()
|
||||||
|
self.mousePixelY = self.mouseData.getY()
|
||||||
|
self.mouseX = ((self.mousePixelX / float(self.width)) * 2.0) - 1.0
|
||||||
|
self.mouseY = ((self.mousePixelY / float(self.height)) * -2.0) + 1.0
|
||||||
|
self.mouseDeltaX = self.mouseX - self.mouseLastX
|
||||||
|
self.mouseDeltaY = self.mouseY - self.mouseLastY
|
||||||
|
# Continue the task
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,12 @@
|
|||||||
of the NodePath class
|
of the NodePath class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# For iterating over children
|
||||||
|
def getChildrenAsList(self):
|
||||||
|
childrenList = []
|
||||||
|
for childNum in range(self.getNumChildren()):
|
||||||
|
childrenList.append(self.getChild(childNum))
|
||||||
|
return childrenList
|
||||||
|
|
||||||
# private methods
|
# private methods
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ class ShowBase:
|
|||||||
# Store dconfig variables
|
# Store dconfig variables
|
||||||
self.wantTk = self.config.GetBool('want-tk', 0)
|
self.wantTk = self.config.GetBool('want-tk', 0)
|
||||||
self.wantSound = self.config.GetBool('want-sound', 1)
|
self.wantSound = self.config.GetBool('want-sound', 1)
|
||||||
|
self.wantDIRECT = self.config.GetBool('want-directtools', 0)
|
||||||
|
|
||||||
import Loader
|
import Loader
|
||||||
|
|
||||||
|
@ -12,3 +12,12 @@ camera = base.camera
|
|||||||
loader = base.loader
|
loader = base.loader
|
||||||
run = base.run
|
run = base.run
|
||||||
tkroot = base.tkroot
|
tkroot = base.tkroot
|
||||||
|
|
||||||
|
# Now create the DIRECT tools
|
||||||
|
if base.wantDIRECT:
|
||||||
|
import DirectSession
|
||||||
|
direct = base.direct = DirectSession.DirectSession()
|
||||||
|
chanCenter = direct.chanCenter
|
||||||
|
else:
|
||||||
|
direct = base.direct = None
|
||||||
|
chanCenter = None
|
||||||
|
@ -252,6 +252,8 @@ class TaskManager:
|
|||||||
self.step()
|
self.step()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.stop()
|
self.stop()
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
# Set a flag so we will stop before beginning next frame
|
# Set a flag so we will stop before beginning next frame
|
||||||
|
Loading…
x
Reference in New Issue
Block a user