Explorar o código

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

Darren Ranalli %!s(int64=18) %!d(string=hai) anos
pai
achega
e51f0b2baf

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

@@ -354,6 +354,8 @@ class GravityWalker(DirectObject.DirectObject):
             # Each time we change the collision geometry, make one
             # more pass to ensure we aren't standing in a wall.
             self.oneTimeCollide()
+            # make sure we have a shadow traverser
+            base.initShadowTrav()
             if active:
                 if 1:
                     # Please let skyler or drose know if this is causing a problem
@@ -364,14 +366,21 @@ class GravityWalker(DirectObject.DirectObject):
                 if self.wantFloorSphere:
                     self.cTrav.addCollider(self.cFloorSphereNodePath, self.pusherFloor)
                 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:
                 if hasattr(self, 'cTrav'):
                     self.cTrav.removeCollider(self.cWallSphereNodePath)
                     if self.wantFloorSphere:
                         self.cTrav.removeCollider(self.cFloorSphereNodePath)
                     self.cTrav.removeCollider(self.cEventSphereNodePath)
-                    self.cTrav.removeCollider(self.cRayNodePath)
+                base.shadowTrav.removeCollider(self.cRayNodePath)
 
     def getCollisionsActive(self):
         assert self.debugPrint("getCollisionsActive() returning=%s"%(

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

@@ -45,10 +45,7 @@ class ShadowPlacer(DirectObject.DirectObject):
 
         if not cTrav:
             # 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
 
         self.cTrav = cTrav

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

@@ -1432,6 +1432,12 @@ class ShowBase(DirectObject.DirectObject):
         IntervalManager.ivalMgr.step()
         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):
         # run the collision traversal if we have a
         # CollisionTraverser set.
@@ -1509,9 +1515,10 @@ class ShowBase(DirectObject.DirectObject):
         # between collisionLoop and igLoop
         self.taskMgr.add(self.__collisionLoop, 'collisionLoop', priority = 30)
         # 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.__shadowCollisionLoop, 'shadowCollisionLoop', priority = 45)
+            self.__shadowCollisionLoop, 'shadowCollisionLoop', priority = 44)
         # give the igLoop task a reasonably "late" priority,
         # so that it will get run after most tasks
         self.taskMgr.add(self.__igLoop, 'igLoop', priority = 50)