| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- """
- DevWalker.py is for avatars.
- A walker control such as this one provides:
- - creation of the collision nodes
- - handling the keyboard and mouse input for avatar movement
- - moving the avatar
- it does not:
- - play sounds
- - play animations
- although it does send messeges that allow a listener to play sounds or
- animations based on walker events.
- """
- from direct.showbase.InputStateGlobal import inputState
- from direct.directnotify import DirectNotifyGlobal
- from direct.showbase import DirectObject
- from direct.task.Task import Task
- from pandac.PandaModules import *
- class DevWalker(DirectObject.DirectObject):
- notify = DirectNotifyGlobal.directNotify.newCategory("DevWalker")
- wantDebugIndicator = base.config.GetBool('want-avatar-physics-indicator', 0)
- runMultiplier = base.config.GetFloat('dev-run-multiplier', 4.0)
- # Ghost mode overrides this:
- slideName = "slide-is-disabled"
- # special methods
- def __init__(self):
- DirectObject.DirectObject.__init__(self)
- self.speed=0.0
- self.rotationSpeed=0.0
- self.slideSpeed=0.0
- self.vel=Vec3(0.0, 0.0, 0.0)
- self.task = None
- def setWalkSpeed(self, forward, jump, reverse, rotate):
- assert self.debugPrint("setWalkSpeed()")
- self.avatarControlForwardSpeed=forward
- #self.avatarControlJumpForce=jump
- self.avatarControlReverseSpeed=reverse
- self.avatarControlRotateSpeed=rotate
- def getSpeeds(self):
- #assert self.debugPrint("getSpeeds()")
- return (self.speed, self.rotationSpeed, self.slideSpeed)
- def setAvatar(self, avatar):
- self.avatar = avatar
- if avatar is not None:
- pass # setup the avatar
- def setWallBitMask(self, bitMask):
- pass
- def setFloorBitMask(self, bitMask):
- pass
- def initializeCollisions(self, collisionTraverser, avatarNodePath,
- wallCollideMask, floorCollideMask,
- avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0):
- assert not avatarNodePath.isEmpty()
- self.cTrav = collisionTraverser
- self.avatarNodePath = avatarNodePath
- def setAirborneHeightFunc(self, getAirborneHeight):
- pass
- def deleteCollisions(self):
- pass
- def setTag(self, key, value):
- pass
- def setCollisionsActive(self, active = 1):
- pass
- def placeOnFloor(self):
- pass
- def oneTimeCollide(self):
- pass
- def addBlastForce(self, vector):
- pass
- def displayDebugInfo(self):
- """
- For debug use.
- """
- onScreenDebug.add("w controls", "DevWalker")
- def handleAvatarControls(self, task):
- """
- Check on the arrow keys and update the avatar.
- """
- # get the button states:
- forward = inputState.isSet("forward")
- reverse = inputState.isSet("reverse")
- turnLeft = inputState.isSet("turnLeft")
- turnRight = inputState.isSet("turnRight")
- slideLeft = inputState.isSet("slideLeft")
- slideRight = inputState.isSet("slideRight")
- levitateUp = inputState.isSet("levitateUp")
- levitateDown = inputState.isSet("levitateDown")
- run = inputState.isSet("run") and self.runMultiplier or 1.0
- # Check for Auto-Run
- if base.localAvatar.getAutoRun():
- forward = 1
- reverse = 0
-
- # Determine what the speeds are based on the buttons:
- self.speed=(
- (forward and self.avatarControlForwardSpeed or
- reverse and -self.avatarControlReverseSpeed))
- self.liftSpeed=(
- (levitateUp and self.avatarControlForwardSpeed or
- levitateDown and -self.avatarControlReverseSpeed))
- self.slideSpeed=(
- (slideLeft and -self.avatarControlForwardSpeed) or
- (slideRight and self.avatarControlForwardSpeed))
- self.rotationSpeed=(
- (turnLeft and self.avatarControlRotateSpeed) or
- (turnRight and -self.avatarControlRotateSpeed))
- if self.wantDebugIndicator:
- self.displayDebugInfo()
- # Check to see if we're moving at all:
- if self.speed or self.liftSpeed or self.slideSpeed or self.rotationSpeed:
- # How far did we move based on the amount of time elapsed?
- dt=ClockObject.getGlobalClock().getDt()
- distance = dt * self.speed * run
- lift = dt * self.liftSpeed * run
- slideDistance = dt * self.slideSpeed * run
- rotation = dt * self.rotationSpeed
- # Take a step in the direction of our previous heading.
- self.vel=Vec3(Vec3.forward() * distance +
- Vec3.up() * lift +
- Vec3.right() * slideDistance)
- if self.vel != Vec3.zero():
- # rotMat is the rotation matrix corresponding to
- # our previous heading.
- rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
- step=rotMat.xform(self.vel)
- self.avatarNodePath.setFluidPos(Point3(self.avatarNodePath.getPos()+step))
- self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
- messenger.send("avatarMoving")
- else:
- self.vel.set(0.0, 0.0, 0.0)
- return Task.cont
- def enableAvatarControls(self):
- """
- Activate the arrow keys, etc.
- """
- assert self.debugPrint("enableAvatarControls")
- if self.task:
- # remove any old
- self.task.remove(self.task)
- # spawn the new task
- self.task = taskMgr.add(
- self.handleAvatarControls, "AvatarControls-dev-%s"%(id(self),))
- def disableAvatarControls(self):
- """
- Ignore the arrow keys, etc.
- """
- assert self.debugPrint("disableAvatarControls")
- if self.task:
- self.task.remove()
- self.task = None
- if __debug__:
- def debugPrint(self, message):
- """for debugging"""
- return self.notify.debug(
- str(id(self))+' '+message)
|