Source code for direct.showbase.ShadowPlacer

""" places a shadow.

It traces a line from a light source to the opposing surface.
Or it may do that later, right now it puts a node on the surface under
the its parent node.

__all__ = ['ShadowPlacer']

from direct.controls.ControlManager import CollisionHandlerRayStart
from direct.directnotify import DirectNotifyGlobal
from panda3d.core import *
from . import DirectObject

[docs]class ShadowPlacer(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory("ShadowPlacer") if __debug__: count = 0 activeCount = 0 # special methods
[docs] def __init__(self, cTrav, shadowNodePath, wallCollideMask, floorCollideMask): self.isActive = 0 # Is the placer "on". This is also printed in the debugCall. assert self.notify.debugCall() DirectObject.DirectObject.__init__(self) self.setup(cTrav, shadowNodePath, wallCollideMask, floorCollideMask) if __debug__: self.count += 1 self.debugDisplay()
[docs] def setup(self, cTrav, shadowNodePath, wallCollideMask, floorCollideMask): """ Set up the collisions """ assert self.notify.debugCall() assert not shadowNodePath.isEmpty() assert not hasattr(self, "cTrav") # Protect from setup() being called again. if not cTrav: # set up the shadow collision traverser base.initShadowTrav() cTrav = base.shadowTrav self.cTrav = cTrav self.shadowNodePath = shadowNodePath floorOffset = 0.025 # Set up the collison ray # This is a ray cast down to detect floor polygons self.cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0) cRayNode = CollisionNode('shadowPlacer') cRayNode.addSolid(self.cRay) self.cRayNodePath = NodePath(cRayNode) self.cRayBitMask = floorCollideMask cRayNode.setFromCollideMask(self.cRayBitMask) cRayNode.setIntoCollideMask(BitMask32.allOff()) # set up floor collision mechanism self.lifter = CollisionHandlerFloor() #self.lifter.setInPattern("on-floor") #self.lifter.setOutPattern("off-floor") self.lifter.setOffset(floorOffset) self.lifter.setReach(4.0) # activate the collider with the traverser and pusher #self.on() self.lifter.addCollider(self.cRayNodePath, shadowNodePath)
[docs] def delete(self): assert self.notify.debugCall() if __debug__: assert not self.isActive self.count -= 1 self.debugDisplay() del self.cTrav del self.shadowNodePath del self.cRay #del self.cRayNode self.cRayNodePath.removeNode() del self.cRayNodePath del self.lifter
[docs] def on(self): """ Turn on the shadow placement. The shadow z position will start being updated until a call to off() is made. """ assert self.notify.debugCall("activeCount=%s"%(self.activeCount,)) if self.isActive: assert self.cTrav.hasCollider(self.cRayNodePath) return assert not self.cTrav.hasCollider(self.cRayNodePath) self.cRayNodePath.reparentTo(self.shadowNodePath.getParent()) self.cTrav.addCollider(self.cRayNodePath, self.lifter) self.isActive = 1 if __debug__: self.activeCount += 1 self.debugDisplay()
[docs] def off(self): """ Turn off the shadow placement. The shadow will still be there, but the z position will not be updated until a call to on() is made. """ assert self.notify.debugCall("activeCount=%s"%(self.activeCount,)) if not self.isActive: assert not self.cTrav.hasCollider(self.cRayNodePath) return assert self.cTrav.hasCollider(self.cRayNodePath) didIt = self.cTrav.removeCollider(self.cRayNodePath) assert didIt # Now that we have disabled collisions, make one more pass # right now to ensure we aren't standing in a wall. self.oneTimeCollide() self.cRayNodePath.detachNode() self.isActive = 0 if __debug__: self.activeCount -= 1 self.debugDisplay()
[docs] def oneTimeCollide(self): """ Makes one quick collision pass for the avatar, for instance as a one-time straighten-things-up operation after collisions have been disabled. """ assert self.notify.debugCall() tempCTrav = CollisionTraverser("oneTimeCollide") tempCTrav.addCollider(self.cRayNodePath, self.lifter) tempCTrav.traverse(render)
[docs] def resetToOrigin(self): if self.shadowNodePath: self.shadowNodePath.setPos(0,0,0)
if __debug__:
[docs] def debugDisplay(self): """for debugging""" if self.notify.getDebug(): message = "%d active (%d total), %d colliders"%( self.activeCount, self.count, self.cTrav.getNumColliders()) self.notify.debug(message) onScreenDebug.add("ShadowPlacers", message) return 1 # to allow assert self.debugDisplay()