Browse Source

*** empty log message ***

Mark Mine 25 years ago
parent
commit
8ff540282f

+ 83 - 51
direct/src/directutil/DirectCameraControl.py

@@ -7,9 +7,13 @@ class DirectCameraControl(PandaObject):
         # Create the grid
         self.direct = direct
         self.defChan = direct.chanCenter
+        self.camera = self.defChan.camera
 	self.orthoViewRoll = 0.0
 	self.lastView = 0
         self.coa = Point3(0)
+        self.coaMarker = loader.loadModel('misc/sphere')
+        self.coaMarker.setColor(1,0,0)
+        self.coaMarkerPos = Point3(0)
 	self.relNodePath = render.attachNewNode(NamedNode('targetNode'))
         self.zeroBaseVec = VBase3(0)
         self.zeroVector = Vec3(0)
@@ -22,25 +26,50 @@ class DirectCameraControl(PandaObject):
 	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
+            # MOUSE IS IN CENTRAL REGION
+            if (self.direct.fShift):
+                # If shift key is pressed, just perform horiz and vert pan:
+                self.spawnHPPan()
+            else:
+                # 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)
+                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()
+                    # 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
+                                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)):
+                        # 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
-            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()
+
+                # Place the marker in render space
+                self.coaMarker.setPos(self.camera,self.coa)
+                # Record this point for later use
+                self.coaMarkerPos = self.coaMarker.getPos()
+                # Now spawn task to determine mouse fly mode
+                self.determineMouseFlyMode()
+            # END MOUSE IN CENTRAL REGION
         else:
             # Mouse is in outer frame, spawn mouseRotateTask
             self.spawnMouseRotateTask()
@@ -92,14 +121,14 @@ class DirectCameraControl(PandaObject):
     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()
+	markerToCam = self.coaMarker.getPos( chan.camera )
+	dist = Vec3(markerToCam - self.zeroPoint).length()
 	scaledCenterVec = self.centerVec * dist
-	delta = widgetToCam - scaledCenterVec
+	delta = markerToCam - scaledCenterVec
 	self.relNodePath.setPosHpr(chan.camera, Point3(0), Point3(0))
-	chan.camera.lerpPos(self.relNodePath,
-                            Point3(delta),
+	chan.camera.lerpPos(Point3(delta),
                             CAM_MOVE_DURATION,
+                            other = self.relNodePath,
                             blendType = 'easeInOut',
                             task = 'manipulateCamera')
 
@@ -107,7 +136,7 @@ class DirectCameraControl(PandaObject):
 	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
+        zoomPtToCam = self.coaMarker.getPos(chan.camera) * zoomFactor
 	# Put a target nodePath there
 	self.relNodePath.setPos(chan.camera, zoomPtToCam)
 	# Move to that point
@@ -122,6 +151,13 @@ class DirectCameraControl(PandaObject):
 	taskMgr.removeTasksNamed('manipulateCamera')
         # Calc hprOffset
 	hprOffset = VBase3()
+
+        if view == 8:
+            # Try the next roll angle
+            self.orthoViewRoll = (self.orthoViewRoll + 90.0) % 360.0
+            # but use the last view
+            view = self.lastView
+        
         if view == 1:
             hprOffset.set(180., 0., 0.)
         elif view == 2:
@@ -137,8 +173,7 @@ class DirectCameraControl(PandaObject):
         elif view == 7:
             hprOffset.set(135., -35.264, 0.)
         # Position target
-	self.relNodePath.setPosHpr(self.direct.widget,
-                                   self.zeroBaseVec,
+	self.relNodePath.setPosHpr(self.coaMarker, self.zeroBaseVec,
                                    hprOffset)
 	# Scale center vec by current distance to target
 	offsetDistance = Vec3(chan.camera.getPos(self.relNodePath) - 
@@ -150,9 +185,11 @@ class DirectCameraControl(PandaObject):
                                    scaledCenterVec,
                                    self.zeroBaseVec)
 
-	# Start off with best view if change is to new view
-        if (view != self.lastView):
+        # Store this view for next time
+        # Reset orthoViewRoll if you change views
+        if view != self.lastView:
             self.orthoViewRoll = 0.0
+            
         self.lastView = view
 	chan.camera.lerpPosHpr(self.zeroPoint,
                                VBase3(0,0,self.orthoViewRoll),
@@ -161,40 +198,33 @@ class DirectCameraControl(PandaObject):
                                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)
+        self.relNodePath.setPos(self.coaMarker, self.zeroPoint)
 	# But aligned with render space
 	self.relNodePath.setHpr(self.zeroPoint)
 
-	parent = self.defChan.camera.getParent
+	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')
+	manipTask = self.relNodePath.lerpHpr(VBase3(degrees,0,0),
+                                             CAM_MOVE_DURATION,
+                                             blendType = 'easeInOut',
+                                             task = 'manipulateCamera')
+        # Upon death, reparent Cam to parent
+        manipTask.parent = parent
+        manipTask.uponDeath = self.reparentCam
 
     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
+	# targetVector = self.coa * -1
+        targetVector = self.coa * -1
         t = Task.Task(self.HPanYZoomTask)
         t.targetVector = targetVector
         taskMgr.spawnTaskNamed(t, 'manipulateCamera')
@@ -253,7 +283,7 @@ class DirectCameraControl(PandaObject):
         return Task.cont
 
     def spawnMouseRotateTask(self):
-	self.relNodePath.setPos(self.coa)
+	self.relNodePath.setPos(render, self.coaMarkerPos)
 	self.relNodePath.setHpr(self.defChan.camera, self.zeroPoint)
         t = Task.Task(self.mouseRotateTask)
 	t.wrtMat = self.defChan.camera.getMat( self.relNodePath )
@@ -284,6 +314,7 @@ class DirectCameraControl(PandaObject):
     def enableMouseFly(self):
 	self.enableMouseInteraction()
 	self.enableHotKeys()
+        self.coaMarker.reparentTo(render)
 
     def enableMouseInteraction(self):
 	# disable C++ fly interface
@@ -297,17 +328,19 @@ class DirectCameraControl(PandaObject):
 	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):
+        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('8', self.removeManipulateCameraTask)
+	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])
 
     def disableMouseFly(self):
