*** empty log message ***

This commit is contained in:
Mark Mine 2000-10-25 16:41:58 +00:00
parent 28c07298d5
commit 79bc776db2
6 changed files with 541 additions and 277 deletions

View File

@ -101,12 +101,12 @@ See the Python Mode home page for details:
:group 'languages
:prefix "py-")
(defcustom py-python-command "ppython"
(defcustom py-python-command "python"
"*Shell command used to start Python interpreter."
:type 'string
:group 'python)
(defcustom pyd-python-command "ppython"
(defcustom pyd-python-command "python_d"
"*Shell command used to start Python interpreter."
:type 'string
:group 'python)
@ -142,7 +142,7 @@ mode buffer is visited during an Emacs session. After that, use
:group 'python)
(defcustom pyd-python-command-args '("-d -i")
(defcustom pyd-python-command-args '("-i")
"*List of string arguments to be used when starting a Python shell."
:type '(repeat string)
:group 'python)
@ -562,6 +562,8 @@ Currently-active file is at the head of the list.")
(define-key py-shell-map "\C-c=" 'py-down-exception)
;; VR STUDIO ENHANCEMENTS
(define-key py-shell-map "\C-d" 'comint-delchar-or-maybe-python-resume)
(define-key py-shell-map [return] 'comint-interrupt-subjob-or-maybe-return)
(define-key py-shell-map [C-return] 'comint-send-input)
(define-key py-shell-map "\C-c\C-r" 'python-resume)
(define-key py-shell-map "\C-c\C-s" 'pyd-shell)
)
@ -3165,6 +3167,15 @@ These are Python temporary files awaiting execution."
(python-resume)
(delete-char arg))))
(defun comint-interrupt-subjob-or-maybe-return (arg)
"Enter a return (comint-send-input) or send a comint-interrupt-subjob
if point is at the end of the buffer and there is no input"
(interactive "p")
(let ((proc (get-buffer-process (current-buffer))))
(if (and (eobp) proc (= (point) (marker-position (process-mark proc))))
(comint-interrupt-subjob)
(comint-send-input))))
;; Function to try to resume panda mainloop
(defun python-resume ()
(interactive)

View File

@ -1,6 +1,20 @@
#! /bin/sh
# Note: De-cygwin-ifying the PYTHONPATH is now the job of ppython
# Under Windows/Cygwin, we have to de-cygwinify the semicolon
# separated PYTHONPATH
# First, initialize the new path
NEWPYTHONPATH=
# To iterate, temporarily change the semicolons into spaces
for path in `echo $PYTHONPATH | sed 'y/;/ /'`; do
# Then for each entry run it through the cygwin filter
NEWPYTHONPATH=$NEWPYTHONPATH\;`cygpath -w $path`
done
# Export the new PYTHONPATH
PYTHONPATH=$NEWPYTHONPATH
export PYTHONPATH
# Lets also de-cygwinify the Project variables (so you can use file name
# completion) This is hardcoded for the most popular trees

View File

@ -6,8 +6,8 @@ class DirectCameraControl(PandaObject):
def __init__(self, direct):
# Create the grid
self.direct = direct
self.defChan = direct.chanCenter
self.camera = self.defChan.camera
self.chan = direct.chanCenter
self.camera = self.chan.camera
self.orthoViewRoll = 0.0
self.lastView = 0
self.coa = Point3(0)
@ -34,39 +34,39 @@ class DirectCameraControl(PandaObject):
# Otherwise, check for a hit point based on current mouse position
# And then spawn task to determine mouse mode
numEntries = self.direct.iRay.pick(render,chan.mouseX,chan.mouseY)
coa = Point3(0)
if(numEntries):
# Start off with first point
minPt = 0
# Find hit point in camera's space
self.coa = self.direct.iRay.camToHitPt(minPt)
self.coaDist = Vec3(self.coa - self.zeroPoint).length()
hitPt = self.direct.iRay.camToHitPt(minPt)
coa.set(hitPt[0],hitPt[1],hitPt[2])
coaDist = Vec3(coa - self.zeroPoint).length()
# Check other intersection points, sorting them
# TBD: Use TBS C++ function to do this
if numEntries > 1:
for i in range(1,numEntries):
hitPt = self.direct.iRay.camToHitPt(i)
dist = Vec3(hitPt - self.zeroPoint).length()
if (dist < self.coaDist):
self.coaDist = dist
self.coa = hitPt
if (dist < coaDist):
coaDist = dist
coa.set(hitPt[0],hitPt[1],hitPt[2])
minPt = i
# Handle case of bad coa point (too close or too far)
if ((self.coaDist < (1.1 * self.defChan.near)) |
(self.coaDist > self.defChan.far)):
if ((coaDist < (1.1 * self.chan.near)) |
(coaDist > self.chan.far)):
# Put it out in front of the camera
self.coa.set(0,10,0)
self.coaDist = 10
coa.set(0,100,0)
coaDist = 100
else:
# If no intersection point:
# Put coa out in front of the camera
self.coa.set(0,10,0)
self.coaDist = 10
coa.set(0,100,0)
coaDist = 100
# Place the marker in render space
self.coaMarker.setPos(self.camera,self.coa)
# Record this point for later use
self.coaMarkerPos = self.coaMarker.getPos()
# Update coa and marker
self.updateCoa(coa, coaDist)
# Now spawn task to determine mouse fly mode
self.determineMouseFlyMode()
# END MOUSE IN CENTRAL REGION
@ -79,17 +79,13 @@ class DirectCameraControl(PandaObject):
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')
# 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
deltaX = self.chan.mouseX - self.initMouseX
deltaY = self.chan.mouseY - self.initMouseY
if ((abs(deltaX) < 0.1) & (abs(deltaY) < 0.1)):
return Task.cont
else:
@ -99,6 +95,17 @@ class DirectCameraControl(PandaObject):
self.spawnXZTranslate()
return Task.done
def updateCoa(self, cam2point, coaDist = None):
self.coa.set(cam2point[0], cam2point[1], cam2point[2])
if coaDist:
self.coaDist = coaDist
else:
self.coaDist = Vec3(self.coa - self.zeroPoint).length()
# Place the marker in render space
self.coaMarker.setPos(self.camera,self.coa)
# Record marker pos in render space
self.coaMarkerPos = self.coaMarker.getPos()
def homeCam(self, chan):
chan.camera.setMat(Mat4.identMat())
@ -121,7 +128,7 @@ class DirectCameraControl(PandaObject):
def centerCamIn(self, chan,t):
# Chan is a display region context
taskMgr.removeTasksNamed('manipulateCamera')
markerToCam = self.coaMarker.getPos( chan.camera )
markerToCam = self.coaMarker.getPos( chan.camera )
dist = Vec3(markerToCam - self.zeroPoint).length()
scaledCenterVec = self.centerVec * dist
delta = markerToCam - scaledCenterVec
@ -207,8 +214,8 @@ class DirectCameraControl(PandaObject):
# But aligned with render space
self.relNodePath.setHpr(self.zeroPoint)
parent = self.defChan.camera.getParent()
self.defChan.camera.wrtReparentTo(self.relNodePath)
parent = self.camera.getParent()
self.camera.wrtReparentTo(self.relNodePath)
manipTask = self.relNodePath.lerpHpr(VBase3(degrees,0,0),
CAM_MOVE_DURATION,
@ -219,11 +226,12 @@ class DirectCameraControl(PandaObject):
manipTask.uponDeath = self.reparentCam
def reparentCam(self, state):
self.defChan.camera.wrtReparentTo(state.parent)
self.camera.wrtReparentTo(state.parent)
def spawnHPanYZoom(self):
# Kill any existing tasks
taskMgr.removeTasksNamed('manipulateCamera')
# 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.targetVector = targetVector
@ -231,84 +239,93 @@ class DirectCameraControl(PandaObject):
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)
distToMove = targetVector * self.chan.mouseDeltaY
self.camera.setPosHpr(self.camera,
distToMove[0],
distToMove[1],
distToMove[2],
(0.5 * self.chan.mouseDeltaX *
self.chan.fovH),
0.0, 0.0)
return Task.cont
def spawnXZTranslateOrHPPan(self):
# Kill any existing tasks
taskMgr.removeTasksNamed('manipulateCamera')
t = Task.Task(self.XZTranslateOrHPPanTask)
t.scaleFactor = (self.coaDist / self.defChan.near)
t.scaleFactor = (self.coaDist / self.chan.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)
self.camera.setHpr(self.camera,
(0.5 * self.chan.mouseDeltaX *
self.chan.fovH),
(-0.5 * self.chan.mouseDeltaY *
self.chan.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))
self.camera.setPos(self.camera,
(-0.5 * self.chan.mouseDeltaX *
self.chan.nearWidth *
state.scaleFactor),
0.0,
(-0.5 * self.chan.mouseDeltaY *
self.chan.nearHeight *
state.scaleFactor))
return Task.cont
def spawnXZTranslate(self):
# Kill any existing tasks
taskMgr.removeTasksNamed('manipulateCamera')
t = Task.Task(self.XZTranslateTask)
t.scaleFactor = (self.coaDist / self.defChan.near)
t.scaleFactor = (self.coaDist / self.chan.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))
self.camera.setPos(self.camera,
(-0.5 * self.chan.mouseDeltaX *
self.chan.nearWidth *
state.scaleFactor),
0.0,
(-0.5 * self.chan.mouseDeltaY *
self.chan.nearHeight *
state.scaleFactor))
return Task.cont
def spawnMouseRotateTask(self):
self.relNodePath.setPos(render, self.coaMarkerPos)
self.relNodePath.setHpr(self.defChan.camera, self.zeroPoint)
# Kill any existing tasks
taskMgr.removeTasksNamed('manipulateCamera')
# Set at markers position in render coordinates
self.relNodePath.setPos(self.coaMarkerPos)
self.relNodePath.setHpr(self.camera, self.zeroPoint)
t = Task.Task(self.mouseRotateTask)
t.wrtMat = self.defChan.camera.getMat( self.relNodePath )
t.wrtMat = self.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.5 * self.chan.mouseDeltaX * 180.0),
(0.5 * self.chan.mouseDeltaY * 180.0),
0.0)
self.defChan.camera.setMat(self.relNodePath, wrtMat)
self.camera.setMat(self.relNodePath, wrtMat)
return Task.cont
def spawnHPPan(self):
# Kill any existing tasks
taskMgr.removeTasksNamed('manipulateCamera')
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)
self.camera.setHpr(self.camera,
(0.5 * self.chan.mouseDeltaX *
self.chan.fovH),
(-0.5 * self.chan.mouseDeltaY *
self.chan.fovV),
0.0)
return Task.cont
def enableMouseFly(self):
@ -320,30 +337,30 @@ class DirectCameraControl(PandaObject):
# disable C++ fly interface
base.disableMouse()
# Accept middle mouse events
self.accept('mouse2', self.mouseFlyStart, [self.defChan])
self.accept('mouse2-up', self.mouseFlyStop)
self.accept('handleMouse2', self.mouseFlyStart, [self.chan])
self.accept('handleMouse2Up', 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])
self.accept('u', self.uprightCam, [self.chan])
self.accept('c', self.centerCamIn, [self.chan, 0.5])
self.accept('h', self.homeCam, [self.chan])
for i in range(1,9):
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(`i`, self.SpawnMoveToView, [self.chan, i])
self.accept('9', self.swingCamAboutWidget, [self.chan, -90.0, t])
self.accept('0', self.swingCamAboutWidget, [self.chan, 90.0, t])
self.accept('`', 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])
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])
def disableMouseFly(self):
# Hide the marker
self.coaMarker.reparentTo(hidden)
# Accept middle mouse events
self.ignore('mouse2')
self.ignore('mouse2-up')
# Ignore middle mouse events
self.ignore('handleMouse2')
self.ignore('handleMouse2Up')
self.ignore('u')
self.ignore('c')
self.ignore('h')

View File

@ -1,4 +1,7 @@
from PandaObject import *
from DirectGeometry import *
from DirectSelection import *
class SelectionRay:
def __init__(self, camera, fGeom = 1):
@ -41,6 +44,289 @@ class SelectionRay:
# Convert point from object local space to camera space
return entry.getInvWrtSpace().xformPoint(hitPt)
class DirectBoundingBox:
def __init__(self, nodePath):
# Record the node path
self.nodePath = nodePath
# Compute bounds, min, max, etc.
self.computeBounds()
# Generate the bounding box
self.lines = self.createBBoxLines()
def computeBounds(self):
self.bounds = self.nodePath.getBounds()
self.center = self.bounds.getCenter()
self.radius = self.bounds.getRadius()
self.min = Point3(self.center - Point3(self.radius))
self.max = Point3(self.center + Point3(self.radius))
def createBBoxLines(self):
# Create a line segments object for the bbox
lines = LineNodePath(hidden)
lines.node().setName('bboxLines')
lines.setColor( VBase4( 1., 0., 0., 1. ) )
lines.setThickness( 0.5 )
minX = self.min[0]
minY = self.min[1]
minZ = self.min[2]
maxX = self.max[0]
maxY = self.max[1]
maxZ = self.max[2]
# Bottom face
lines.moveTo( minX, minY, minZ )
lines.drawTo( maxX, minY, minZ )
lines.drawTo( maxX, maxY, minZ )
lines.drawTo( minX, maxY, minZ )
lines.drawTo( minX, minY, minZ )
# Front Edge/Top face
lines.drawTo( minX, minY, maxZ )
lines.drawTo( maxX, minY, maxZ )
lines.drawTo( maxX, maxY, maxZ )
lines.drawTo( minX, maxY, maxZ )
lines.drawTo( minX, minY, maxZ )
# Three remaining edges
lines.moveTo( maxX, minY, minZ )
lines.drawTo( maxX, minY, maxZ )
lines.moveTo( maxX, maxY, minZ )
lines.drawTo( maxX, maxY, maxZ )
lines.moveTo( minX, maxY, minZ )
lines.drawTo( minX, maxY, maxZ )
# Create and return bbox lines
lines.create()
return lines
def updateBBoxLines(self):
ls = self.lines.lineSegs
minX = self.min[0]
minY = self.min[1]
minZ = self.min[2]
maxX = self.max[0]
maxY = self.max[1]
maxZ = self.max[2]
# Bottom face
ls.setVertex( 0, minX, minY, minZ )
ls.setVertex( 1, maxX, minY, minZ )
ls.setVertex( 2, maxX, maxY, minZ )
ls.setVertex( 3, minX, maxY, minZ )
ls.setVertex( 4, minX, minY, minZ )
# Front Edge/Top face
ls.setVertex( 5, minX, minY, maxZ )
ls.setVertex( 6, maxX, minY, maxZ )
ls.setVertex( 7, maxX, maxY, maxZ )
ls.setVertex( 8, minX, maxY, maxZ )
ls.setVertex( 9, minX, minY, maxZ )
# Three remaining edges
ls.setVertex( 10, maxX, minY, minZ )
ls.setVertex( 11, maxX, minY, maxZ )
ls.setVertex( 12, maxX, maxY, minZ )
ls.setVertex( 13, maxX, maxY, maxZ )
ls.setVertex( 14, minX, maxY, minZ )
ls.setVertex( 15, minX, maxY, maxZ )
def getBounds(self):
# Get a node path's bounds
nodeBounds = self.nodePath.node().getBound()
for child in self.nodePath.getChildrenAsList():
nodeBounds.extendBy(child.getBottomArc().getBound())
return nodeBounds.makeCopy()
def show(self):
self.lines.reparentTo(self.nodePath)
def hide(self):
self.lines.reparentTo(hidden)
def getCenter(self):
return self.center
def getRadius(self):
return self.radius
def getMin(self):
return self.min
def getMax(self):
return self.max
def vecAsString(self, vec):
return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2])
def __repr__(self):
return (`self.__class__` +
'\nNodePath:\t%s\n' % self.name +
'Min:\t\t%s\n' % self.vecAsString(self.min) +
'Max:\t\t%s\n' % self.vecAsString(self.max) +
'Center:\t\t%s\n' % self.vecAsString(self.center) +
'Radius:\t\t%.2f' % self.radius
)
class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods
def __init__(self, nodePath):
# Initialize the superclass
NodePath.__init__(self)
self.assign(nodePath)
# Get a reasonable name
self.name = self.getNodePathName()
# Create a bounding box
self.bbox = DirectBoundingBox(self)
# Use value of this pointer as unique ID
self.id = self.node().this
# Show bounding box
self.highlight()
def highlight(self):
self.bbox.show()
def dehighlight(self):
self.bbox.hide()
def getCenter(self):
return self.bbox.getCenter()
def getRadius(self):
return self.bbox.getRadius()
def getMin(self):
return self.bbox.getMin()
def getMax(self):
return self.bbox.getMax()
def __repr__(self):
return ('NodePath:\t%s\n' % self.name)
class SelectedNodePaths(PandaObject):
def __init__(self):
self.selectedDict = {}
self.deselectedDict = {}
self.last = None
def select(self, nodePath, fMultiSelect = 0):
# Do nothing if nothing selected
if not nodePath:
print 'Nothing selected!!'
return None
# Reset selected objects and highlight if multiSelect is false
if not fMultiSelect:
self.deselectAll()
# Get this pointer
id = nodePath.node().this
# First see if its already in the selected dictionary
dnp = self.selectedDict.get(id, None)
# If so, we're done
if not dnp:
# See if it is in the deselected dictionary
dnp = self.deselectedDict.get(id, None)
if dnp:
# It has been previously selected:
# Show its bounding box
dnp.highlight()
# Remove it from the deselected dictionary
del(self.deselectedDict[id])
else:
# Didn't find it, create a new selectedNodePath instance
dnp = DirectNodePath(nodePath)
# Add it to the selected dictionary
self.selectedDict[dnp.id] = dnp
# And update last
self.last = dnp
return dnp
def deselect(self, nodePath):
# Get this pointer
id = nodePath.node().this
# See if it is in the selected dictionary
dnp = self.selectedDict.get(id, None)
if dnp:
# It was selected:
# Hide its bounding box
dnp.dehighlight()
# Remove it from the selected dictionary
del(self.selectedDict[id])
# And keep track of it in the deselected dictionary
self.deselectedDict[id] = dnp
return dnp
def selectedAsList(self):
list = []
for key in self.selectedDict.keys():
list.append(self.selectedDict[key])
def deselectedAsList(self):
list = []
for key in self.deselectedDict.keys():
list.append(self.deselectedDict[key])
def forEachSelectedNodePathDo(self, func):
duplicateKeys = self.selectedDict.keys()[:]
for key in duplicateKeys:
func(self.selectedDict[key])
def forEachDeselectedNodePathDo(self, func):
duplicateKeys = self.deselectedDict.keys()[:]
for key in duplicateKeys:
func(self.deselectedDict[key])
def deselectAll(self):
self.forEachSelectedNodePathDo(self.deselect)
def highlightAll(self):
self.forEachSelectedNodePathDo(DirectNodePath.highlight)
def dehighlightAll(self):
self.forEachSelectedNodePathDo(DirectNodePath.dehighlight)
def removeSelected(self):
selected = self.dnp.last
if selected:
selected.remove()
def removeAll(self):
# Remove all selected nodePaths from the Scene Graph
self.forEachSelectedNodePathDo(NodePath.remove)
def toggleVizSelected(self):
selected = self.dnp.last
# Toggle visibility of selected node paths
if selected:
selected.toggleViz()
def toggleVizAll(self):
# Toggle viz for all selected node paths
self.forEachSelectedNodePathDo(NodePath.toggleViz)
def isolateSelected(self):
selected = self.dnp.last
if selected:
selected.isolate()
def getDirectNodePath(self, nodePath):
# Get this pointer
id = nodePath.node().this
# First check selected dict
dnp = self.selectedDict.get(id, None)
if dnp:
return dnp
# Otherwise return result of deselected search
return self.selectedDict.get(id, None)
def getNumSelected(self):
return len(self.selectedDict.keys())
"""
dd = loader.loadModel(r"I:\beta\toons\install\neighborhoods\donalds_dock")
dd.reparentTo(render)

View File

@ -1,11 +1,13 @@
from PandaObject import *
from DirectCameraControl import *
from DirectManipulation import *
from DirectSelection import *
from DirectGeometry import *
import OnscreenText
class DirectSession(PandaObject):
def __init__(self):
self.contextList = []
self.iRayList = []
@ -15,11 +17,10 @@ class DirectSession(PandaObject):
self.chanCenter = self.getChanData(0)
self.cameraControls = DirectCameraControl(self)
self.manipulationControls = DirectManipulationControl(self)
# Initialize the collection of selected nodePaths
self.selectedNodePaths = {}
self.selectedNodePath = None
self.lastSelected = None
self.selected = SelectedNodePaths()
self.readout = OnscreenText.OnscreenText( '', 0.1, -0.95 )
# self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5)
@ -28,24 +29,23 @@ class DirectSession(PandaObject):
self.createObjectHandles()
self.useObjectHandles()
self.createBBox()
self.bboxList = []
self.fControl = 0
self.fAlt = 0
self.fShift = 0
self.in2DWidget = 0
self.iRay = self.iRayList[0]
self.iRay.rayCollisionNodePath.node().setFromCollideMask(BitMask32().allOff())
self.iRay.rayCollisionNodePath.node().setIntoCollideMask(BitMask32().allOff())
self.iRay.rayCollisionNodePath.node().setFromCollideMask(
BitMask32().allOff())
self.iRay.rayCollisionNodePath.node().setIntoCollideMask(
BitMask32().allOff())
self.hitPt = Point3(0.0)
self.actionEvents = [('selectNodePath', self.selectNodePath),
('deselectNodePath', self.deselectNodePath),
self.actionEvents = [('select', self.select),
('deselect', self.deselect),
('deselectAll', self.deselectAll),
('highlightNodePath', self.highlightNodePath),
('removeNodePath', self.removeNodePath),
('highlightAll', self.selected.highlightAll),
('preRemoveNodePath', self.deselect),
('in2DWidget', self.in2DWidget)]
self.keyEvents = ['left', 'right', 'up', 'down',
'escape', 'space', 'delete',
@ -57,147 +57,59 @@ class DirectSession(PandaObject):
'mouse2', 'mouse2-up',
'mouse3', 'mouse3-up']
def selectNodePath(self, aNodePath, multiSelect = 0):
self.lastSelected = aNodePath
def select(self, nodePath):
dnp = self.selected.select(nodePath)
if dnp:
# Update the readout
self.readout.reparentTo(render2d)
self.readout.setText(dnp.name)
# Show the manipulation widget
self.objectHandles.reparentTo(render)
# Adjust its size
self.objectHandles.setScale(dnp.getRadius())
# 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')
# TBD Compute widget COA
# Update camera controls coa to this point
wrtMat = dnp.getMat(base.camera)
self.cameraControls.updateCoa(
wrtMat.xformPoint(dnp.getCenter()))
# Spawn task to have object handles follow the selected object
taskMgr.removeTasksNamed('followSelectedNodePath')
t = Task.Task(self.followSelectedNodePathTask)
t.nodePath = dnp
taskMgr.spawnTaskNamed(t, 'followSelectedNodePath')
# Send an message marking the event
messenger.send('selectedNodePath', [dnp])
def followSelectedNodePathTask(self, state):
aNodePath = state.aNodePath
pos = aNodePath.getPos(render)
nodePath = state.nodePath
pos = nodePath.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 deselect(self, nodePath):
dnp = self.snp.deselect(nodePath)
if dnp:
# Hide the manipulation widget
self.objectHandles.reparentTo(hidden)
self.readout.reparentTo(hidden)
self.readout.setText(' ')
taskMgr.removeTasksNamed('followSelectedNodePath')
# Send an message marking the event
messenger.send('deselectedNodePath', [dnp])
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 deselectAll(self):
self.selected.deselectAll()
# Hide the manipulation widget
self.objectHandles.reparentTo(hidden)
self.readout.reparentTo(hidden)
self.readout.setText(' ')
taskMgr.removeTasksNamed('followSelectedNodePath')
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 in2DWidget(self):
self.in2DWidget = 1
def enable(self):
# Start all display region context tasks
@ -205,6 +117,8 @@ class DirectSession(PandaObject):
context.spawnContextTask()
# Turn on mouse Flying
self.cameraControls.enableMouseFly()
# Turn on object manipulation
self.manipulationControls.enableManipulation()
# Accept appropriate hooks
self.enableKeyEvents()
self.enableMouseEvents()
@ -216,6 +130,8 @@ class DirectSession(PandaObject):
context.removeContextTask()
# Turn off camera fly
self.cameraControls.disableMouseFly()
# Turn off object manipulation
self.manipulationControls.disableManipulation()
self.disableKeyEvents()
self.disableMouseEvents()
self.disableActionEvents()
@ -285,6 +201,10 @@ class DirectSession(PandaObject):
messenger.send('handle2DMouse1Up')
if not self.in2DWidget:
messenger.send('handleMouse1Up')
elif input == 'mouse2':
messenger.send('handleMouse2')
elif input == 'mouse2-up':
messenger.send('handleMouse2Up')
elif input == 'mouse3':
messenger.send('handleMouse3')
elif input == 'mouse3-up':
@ -304,12 +224,12 @@ class DirectSession(PandaObject):
elif input == 'escape':
self.deselectAll()
elif input == 'l':
if not self.lastSelected:
self.selectNodePath(self.lastSelected)
if self.selected.last:
self.select(self.selected.last)
elif input == 'delete':
self.removeSelectedNodePaths()
self.selected.removeAll()
elif input == 'v':
self.toggleVizSelectedNodePaths()
self.selected.toggleVizAll()
elif input == 'b':
base.toggleBackface()
elif input == 't':
@ -317,39 +237,6 @@ class DirectSession(PandaObject):
elif input == 'w':
base.toggleWireframe()
def createBBox(self, parent = None):
# Create a line segments object for the bbox
if parent is None:
parent = hidden
bbox = self.bbox = LineNodePath(parent)
#bbox.setName('bbox')
bbox.setColor( VBase4( 1., 0., 0., 1. ) )
bbox.setThickness( 0.5 )
# Bottom face
bbox.drawTo( 0.0, 0.0, 0.0 )
bbox.drawTo( 1.0, 0.0, 0.0 )
bbox.drawTo( 1.0, 1.0, 0.0 )
bbox.drawTo( 0.0, 1.0, 0.0 )
bbox.drawTo( 0.0, 0.0, 0.0 )
# Front Edge/Top face
bbox.drawTo( 0.0, 0.0, 1.0 )
bbox.drawTo( 1.0, 0.0, 1.0 )
bbox.drawTo( 1.0, 1.0, 1.0 )
bbox.drawTo( 0.0, 1.0, 1.0 )
bbox.drawTo( 0.0, 0.0, 1.0 )
# Three remaining edges
bbox.moveTo( Point3( 1.0, 0.0, 0.0 ) )
bbox.drawTo( 1.0, 0.0, 1.0 )
bbox.moveTo( Point3( 1.0, 1.0, 0.0 ) )
bbox.drawTo( 1.0, 1.0, 1.0 )
bbox.moveTo( Point3( 0.0, 1.0, 0.0 ) )
bbox.drawTo( 0.0, 1.0, 1.0 )
bbox.create()
def createObjectHandles(self):
oh = self.objectHandles = hidden.attachNewNode(
NamedNode('objectHandles') )
@ -429,3 +316,4 @@ class DisplayRegionContext(PandaObject):
self.mouseDeltaY = self.mouseY - self.mouseLastY
# Continue the task
return Task.cont

View File

@ -1,8 +1,23 @@
"""
NodePath-extensions module: contains methods to extend functionality
of the NodePath class
"""
def getNodePathName(self):
from PandaModules import *
# Initialize to a default value
name = '<noname>'
# Get the bottom node
node = self.node()
# Is it a named node?, If so, see if it has a name
if issubclass(node.__class__, NamedNode):
namedNodeName = node.getName()
# Is it not zero length?
if len(namedNodeName) != 0:
name = namedNodeName
return name
# For iterating over children
def getChildrenAsList(self):
childrenList = []
@ -10,6 +25,39 @@
childrenList.append(self.getChild(childNum))
return childrenList
def toggleViz(self):
if self.isHidden():
self.show()
else:
self.hide()
def showSiblings(self):
for sib in self.getParent().getChildrenAsList():
if sib != self:
sib.show()
def hideSiblings(self):
for sib in self.getParent().getChildrenAsList():
if sib != aNodePath:
sib.hide()
def showAllDescendants(self):
self.show()
for child in self.getChildrenAsList():
self.showAllDescendants(child)
def isolate(self):
self.showAllDescendants()
self.hideSiblings()
def remove(self):
# Send message in case anyone needs to do something
# before node is deleted
messenger.send('preRemoveNodePath', [self])
# Remove nodePath
self.reparentTo(hidden)
self.removeNode()
# private methods
def __getBlend(self, blendType):