From e51f0b2bafd77dd92c49bddac76850c9a289a30b Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Wed, 1 Aug 2007 01:31:56 +0000 Subject: [PATCH] moved lifter to shadow-placer traverser, fixes fall-through-ledge problem --- direct/src/controls/GravityWalker.py | 13 +++++++++++-- direct/src/showbase/ShadowPlacer.py | 5 +---- direct/src/showbase/ShowBase.py | 11 +++++++++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/direct/src/controls/GravityWalker.py b/direct/src/controls/GravityWalker.py index 9534afafc4..3e0cf3a027 100755 --- a/direct/src/controls/GravityWalker.py +++ b/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"%( diff --git a/direct/src/showbase/ShadowPlacer.py b/direct/src/showbase/ShadowPlacer.py index d6c2940764..407caee940 100755 --- a/direct/src/showbase/ShadowPlacer.py +++ b/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 diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index d579eca400..f83ee8dec5 100644 --- a/direct/src/showbase/ShowBase.py +++ b/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)