+        # Hide the marker
+        self.coaMarker.reparentTo(hidden)
 	# Accept middle mouse events
 	self.ignore('mouse2')
 	self.ignore('mouse2-up')
@@ -319,10 +352,9 @@ class DirectCameraControl(PandaObject):
 	self.ignore('=')
 	self.ignore('+')
 	self.ignore('-')
-	self.ignore('=')
+	self.ignore('_')
+        self.ignore('`')
 
     def removeManipulateCameraTask(self):
         taskMgr.removeTasksNamed('manipulateCamera')
 
-
-

+ 5 - 3
direct/src/directutil/DirectSelection.py

@@ -31,13 +31,15 @@ class SelectionRay:
         self.numEntries = self.cq.getNumEntries()
         return self.numEntries
 
-    def localHitPt(self, index):
+    def objectToHitPt(self, index):
         return self.cq.getEntry(index).getIntoIntersectionPoint()
 
-    def hitPt(self, index):
+    def camToHitPt(self, index):
+        # Get the specified entry
         entry = self.cq.getEntry(index)
         hitPt = entry.getIntoIntersectionPoint()
-        return entry.getWrtSpace().xformPoint(hitPt)
+        # Convert point from object local space to camera space
+        return entry.getInvWrtSpace().xformPoint(hitPt)
 
 """
 dd = loader.loadModel(r"I:\beta\toons\install\neighborhoods\donalds_dock")

+ 8 - 337
direct/src/directutil/DirectSession.py

@@ -37,6 +37,8 @@ class DirectSession(PandaObject):
         self.in2DWidget = 0
 
         self.iRay = self.iRayList[0]
+        self.iRay.rayCollisionNodePath.node().setFromCollideMask(BitMask32().allOff())
+        self.iRay.rayCollisionNodePath.node().setIntoCollideMask(BitMask32().allOff())
         self.hitPt = Point3(0.0)
 
         self.actionEvents = [('selectNodePath', self.selectNodePath),
@@ -288,17 +290,17 @@ class DirectSession(PandaObject):
         elif input == 'mouse3-up':
             messenger.send('handleMouse3Up')
         elif input == 'shift':
-            self.fShift = true
+            self.fShift = 1
         elif input == 'shift-up':
-            self.fShift = false
+            self.fShift = 0
         elif input == 'control':
-            self.fControl = true
+            self.fControl = 1
         elif input == 'control-up':
-            self.fControl = false
+            self.fControl = 0
         elif input == 'alt':
-            self.fAlt = true
+            self.fAlt = 1
         elif input == 'alt-up':
-            self.fAlt = false
+            self.fAlt = 0
         elif input == 'escape':
             self.deselectAll()
         elif input == 'l':
@@ -427,334 +429,3 @@ class DisplayRegionContext(PandaObject):
         self.mouseDeltaY = self.mouseY - self.mouseLastY
         # Continue the task
         return Task.cont
-
-
-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
-        targetVector = self.coa
-        print self.coa[0], self.coa[1], self.coa[2]
-        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')
-
-
-

+ 14 - 0
direct/src/showbase/Task.py

@@ -29,6 +29,7 @@ def getTimeFrame():
 class Task:
     def __init__(self, callback):
         self.__call__ = callback
+        self.uponDeath = None
         
     def setStartTimeFrame(self, startTime, startFrame):
         self.starttime = startTime
@@ -212,6 +213,8 @@ class TaskManager:
         except:
             pass
         # TODO: upon death
+        if task.uponDeath:
+            task.uponDeath(task)
 
     def removeTasksNamed(self, taskName):
         removedTasks = []
@@ -318,6 +321,7 @@ t = taskMgr.spawnTaskNamed(seq, 'doLater-fooLater')
 run()
 
 # tasks with state
+# Combined with uponDeath
 
 someValue = 1
 
@@ -329,9 +333,19 @@ def func(state):
         state.someValue = state.someValue + 1
         return Task.cont
 
+def deathFunc(state):
+    print 'Value at death: ', state.someValue
+
 task = Task.Task(func)
+
 # set task state here
 task.someValue = someValue
+
+# Use instance variable uponDeath to specify function
+# to perform on task removal
+# Default value of uponDeath is None
+task.uponDeath = deathFunc
+
 t = taskMgr.spawnTaskNamed(task, 'funcTask')
 run()
 """