mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
*** empty log message ***
This commit is contained in:
parent
28c07298d5
commit
79bc776db2
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user