瀏覽代碼

moved lifter to shadow-placer traverser, fixes fall-through-ledge problem

Darren Ranalli 18 年之前
父節點
當前提交
e51f0b2baf
共有 3 個文件被更改,包括 21 次插入8 次删除
  1. 11 2
      direct/src/controls/GravityWalker.py
  2. 1 4
      direct/src/showbase/ShadowPlacer.py
  3. 9 2
      direct/src/showbase/ShowBase.py

+ 11 - 2
direct/src/controls/GravityWalker.py

@@ -354,6 +354,8 @@ class GravityWalker(DirectObject.DirectObject):
             # Each time we change the collision geometry, make one
             # Each time we change the collision geometry, make one
             # more pass to ensure we aren't standing in a wall.
             # more pass to ensure we aren't standing in a wall.
             self.oneTimeCollide()
             self.oneTimeCollide()
+            # make sure we have a shadow traverser
+            base.initShadowTrav()
             if active:
             if active:
                 if 1:
                 if 1:
                     # Please let skyler or drose know if this is causing a problem
                     # Please let skyler or drose know if this is causing a problem
@@ -364,14 +366,21 @@ class GravityWalker(DirectObject.DirectObject):
                 if self.wantFloorSphere:
                 if self.wantFloorSphere:
                     self.cTrav.addCollider(self.cFloorSphereNodePath, self.pusherFloor)
                     self.cTrav.addCollider(self.cFloorSphereNodePath, self.pusherFloor)
                 self.cTrav.addCollider(self.cEventSphereNodePath, self.event)
                 self.cTrav.addCollider(self.cEventSphereNodePath, self.event)
-                self.cTrav.addCollider(self.cRayNodePath, self.lifter)
+                # Add the lifter to the shadow traverser, which runs after
+                # our traverser. This prevents the "fall through wall and
+                # off ledge" bug. The problem was that we couldn't control
+                # which collided first, the wall pusher or the lifter, if
+                # they're in the same collision traverser. If the lifter
+                # collided first, we'd start falling before getting pushed
+                # back behind the wall.
+                base.shadowTrav.addCollider(self.cRayNodePath, self.lifter)
             else:
             else:
                 if hasattr(self, 'cTrav'):
                 if hasattr(self, 'cTrav'):
                     self.cTrav.removeCollider(self.cWallSphereNodePath)
                     self.cTrav.removeCollider(self.cWallSphereNodePath)
                     if self.wantFloorSphere:
                     if self.wantFloorSphere:
                         self.cTrav.removeCollider(self.cFloorSphereNodePath)
                         self.cTrav.removeCollider(self.cFloorSphereNodePath)
                     self.cTrav.removeCollider(self.cEventSphereNodePath)
                     self.cTrav.removeCollider(self.cEventSphereNodePath)
-                    self.cTrav.removeCollider(self.cRayNodePath)
+                base.shadowTrav.removeCollider(self.cRayNodePath)
 
 
     def getCollisionsActive(self):
     def getCollisionsActive(self):
         assert self.debugPrint("getCollisionsActive() returning=%s"%(
         assert self.debugPrint("getCollisionsActive() returning=%s"%(

+ 1 - 4
direct/src/showbase/ShadowPlacer.py

@@ -45,10 +45,7 @@ class ShadowPlacer(DirectObject.DirectObject):
 
 
         if not cTrav:
         if not cTrav:
             # set up the shadow collision traverser
             # set up the shadow collision traverser
-            if not base.shadowTrav:
-                # set up the shadow collision traverser
-                base.shadowTrav = CollisionTraverser("base.shadowTrav")
-                base.shadowTrav.setRespectPrevTransform(False)
+            base.initShadowTrav()
             cTrav = base.shadowTrav
             cTrav = base.shadowTrav
 
 
         self.cTrav = cTrav
         self.cTrav = cTrav

+ 9 - 2
direct/src/showbase/ShowBase.py

@@ -1432,6 +1432,12 @@ class ShowBase(DirectObject.DirectObject):
         IntervalManager.ivalMgr.step()
         IntervalManager.ivalMgr.step()
         return Task.cont
         return Task.cont
 
 
+    def initShadowTrav(self):
+        if not self.shadowTrav:
+            # set up the shadow collision traverser
+            self.shadowTrav = CollisionTraverser("base.shadowTrav")
+            self.shadowTrav.setRespectPrevTransform(False)
+
     def __shadowCollisionLoop(self, state):
     def __shadowCollisionLoop(self, state):
         # run the collision traversal if we have a
         # run the collision traversal if we have a
         # CollisionTraverser set.
         # CollisionTraverser set.
@@ -1509,9 +1515,10 @@ class ShowBase(DirectObject.DirectObject):
         # between collisionLoop and igLoop
         # between collisionLoop and igLoop
         self.taskMgr.add(self.__collisionLoop, 'collisionLoop', priority = 30)
         self.taskMgr.add(self.__collisionLoop, 'collisionLoop', priority = 30)
         # do the shadowCollisionLoop after the collisionLoop and
         # do the shadowCollisionLoop after the collisionLoop and
-        # befor the igLoop:
+        # before the igLoop and camera updates (this moves the avatar vertically,
+        # to his final position for the frame):
         self.taskMgr.add(
         self.taskMgr.add(
-            self.__shadowCollisionLoop, 'shadowCollisionLoop', priority = 45)
+            self.__shadowCollisionLoop, 'shadowCollisionLoop', priority = 44)
         # give the igLoop task a reasonably "late" priority,
         # give the igLoop task a reasonably "late" priority,
         # so that it will get run after most tasks
         # so that it will get run after most tasks
         self.taskMgr.add(self.__igLoop, 'igLoop', priority = 50)
         self.taskMgr.add(self.__igLoop, 'igLoop', priority = 50)