From 679a3782e61fd23976cee96f1ea7ee5b6ccc99ef Mon Sep 17 00:00:00 2001 From: Zachary Pavlov Date: Fri, 22 Jan 2010 22:41:39 +0000 Subject: [PATCH] phase 1 of ship cleanup --- direct/src/controls/ShipPilot.py | 680 ------------------- direct/src/controls/ShipPilot2.py | 1009 ----------------------------- 2 files changed, 1689 deletions(-) delete mode 100755 direct/src/controls/ShipPilot.py delete mode 100755 direct/src/controls/ShipPilot2.py diff --git a/direct/src/controls/ShipPilot.py b/direct/src/controls/ShipPilot.py deleted file mode 100755 index 63fa0d3434..0000000000 --- a/direct/src/controls/ShipPilot.py +++ /dev/null @@ -1,680 +0,0 @@ -""" -ShipPilot.py is for avatars pilotting ships (or more accurately, a ship -as the avatar). - -A 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 control events. -""" - -from pandac.PandaModules import * -from direct.directnotify.DirectNotifyGlobal import directNotify -from direct.showbase.InputStateGlobal import inputState -from direct.task.Task import Task -from PhysicsWalker import PhysicsWalker -import math - -class ShipPilot(PhysicsWalker): - notify = directNotify.newCategory("ShipPilot") - wantDebugIndicator = base.config.GetBool( - 'want-avatar-physics-indicator', 0) - - MAX_STRAIGHT_SAIL_BONUS = 2.1 # 1.25 Old - STRAIGHT_SAIL_BONUS_TIME = 18.0 - REVERSE_STRAIGHT_SAIL_BONUS_TIME = -8.0 - TURNING_BONUS_REDUCTION = 3.0 - - # special methods - def __init__(self, - gravity = -32.1740, - standableGround=0.707, - hardLandingForce=16.0): - assert self.debugPrint( - "PhysicsWalker(gravity=%s, standableGround=%s)"%( - gravity, standableGround)) - PhysicsWalker.__init__( - self, gravity, standableGround, hardLandingForce) - - self.__speed=0.0 - self.__rotationSpeed=0.0 - self.__slideSpeed=0.0 - self.__vel=Vec3(0.0) - self.currentTurning = 0.0 - - self.ship = None - self.pusher = None - - # Keeps track of the ship sailing in a straight heading - # for long periods of time. We slowly up the ship's max - # acceleration as this increases. - self.straightHeading = 0 - - self.cNodePath = None - - def setWalkSpeed(self, forward, jump, reverse, rotate): - assert self.debugPrint("setWalkSpeed()") - PhysicsWalker.setWalkSpeed(self, forward, 0, reverse, rotate) - - def setWallBitMask(self, bitMask): - self.wallBitmask = bitMask - - def adjustWallBitMask(self, oldMask, newMask): - # this will clear any bits set in oldMask and set any bits - # set in newMask - self.wallBitmask = self.wallBitmask &~ oldMask - self.wallBitmask |= newMask - - if self.cNodePath and not self.cNodePath.isEmpty(): - self.cNodePath.node().setFromCollideMask(self.wallBitmask) - - def setFloorBitMask(self, bitMask): - self.floorBitmask = bitMask - - def setShip(self, ship): - self.setAvatar(ship) - - def setAvatar(self, ship): - if ship is None: - # only clear out the global controlForce's physics object if it hasn't - # been changed since we set it up for our boat - # this could still break if we have more than one ShipPilot referencing - # a single boat - if (self.ship is not None and - base.controlForce.getPhysicsObject() == self.ship.node().getPhysicsObject()): - base.controlForce.clearPhysicsObject() - base.controlForce.setVector(Vec3(0)) - self.takedownPhysics() - self.setCollisionsActive(0) - self.ship = ship - else: - base.controlForce.setPhysicsObject(ship.node().getPhysicsObject()) - self.ship = ship - self.setupPhysics(ship) - self.setCollisionsActive(1) - - def initializeCollisions(self, collisionTraverser, cRootNodePath, - bow, stern, starboard, port): - """ - Set up the avatar collisions. All we do here is assign - the traverser. All the ship specific stuff happens in - setAvatar() and its helper functions. - """ - assert self.debugPrint("initializeCollisions()") - self.cTrav = collisionTraverser - self.cRootNodePath = cRootNodePath - self.bowPos = bow.getPos(cRootNodePath) - self.sternPos = stern.getPos(cRootNodePath) - self.starboardPos = starboard.getPos(cRootNodePath) - self.portPos = port.getPos(cRootNodePath) - - def setupCollisions(self): - if self.pusher: - return - """ - Set up the collision sphere - """ - # This is a sphere on the ground to detect barrier collisions - - # set up collision mechanism - self.pusher = CollisionHandlerPusher() - self.pusher.setInPattern("enter%in") - self.pusher.setOutPattern("exit%in") - - sRadius = abs((self.portPos - self.starboardPos)[0] / 2.0) - - cNode = CollisionNode('SP.cNode') - - # Front sphere: - frontPos = self.bowPos[1]+sRadius - rearPos = self.sternPos[1]-sRadius - cBowSphere = CollisionSphere( - 0.0, frontPos, 0.0, sRadius) - - # Back sphere: - cSternSphere = CollisionSphere( - 0.0, rearPos, 0.0, sRadius) - - # Mid sphere: create to fill in the gap between front and back spheres, - # minimum radius it can be is the radius of the front and rear sphere, but - # allow it to get bigger to completely fill the middle - midSphereRadius = max(sRadius,((rearPos - frontPos) - (sRadius * 2))/2) - cMidSphere = CollisionSphere( - 0.0, frontPos + ((rearPos - frontPos) / 2), 0.0, midSphereRadius) - - # Scaled sphere - # jbutler: abandoned using the stretched sphere since there are problems - # with pushing against a scaled sphere -# cObj = CollisionSphere( -# 0.0, (self.sternPos[1]+self.bowPos[1])/2.0, 0.0, sRadius) - - ## Combine them all - cNode.addSolid(cBowSphere) - cNode.addSolid(cMidSphere) - cNode.addSolid(cSternSphere) - #cNode.addSolid(cObj) - shipIColRoot = self.ship.getInteractCollisionRoot() - self.cNodePath = shipIColRoot.attachNewNode(cNode) - shipLen = abs(self.sternPos[1]-self.bowPos[1]) - self.cNodePath.setScale(1,1,1) - #self.cNodePath.setScale(1,(shipLen/2.0)/sRadius,1) - self.pusher.addCollider( - self.cNodePath, self.shipNodePath) - self.pusher.setHorizontal(True) - # hide other things on my ship that these spheres might collide - # with and which I dont need anyways... - shipCollWall = self.shipNodePath.find("**/collision_hull") - if not shipCollWall.isEmpty(): - shipCollWall.stash() - - def setCollisionsActive(self, active = 1): - if active: - self.setupCollisions() - - assert self.debugPrint("collisionsActive(active=%s)"%(active,)) - if self.collisionsActive != active: - self.collisionsActive = active - shipCollWall = self.shipNodePath.getWallCollisions() - if active: - self.cNodePath.node().setFromCollideMask(self.wallBitmask) - self.cNodePath.node().setIntoCollideMask(BitMask32.allOff()) - self.cTrav.addCollider(self.cNodePath, self.pusher) - shipCollWall.stash() - else: - self.cTrav.removeCollider(self.cNodePath) - shipCollWall.unstash() - # Now that we have disabled collisions, make one more pass - # right now to ensure we aren't standing in a wall. - self.oneTimeCollide() - - def deleteCollisions(self): - assert self.debugPrint("deleteCollisions()") - del self.cTrav - - """ - if hasattr(self, "cBowSphereNodePath"): - self.cBowSphereNodePath.removeNode() - del self.cBowSphereNodePath - - if hasattr(self, "cSternSphereNodePath"): - self.cSternSphereNodePath.removeNode() - del self.cSternSphereNodePath - """ - if hasattr(self, "cNodePath"): - self.cNodePath.removeNode() - self.cNodePath = None - - del self.pusher - - def setupPhysics(self, shipNodePath): - assert self.debugPrint("setupPhysics()") - if shipNodePath is None: - return - assert not shipNodePath.isEmpty() - - self.takedownPhysics() - - # these are used in collision setup and handleControls - self.shipNodePath = shipNodePath - self.actorNode = shipNodePath.node() - - def takedownPhysics(self): - assert self.debugPrint("takedownPhysics()") - - def setTag(self, key, value): - self.cNodePath.setTag(key, value) - - def setAvatarPhysicsIndicator(self, indicator): - """ - indicator is a NodePath - """ - assert self.debugPrint("setAvatarPhysicsIndicator()") - self.cNodePath.show() - if indicator: - # Indicator Node: - change=render.attachNewNode("change") - #change.setPos(Vec3(1.0, 1.0, 1.0)) - #change.setHpr(0.0, 0.0, 0.0) - change.setScale(0.1) - #change.setColor(Vec4(1.0, 1.0, 1.0, 1.0)) - indicator.reparentTo(change) - - indicatorNode=render.attachNewNode("physVelocityIndicator") - #indicatorNode.setScale(0.1) - #indicatorNode.setP(90.0) - indicatorNode.setPos(self.shipNodePath, 0.0, 0.0, 6.0) - indicatorNode.setColor(0.0, 0.0, 1.0, 1.0) - change.reparentTo(indicatorNode) - - self.physVelocityIndicator=indicatorNode - # Contact Node: - contactIndicatorNode=render.attachNewNode("physContactIndicator") - contactIndicatorNode.setScale(0.25) - contactIndicatorNode.setP(90.0) - contactIndicatorNode.setPos(self.shipNodePath, 0.0, 0.0, 5.0) - contactIndicatorNode.setColor(1.0, 0.0, 0.0, 1.0) - indicator.instanceTo(contactIndicatorNode) - self.physContactIndicator=contactIndicatorNode - else: - print "failed load of physics indicator" - - def avatarPhysicsIndicator(self, task): - #assert self.debugPrint("avatarPhysicsIndicator()") - # Velocity: - self.physVelocityIndicator.setPos(self.shipNodePath, 0.0, 0.0, 6.0) - physObject=self.actorNode.getPhysicsObject() - a=physObject.getVelocity() - self.physVelocityIndicator.setScale(math.sqrt(a.length())) - a+=self.physVelocityIndicator.getPos() - self.physVelocityIndicator.lookAt(Point3(a)) - # Contact: - contact=self.actorNode.getContactVector() - if contact==Vec3.zero(): - self.physContactIndicator.hide() - else: - self.physContactIndicator.show() - self.physContactIndicator.setPos(self.shipNodePath, 0.0, 0.0, 5.0) - #contact=self.actorNode.getContactVector() - point=Point3(contact+self.physContactIndicator.getPos()) - self.physContactIndicator.lookAt(point) - return Task.cont - - def displayDebugInfo(self): - """ - For debug use. - """ - onScreenDebug.add("w controls", "ShipPilot") - - onScreenDebug.add("w ship", self.ship) - onScreenDebug.add("w isAirborne", self.isAirborne) - onScreenDebug.add("posDelta1", - self.shipNodePath.getPosDelta(render).pPrintValues()) - - physObject=self.actorNode.getPhysicsObject() - if 0: - onScreenDebug.add("w posDelta3", - render.getRelativeVector( - self.shipNodePath, - self.shipNodePath.getPosDelta(render)).pPrintValues()) - if 0: - onScreenDebug.add("w priorParent", - self.priorParent.getLocalVector().pPrintValues()) - - onScreenDebug.add("w physObject pos", - physObject.getPosition().pPrintValues()) - onScreenDebug.add("w physObject hpr", - physObject.getOrientation().getHpr().pPrintValues()) - onScreenDebug.add("w physObject orien", - physObject.getOrientation().pPrintValues()) - if 1: - physObject = physObject.getVelocity() - onScreenDebug.add("w physObject vec", - physObject.pPrintValues()) - onScreenDebug.add("w physObject len", - "% 10.4f"%physObject.length()) - - onScreenDebug.add("orientation", - self.actorNode.getPhysicsObject().getOrientation().pPrintValues()) - - if 0: - momentumForce = self.momentumForce.getLocalVector() - onScreenDebug.add("w momentumForce vec", - momentumForce.pPrintValues()) - onScreenDebug.add("w momentumForce len", - "% 10.4f"%momentumForce.length()) - - if 0: - onScreenDebug.add("posDelta4", - self.priorParentNp.getRelativeVector( - render, - self.shipNodePath.getPosDelta(render)).pPrintValues()) - if 0: - onScreenDebug.add("w priorParent", - self.priorParent.getLocalVector().pPrintValues()) - if 0: - onScreenDebug.add("w priorParent po", - self.priorParent.getVector(physObject).pPrintValues()) - - if 1: - onScreenDebug.add("w contact", - self.actorNode.getContactVector().pPrintValues()) - - def handleAvatarControls(self, task): - """ - Check on the arrow keys and update the "avatar" (ship). - """ - if __debug__: - if self.wantDebugIndicator: - onScreenDebug.append("localAvatar pos = %s\n"%( - base.localAvatar.getPos().pPrintValues(),)) - onScreenDebug.append("localAvatar hpr = %s\n"%( - base.localAvatar.getHpr().pPrintValues(),)) - assert self.debugPrint("handleAvatarControls(task=%s)"%(task,)) - physObject = self.actorNode.getPhysicsObject() - contact = self.actorNode.getContactVector() - # get the button states: - forward = inputState.isSet("forward") - reverse = inputState.isSet("reverse") - turnLeft = inputState.isSet("slideLeft") or inputState.isSet("turnLeft") - turnRight = inputState.isSet("slideRight") or inputState.isSet("turnRight") - slide = inputState.isSet("slide") - slideLeft = 0 - slideRight = 0 - jump = inputState.isSet("jump") - # Determine what the speeds are based on the buttons: - - # Check for Auto-Sailing - if self.ship.getIsAutoSailing(): - forward = 1 - reverse = 0 - else: - forward = 0 - - # How far did we move based on the amount of time elapsed? - dt = ClockObject.getGlobalClock().getDt() - - minSpeed = (self.ship.acceleration + self.ship.speedboost) * self.ship.speednerf - minStraightSail = 1.0 / self.MAX_STRAIGHT_SAIL_BONUS * self.STRAIGHT_SAIL_BONUS_TIME * self.ship.speednerf - - if reverse: - # Decelerate while sails are up - if (self.straightHeading < 0): - self.straightHeading -= dt * self.TURNING_BONUS_REDUCTION * 2.0 - else: - self.straightHeading -= dt * self.TURNING_BONUS_REDUCTION * 4.0 - elif (self.straightHeading < minStraightSail) and forward: - # If not at MinSpeed, Accelerate regardless - self.straightHeading += dt * 1.5 - elif self.ship.threatCounter: - # If ship is recently damaged, do not increase Travel Speed - self.straightHeading = min(minStraightSail, self.straightHeading) - elif turnLeft or turnRight or not forward: - # Reset Straight Sailing Bonus - Only if above MinSpeed - if forward and (self.straightHeading - (dt * self.TURNING_BONUS_REDUCTION) < minStraightSail) and (self.straightHeading >= minStraightSail): - self.straightHeading = minStraightSail - else: - self.straightHeading -= dt * self.TURNING_BONUS_REDUCTION - elif forward: - # Add in the Straight Sailing Time - self.straightHeading += dt - - if reverse: - # Allow straightHeading to reach a negative value - self.straightHeading = max(self.REVERSE_STRAIGHT_SAIL_BONUS_TIME, self.straightHeading) - else: - # Normally min straightHeading is 0.0 - self.straightHeading = max(0.0, min(self.STRAIGHT_SAIL_BONUS_TIME, self.straightHeading)) - - # Straight Sailing Acceleration Bonus - straightSailBonus = 0.0 - straightSailBonus = self.straightHeading / self.STRAIGHT_SAIL_BONUS_TIME - straightSailBonus = min(self.MAX_STRAIGHT_SAIL_BONUS, straightSailBonus * self.MAX_STRAIGHT_SAIL_BONUS) - # self.__speed=(forward and self.ship.acceleration) or (reverse and self.ship.reverseAcceleration) - self.__speed = self.ship.acceleration - - avatarSlideSpeed = self.ship.acceleration * 0.5 * straightSailBonus - self.__slideSpeed=(forward or reverse) and ( - (slideLeft and -avatarSlideSpeed) or - (slideRight and avatarSlideSpeed)) - self.__rotationSpeed=not slide and ( - (turnLeft and self.ship.turnRate) or - (turnRight and -self.ship.turnRate)) - - # Add in Straight Sailing Multiplier - self.__speed *= (straightSailBonus * self.ship.speednerf) - self.__speed += self.ship.speedboost - self.__slideSpeed *= straightSailBonus - maxSpeed = self.ship.maxSpeed - - # Enable debug turbo modec - debugRunning = inputState.isSet("debugRunning") - if(debugRunning): - self.__speed*=base.debugRunningMultiplier - self.__slideSpeed*=base.debugRunningMultiplier - self.__rotationSpeed*=1.25 - maxSpeed = self.ship.maxSpeed * base.debugRunningMultiplier - - #*# - self.currentTurning += self.__rotationSpeed - if self.currentTurning > self.ship.maxTurn: - self.currentTurning = self.ship.maxTurn - elif self.currentTurning < -self.ship.maxTurn: - self.currentTurning = -self.ship.maxTurn - if turnLeft or turnRight: - mult = .9 - elif forward or reverse: - mult = .82 - else: - mult = .8 - self.currentTurning *= mult - if self.currentTurning < 0.001 and self.currentTurning > -0.001: - self.currentTurning = 0.0 - self.__rotationSpeed = self.currentTurning - - # Broadcast Event to Handlers (ShipStatusMeter) - messenger.send("setShipSpeed-%s" % (self.ship.getDoId()), [self.__speed, self.getMaxSpeed()]) - - if self.wantDebugIndicator: - self.displayDebugInfo() - - if self.needToDeltaPos: - self.setPriorParentVector() - self.needToDeltaPos = 0 - - #------------------------------ - #debugTempH=self.shipNodePath.getH() - if __debug__: - q1=self.shipNodePath.getQuat() - q2=physObject.getOrientation() - q1.normalize() - q2.normalize() - assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr()) - assert self.shipNodePath.getPos().almostEqual( - physObject.getPosition(), 0.0001) - #------------------------------ - - # Check to see if we're moving at all: - physVel = physObject.getVelocity() - physVelLen = physVel.length() - if (not physVel.almostEqual(Vec3(0),0.1) - or self.__speed - or self.__slideSpeed - or self.__rotationSpeed): - # don't factor in dt, the physics system will do that - distance = self.__speed #dt * self.__speed - goForward = True - if (distance < 0): - goForward = False - slideDistance = self.__slideSpeed - rotation = self.__rotationSpeed - if debugRunning: - rotation *= 4 - - # update pos: - # Take a step in the direction of our previous heading. - self.__vel=Vec3(Vec3.forward() * distance + Vec3.right() * slideDistance) - # rotMat is the rotation matrix corresponding to - # our previous heading. - rotMat=Mat3.rotateMatNormaxis(self.shipNodePath.getH(), Vec3.up()) - step=rotMat.xform(self.__vel) - - #newVector = self.acForce.getLocalVector()+Vec3(step) - newVector = Vec3(step) - #newVector=Vec3(rotMat.xform(newVector)) - #maxLen = maxSpeed - if (goForward): - maxLen = self.__speed - else: - maxLen = self.ship.reverseAcceleration - - if newVector.length() > maxLen and \ - not (debugRunning or base.localAvatar.getTurbo()): - newVector.normalize() - newVector *= maxLen - - if __debug__: - onScreenDebug.add( - "newVector", newVector) - onScreenDebug.add( - "newVector length", newVector.length()) - - base.controlForce.setVector(newVector) - - assert base.controlForce.getLocalVector() == newVector,'1' - assert base.controlForce.getPhysicsObject(),'2' - assert base.controlForce.getPhysicsObject() == physObject,'3' - - #momentum = self.momentumForce.getLocalVector() - #momentum *= 0.9 - #self.momentumForce.setVector(momentum) - - # update hpr: - o=physObject.getOrientation() - r=LRotationf() - # factor in dt since we're directly setting the rotation here - r.setHpr(Vec3(rotation * dt, 0.0, 0.0)) - physObject.setOrientation(o*r) - - # sync the change: - self.actorNode.updateTransform() - #assert self.shipNodePath.getH()==debugTempH-rotation - messenger.send("avatarMoving") - else: - # even if there are no active inputs, we still might be moving - assert physObject.getVelocity().almostEqual(Vec3(0),0.1) - #base.controlForce.setVector(Vec3.zero()) - goForward = True - - #*# - speed = physVel - if (goForward): - if physVelLen > maxSpeed: - speed.normalize() - speed *= maxSpeed - else: - if physVelLen > self.ship.maxReverseSpeed: - speed.normalize() - speed *= self.ship.maxReverseSpeed - - #speed *= 1.0 - dt * 0.05 - - # modify based on sail damage - speed *= self.ship.Sp - speed /= self.ship.maxSp - - if __debug__: - q1=self.shipNodePath.getQuat() - q2=physObject.getOrientation() - q1.normalize() - q2.normalize() - assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr() - assert self.shipNodePath.getPos().almostEqual( - physObject.getPosition(), 0.0001) - - # Clear the contact vector so we can - # tell if we contact something next frame - self.actorNode.setContactVector(Vec3.zero()) - - oldPosDelta = self.shipNodePath.getPosDelta(render) - oldDt = dt - assert hasattr(self.ship, 'worldVelocity') - if oldDt: - self.ship.worldVelocity = oldPosDelta*(1/oldDt) - if self.wantDebugIndicator: - onScreenDebug.add("w __oldPosDelta vec", - oldPosDelta.pPrintValues()) - onScreenDebug.add("w __oldPosDelta len", - "% 10.4f"%oldPosDelta.length()) - onScreenDebug.add("w __oldDt", - "% 10.4f"%oldDt) - onScreenDebug.add("w worldVelocity vec", - self.ship.worldVelocity.pPrintValues()) - onScreenDebug.add("w worldVelocity len", - "% 10.4f"%self.ship.worldVelocity.length()) - - # if hasattr(self.ship, 'sailBillow'): - # self.ship.sailBillow = self.sailsDeployed - - if hasattr(self.ship, 'currentTurning'): - self.ship.currentTurning = self.currentTurning - - return Task.cont - - def getMaxSpeed(self): - return self.ship.acceleration * self.MAX_STRAIGHT_SAIL_BONUS + self.ship.speedboost - - def getVelocity(self): - return self.__vel - - def enableAvatarControls(self): - """ - Activate the arrow keys, etc. - """ - assert self.debugPrint("enableShipControls()") - - # Reset our straight heading timer (to clear the straight-line sailing bonus) - self.straightHeading = 0 - - self.setCollisionsActive(1) - - if __debug__: - #self.accept("control-f3", self.spawnTest) #*# - self.accept("f3", self.reset) # for debugging only. - - taskName = "ShipControls-%s"%(id(self),) - # remove any old - taskMgr.remove(taskName) - # spawn the new task - taskMgr.add(self.handleAvatarControls, taskName, 25) - if self.physVelocityIndicator: - taskMgr.add( - self.avatarPhysicsIndicator, - "ShipControlsIndicator%s"%(id(self),), 35) - - def disableAvatarControls(self): - """ - Ignore the arrow keys, etc. - """ - # Clear our force vector - base.controlForce.setVector(Vec3(0)) - - # Reset our straight heading timer (to clear the straight-line sailing bonus) - self.straightHeading = 0 - - assert self.debugPrint("disableShipControls()") - taskName = "ShipControls-%s"%(id(self),) - taskMgr.remove(taskName) - - taskName = "ShipControlsIndicator%s"%(id(self),) - taskMgr.remove(taskName) - - if self.ship: - self.ship.worldVelocity = Vec3(0) - - if __debug__: - self.ignore("control-f3") #*# - self.ignore("f3") - - self.__speed = 0; - - # Broadcast Event to Handlers (ShipStatusMeter) - if self.ship: - messenger.send("setShipSpeed-%s" % (self.ship.getDoId()), [self.__speed, self.getMaxSpeed()]) - - if __debug__: - def setupAvatarPhysicsIndicator(self): - if self.wantDebugIndicator: - indicator=loader.loadModel('phase_5/models/props/dagger') - #self.walkControls.setAvatarPhysicsIndicator(indicator) - - def debugPrint(self, message): - """for debugging""" - return self.notify.debug( - str(id(self))+' '+message) diff --git a/direct/src/controls/ShipPilot2.py b/direct/src/controls/ShipPilot2.py deleted file mode 100755 index 215d2bf418..0000000000 --- a/direct/src/controls/ShipPilot2.py +++ /dev/null @@ -1,1009 +0,0 @@ -""" -ShipPilot.py is for avatars pilotting ships (or more accurately, a ship -as the avatar). - -A 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 control events. -""" - -from direct.directnotify.DirectNotifyGlobal import directNotify -from direct.controls.ControlManager import CollisionHandlerRayStart -from direct.showbase.InputStateGlobal import inputState -from direct.task.Task import Task -from pandac.PandaModules import * -import math - -from PhysicsWalker import PhysicsWalker - -class ShipPilot2(PhysicsWalker): - notify = directNotify.newCategory("PhysicsWalker") - wantDebugIndicator = base.config.GetBool( - 'want-avatar-physics-indicator', 0) - - useBowSternSpheres = 1 - useOneSphere = 0 - useDSSolid = 0 - useLifter = 0 - useHeightRay = 0 - - MAX_STRAIGHT_SAIL_BONUS = 4.0 - STRAIGHT_SAIL_BONUS_TIME = 10.0 - - # special methods - def __init__(self, gravity = -32.1740, standableGround=0.707, - hardLandingForce=16.0): - assert self.debugPrint( - "PhysicsWalker(gravity=%s, standableGround=%s)"%( - gravity, standableGround)) - PhysicsWalker.__init__( - self, gravity, standableGround, hardLandingForce) - self.__gravity=gravity - self.__standableGround=standableGround - self.__hardLandingForce=hardLandingForce - - self.needToDeltaPos = 0 - self.physVelocityIndicator=None - self.avatarControlForwardSpeed=0 - self.avatarControlJumpForce=0 - self.avatarControlReverseSpeed=0 - self.avatarControlRotateSpeed=0 - self.__oldAirborneHeight=None - self.getAirborneHeight=None - self.__oldContact=None - self.__oldPosDelta=Vec3(0) - self.__oldDt=0 - self.__speed=0.0 - self.__rotationSpeed=0.0 - self.__slideSpeed=0.0 - self.__vel=Vec3(0.0) - self.collisionsActive = 0 - self.currentTurning = 0.0 - - self.isAirborne = 0 - self.highMark = 0 - self.ship = None - - # Keeps track of the ship sailing in a straight heading - # for long periods of time. We slowly up the ship's max - # acceleration as this increases. - self.straightHeading = 0 - - def setWalkSpeed(self, forward, jump, reverse, rotate): - assert self.debugPrint("setWalkSpeed()") - self.avatarControlForwardSpeed=forward - self.avatarControlJumpForce=0.0 - self.avatarControlReverseSpeed=reverse - self.avatarControlRotateSpeed=rotate - - def getSpeeds(self): - #assert self.debugPrint("getSpeeds()") - return (self.__speed, self.__rotationSpeed) - - def setAvatar(self, ship): - if ship is None: - base.controlForce.clearPhysicsObject() - self.takedownPhysics() - self.ship = None - else: - base.controlForce.setPhysicsObject(ship.node().getPhysicsObject()) - #self.setupShip() - self.setupPhysics(ship) - self.ship = ship - - """ - #*# Debug: - if not hasattr(ship, "acceleration"): - self.ship.acceleration = 60 - self.ship.maxSpeed = 14 - self.ship.reverseAcceleration = 30 - self.ship.maxReverseSpeed = 2 - self.ship.turnRate = 3 - self.ship.maxTurn = 30 - self.ship.anchorDrag = .9 - self.ship.hullDrag = .9 - """ - - def setupRay(self, floorBitmask, floorOffset): - # This is a ray cast from your head down to detect floor polygons - # A toon is about 4.0 feet high, so start it there - self.cRay = CollisionRay( - 0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0) - cRayNode = CollisionNode('PW.cRayNode') - cRayNode.addSolid(self.cRay) - self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) - self.cRayBitMask = floorBitmask - cRayNode.setFromCollideMask(self.cRayBitMask) - cRayNode.setIntoCollideMask(BitMask32.allOff()) - - if 0 or self.useLifter: - # set up floor collision mechanism - self.lifter = CollisionHandlerFloor() - self.lifter.setInPattern("enter%in") - self.lifter.setOutPattern("exit%in") - self.lifter.setOffset(floorOffset) - - # Limit our rate-of-fall with the lifter. - # If this is too low, we actually "fall" off steep stairs - # and float above them as we go down. I increased this - # from 8.0 to 16.0 to prevent this - #self.lifter.setMaxVelocity(16.0) - - #self.bobNodePath = self.avatarNodePath.attachNewNode("bob") - #self.lifter.addCollider(self.cRayNodePath, self.cRayNodePath) - self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath) - else: # useCollisionHandlerQueue - self.cRayQueue = CollisionHandlerQueue() - self.cTrav.addCollider(self.cRayNodePath, self.cRayQueue) - - def determineHeight(self): - """ - returns the height of the avatar above the ground. - If there is no floor below the avatar, 0.0 is returned. - aka get airborne height. - """ - if self.useLifter: - height = self.avatarNodePath.getPos(self.cRayNodePath) - # If the shadow where not pointed strait down, we would need to - # get magnitude of the vector. Since it is strait down, we'll - # just get the z: - #spammy --> assert self.debugPrint( - #spammy --> "getAirborneHeight() returning %s"%(height.getZ(),)) - assert onScreenDebug.add("height", height.getZ()) - return height.getZ() - self.floorOffset - else: # useCollisionHandlerQueue - """ - returns the height of the avatar above the ground. - If there is no floor below the avatar, 0.0 is returned. - aka get airborne height. - """ - height = 0.0 - #*#self.cRayTrav.traverse(render) - if self.cRayQueue.getNumEntries() != 0: - # ...we have a floor. - # Choose the highest of the possibly several floors we're over: - self.cRayQueue.sortEntries() - floorPoint = self.cRayQueue.getEntry(0).getFromIntersectionPoint() - height = -floorPoint.getZ() - self.cRayQueue.clearEntries() - if __debug__: - onScreenDebug.add("height", height) - return height - - def setupSphere(self, bitmask, avatarRadius): - """ - Set up the collision sphere - """ - # This is a sphere on the ground to detect barrier collisions - if 0: - self.avatarRadius = avatarRadius - self.cSphere = CollisionTube( - Point3(0.0, 0.0, 0.0), Point3(0.0, 40.0, 0.0), avatarRadius) - cSphereNode = CollisionNode('SP.cSphereNode') - cSphereNode.addSolid(self.cSphere) - self.cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) - self.cSphereBitMask = bitmask - else: - # Middle sphere: - self.avatarRadius = avatarRadius - #self.cSphere = CollisionSphere(0.0, -5.0, 0.0, avatarRadius) - #cSphereNode = CollisionNode('SP.cSphereNode') - #cSphereNode.addSolid(self.cSphere) - #self.cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode) - self.cSphereBitMask = bitmask - - #cSphereNode.setFromCollideMask(self.cSphereBitMask) - #cSphereNode.setIntoCollideMask(BitMask32.allOff()) - - # set up collision mechanism - self.pusher = PhysicsCollisionHandler() - self.pusher.setInPattern("enter%in") - self.pusher.setOutPattern("exit%in") - - #self.pusher.addCollider(self.cSphereNodePath, self.avatarNodePath) - - if self.useBowSternSpheres: - # Front sphere: - self.cBowSphere = CollisionSphere( - 0.0, self.frontSphereOffset, -5.0, avatarRadius) - cBowSphereNode = CollisionNode('SP.cBowSphereNode') - cBowSphereNode.addSolid(self.cBowSphere) - self.cBowSphereNodePath = self.avatarNodePath.attachNewNode( - cBowSphereNode) - #self.cBowSphereNodePath.show() - - cBowSphereNode.setFromCollideMask(self.cSphereBitMask) - cBowSphereNode.setIntoCollideMask(BitMask32.allOff()) - - self.cBowSphereNode = cBowSphereNode - - self.pusher.addCollider( - self.cBowSphereNodePath, self.avatarNodePath) - - # Back sphere: - self.cSternSphere = CollisionSphere( - 0.0, self.backSphereOffset, -5.0, avatarRadius) - cSternSphereNode = CollisionNode('SP.cSternSphereNode') - cSternSphereNode.addSolid(self.cSternSphere) - self.cSternSphereNodePath = self.avatarNodePath.attachNewNode( - cSternSphereNode) - #self.cSternSphereNodePath.show() - self.cSternSphereBitMask = bitmask - - cSternSphereNode.setFromCollideMask(self.cSphereBitMask) - cSternSphereNode.setIntoCollideMask(BitMask32.allOff()) - - self.pusher.addCollider( - self.cSternSphereNodePath, self.avatarNodePath) - - # hide other things on my ship that these spheres might collide - # with and which I dont need anyways... - shipCollWall = self.avatarNodePath.transNode.find("**/collision_hull") - if not shipCollWall.isEmpty(): - shipCollWall.stash() - elif self.useOneSphere: - # Front sphere: - self.cSphere = CollisionSphere(0.0, 0.0, -5.0, avatarRadius) - cSphereNode = CollisionNode('SP.cSphereNode') - cSphereNode.addSolid(self.cSphere) - self.cSphereNodePath = self.avatarNodePath.attachNewNode( - cSphereNode) - if 1: - self.cSphereNodePath.show() - self.cSphereNodePath.showBounds() - - cSphereNode.setFromCollideMask(self.cSphereBitMask) - cSphereNode.setIntoCollideMask(BitMask32.allOff()) - - self.cSphereNode = cSphereNode - - self.pusher.addCollider( - self.cSphereNodePath, self.avatarNodePath) - - # hide other things on my ship that these spheres might collide - # with and which I dont need anyways... - shipCollWall = self.avatarNodePath.transNode.find("**/collision_hull") - if not shipCollWall.isEmpty(): - shipCollWall.stash() - elif self.useDSSolid: - # DSSolid: - self.cHull = CollisionDSSolid( - Point3(-160, 0, 0), 200, Point3(160, 0, 0), 200, - Plane(Vec3(0, 0, 1), Point3(0, 0, 50)), - Plane(Vec3(0, -1, 0), Point3(0, -90, 0))) - cHullNode = CollisionNode('SP.cHullNode') - cHullNode.addSolid(self.cHull) - self.cHullNodePath = self.avatarNodePath.attachNewNode( - cHullNode) - self.cHullNodePath.show() - - cHullNode.setFromCollideMask(bitmask) - cHullNode.setIntoCollideMask(BitMask32.allOff()) - - self.cHullNode = cHullNode - - self.pusher.addCollider( - self.cHullNodePath, self.avatarNodePath) - - # hide other things on my ship that these spheres might collide - # with and which I dont need anyways... - shipCollWall = self.avatarNodePath.transNode.find("**/collision_hull") - if not shipCollWall.isEmpty(): - shipCollWall.stash() - - def takedownPhysics(self): - assert self.debugPrint("takedownPhysics()") - if 0: - if hasattr(self, "phys"): - for i in self.nodes: - i.removeNode() - del self.phys - if self.ship != None: - self.ship.worldVelocity = Vec3.zero() - - def setupPhysics(self, avatarNodePath): - assert self.debugPrint("setupPhysics()") - if avatarNodePath is None: - return - assert not avatarNodePath.isEmpty() - - self.takedownPhysics() - self.nodes = [] - self.actorNode = avatarNodePath.node() - - if 0: - fn=ForceNode("ship priorParent") - fnp=NodePath(fn) - fnp.reparentTo(render) - self.nodes.append(fnp) - priorParent=LinearVectorForce(0.0, 0.0, 0.0) - fn.addForce(priorParent) - self.phys.addLinearForce(priorParent) - self.priorParentNp = fnp - self.priorParent = priorParent - - self.avatarNodePath = avatarNodePath - #self.actorNode.getPhysicsObject().resetPosition(self.avatarNodePath.getPos()) - #self.actorNode.updateTransform() - self.setupSphere(self.wallBitmask|self.floorBitmask, self.avatarRadius) - - - assert not avatarNodePath.isEmpty() - - self.setCollisionsActive(1) - - def setWallBitMask(self, bitMask): - self.wallBitmask = bitMask - - def setFloorBitMask(self, bitMask): - self.floorBitmask = bitMask - - def initializeCollisions(self, collisionTraverser, - avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0, - width = 30.0, length = 105.0, height = 45.0): - """ - width is feet from port to starboard. - length is feet from aft to bow. - height is feet from bildge to deck (i.e. not including mast height). - - Set up the avatar collisions - """ - assert self.debugPrint("initializeCollisions()") - self.cTrav = collisionTraverser - self.avatarRadius = avatarRadius - self.floorOffset = floorOffset - self.reach = reach - if self.useBowSternSpheres: - self.frontSphereOffset = length * 0.3 - self.backSphereOffset = -length * 0.7 - self.width = width - self.length = length - self.height = height - - def deleteCollisions(self): - assert self.debugPrint("deleteCollisions()") - del self.cTrav - - if self.useHeightRay: - del self.cRayQueue - self.cRayNodePath.removeNode() - del self.cRayNodePath - - if hasattr(self, "cSphere"): - del self.cSphere - self.cSphereNodePath.removeNode() - del self.cSphereNodePath - - del self.pusher - - self.getAirborneHeight = None - - def setTag(self, key, value): - if not hasattr(self, "collisionTags"): - self.collisionTags = {} - self.collisionTags[key] = value - - def setAirborneHeightFunc(self, getAirborneHeight): - self.getAirborneHeight = getAirborneHeight - - def setAvatarPhysicsIndicator(self, indicator): - """ - indicator is a NodePath - """ - assert self.debugPrint("setAvatarPhysicsIndicator()") - self.cSphereNodePath.show() - if indicator: - # Indicator Node: - change=render.attachNewNode("change") - #change.setPos(Vec3(1.0, 1.0, 1.0)) - #change.setHpr(0.0, 0.0, 0.0) - change.setScale(0.1) - #change.setColor(Vec4(1.0, 1.0, 1.0, 1.0)) - indicator.reparentTo(change) - - indicatorNode=render.attachNewNode("physVelocityIndicator") - #indicatorNode.setScale(0.1) - #indicatorNode.setP(90.0) - indicatorNode.setPos(self.avatarNodePath, 0.0, 0.0, 6.0) - indicatorNode.setColor(0.0, 0.0, 1.0, 1.0) - change.reparentTo(indicatorNode) - - self.physVelocityIndicator=indicatorNode - # Contact Node: - contactIndicatorNode=render.attachNewNode("physContactIndicator") - contactIndicatorNode.setScale(0.25) - contactIndicatorNode.setP(90.0) - contactIndicatorNode.setPos(self.avatarNodePath, 0.0, 0.0, 5.0) - contactIndicatorNode.setColor(1.0, 0.0, 0.0, 1.0) - indicator.instanceTo(contactIndicatorNode) - self.physContactIndicator=contactIndicatorNode - else: - print "failed load of physics indicator" - - def avatarPhysicsIndicator(self, task): - #assert self.debugPrint("avatarPhysicsIndicator()") - # Velocity: - self.physVelocityIndicator.setPos(self.avatarNodePath, 0.0, 0.0, 6.0) - physObject=self.actorNode.getPhysicsObject() - a=physObject.getVelocity() - self.physVelocityIndicator.setScale(math.sqrt(a.length())) - a+=self.physVelocityIndicator.getPos() - self.physVelocityIndicator.lookAt(Point3(a)) - # Contact: - contact=self.actorNode.getContactVector() - if contact==Vec3.zero(): - self.physContactIndicator.hide() - else: - self.physContactIndicator.show() - self.physContactIndicator.setPos(self.avatarNodePath, 0.0, 0.0, 5.0) - #contact=self.actorNode.getContactVector() - point=Point3(contact+self.physContactIndicator.getPos()) - self.physContactIndicator.lookAt(point) - return Task.cont - - def setCollisionsActive(self, active = 1): - assert self.debugPrint("collisionsActive(active=%s)"%(active,)) - if self.collisionsActive != active: - self.collisionsActive = active - if active: - if self.useBowSternSpheres: - self.cTrav.addCollider(self.cBowSphereNodePath, self.pusher) - self.cTrav.addCollider(self.cSternSphereNodePath, self.pusher) - elif self.useOneSphere: - self.cTrav.addCollider(self.cSphereNodePath, self.pusher) - elif self.useDSSolid: - self.cTrav.addCollider(self.cHullNodePath, self.pusher) - if self.useHeightRay: - if self.useLifter: - self.cTrav.addCollider(self.cRayNodePath, self.lifter) - else: - self.cTrav.addCollider(self.cRayNodePath, self.cRayQueue) - else: - if self.useBowSternSpheres: - self.cTrav.removeCollider(self.cBowSphereNodePath) - self.cTrav.removeCollider(self.cSternSphereNodePath) - elif self.useOneSphere: - self.cTrav.removeCollider(self.cSphereNodePath) - elif self.useDSSolid: - self.cTrav.removeCollider(self.cHullNodePath) - if self.useHeightRay: - self.cTrav.removeCollider(self.cRayNodePath) - # Now that we have disabled collisions, make one more pass - # right now to ensure we aren't standing in a wall. - self.oneTimeCollide() - - def getCollisionsActive(self): - assert self.debugPrint( - "getCollisionsActive() returning=%s"%(self.collisionsActive,)) - return self.collisionsActive - - def placeOnFloor(self): - """ - Make a reasonable effort to place the avatar on the ground. - For example, this is useful when switching away from the - current walker. - """ - self.oneTimeCollide() - self.avatarNodePath.setZ( - self.avatarNodePath.getZ()-self.getAirborneHeight()) - - 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.debugPrint("oneTimeCollide()") - tempCTrav = CollisionTraverser("oneTimeCollide") - if self.useHeightRay: - if self.useLifter: - tempCTrav.addCollider(self.cRayNodePath, self.lifter) - else: - tempCTrav.addCollider(self.cRayNodePath, self.cRayQueue) - tempCTrav.traverse(render) - - def addBlastForce(self, vector): - pass - - def displayDebugInfo(self): - """ - For debug use. - """ - onScreenDebug.add("w controls", "ShipPilot") - - onScreenDebug.add("w ship", self.ship) - onScreenDebug.add("w isAirborne", self.isAirborne) - onScreenDebug.add("posDelta1", - self.avatarNodePath.getPosDelta(render).pPrintValues()) - - physObject=self.actorNode.getPhysicsObject() - if 0: - onScreenDebug.add("w posDelta3", - render.getRelativeVector( - self.avatarNodePath, - self.avatarNodePath.getPosDelta(render)).pPrintValues()) - if 0: - onScreenDebug.add("w priorParent", - self.priorParent.getLocalVector().pPrintValues()) - - onScreenDebug.add("w physObject pos", - physObject.getPosition().pPrintValues()) - onScreenDebug.add("w physObject hpr", - physObject.getOrientation().getHpr().pPrintValues()) - onScreenDebug.add("w physObject orien", - physObject.getOrientation().pPrintValues()) - if 1: - physObject = physObject.getVelocity() - onScreenDebug.add("w physObject vec", - physObject.pPrintValues()) - onScreenDebug.add("w physObject len", - "% 10.4f"%physObject.length()) - - onScreenDebug.add("orientation", - self.actorNode.getPhysicsObject().getOrientation().pPrintValues()) - - if 0: - momentumForce = self.momentumForce.getLocalVector() - onScreenDebug.add("w momentumForce vec", - momentumForce.pPrintValues()) - onScreenDebug.add("w momentumForce len", - "% 10.4f"%momentumForce.length()) - - ## if 1: - ## keel = self.keel.getLocalVector() - ## onScreenDebug.add("w keel vec", - ## keel.pPrintValues()) - if 0: - onScreenDebug.add("posDelta4", - self.priorParentNp.getRelativeVector( - render, - self.avatarNodePath.getPosDelta(render)).pPrintValues()) - if 0: - onScreenDebug.add("w priorParent", - self.priorParent.getLocalVector().pPrintValues()) - if 0: - onScreenDebug.add("w priorParent po", - self.priorParent.getVector(physObject).pPrintValues()) - - if 1: - onScreenDebug.add("w contact", - self.actorNode.getContactVector().pPrintValues()) - #onScreenDebug.add("airborneHeight", "% 10.4f"%( - # self.getAirborneHeight(),)) - - def handleAvatarControls(self, task): - """ - Check on the arrow keys and update the avatar. - """ - if __debug__: - if self.wantDebugIndicator: - onScreenDebug.append("localAvatar pos = %s\n"%( - base.localAvatar.getPos().pPrintValues(),)) - onScreenDebug.append("localAvatar hpr = %s\n"%( - base.localAvatar.getHpr().pPrintValues(),)) - #assert self.debugPrint("handleAvatarControls(task=%s)"%(task,)) - physObject=self.actorNode.getPhysicsObject() - contact=self.actorNode.getContactVector() - - # get the button states: - forward = inputState.isSet("forward") - reverse = inputState.isSet("reverse") - turnLeft = inputState.isSet("slideLeft") or inputState.isSet("turnLeft") - turnRight = inputState.isSet("slideRight") or inputState.isSet("turnRight") - slide = inputState.isSet("slide") - slideLeft = 0 - slideRight = 0 - jump = inputState.isSet("jump") - # Determine what the speeds are based on the buttons: - - # Check for Auto-Sailing - if self.ship.getIsAutoSailing(): - forward = 1 - reverse = 0 - - # How far did we move based on the amount of time elapsed? - dt=ClockObject.getGlobalClock().getDt() - - if reverse or turnLeft or turnRight: - # Reset Straight Sailing Bonus - self.straightHeading = 0 - - # Straight Sailing Acceleration Bonus - straightSailDt += dt - straightSailBonus = 0.0 - if straightSailDt > self.STRAIGHT_SAIL_BONUS_TIME / 2.0: - straightSailBonus = (straightSailDt - (self.STRAIGHT_SAIL_BONUS_TIME / 2.0)) / self.STRAIGHT_SAIL_BONUS_TIME / 2.0 - straightSailBonus *= self.MAX_STRAIGHT_SAIL_BONUS - straightSailBonus += 1.0 - - print "##################" - print straightSailBonus - - # this was causing the boat to get stuck moving forward or back - if 0: - if not hasattr(self, "sailsDeployed"): - self.sailsDeployed = 0.0 - if forward and reverse: - # Way anchor: - self.__speed = 0.0 - physObject.setVelocity(Vec3.zero()) - elif forward: - self.sailsDeployed += 0.25 - if self.sailsDeployed > 1.0: - self.sailsDeployed = 1.0 - elif reverse: - self.sailsDeployed -= 0.25 - if self.sailsDeployed < -1.0: - self.sailsDeployed = -1.0 - self.__speed = self.ship.acceleration * self.sailsDeployed - else: - self.__speed=(forward and self.ship.acceleration) or \ - (reverse and -self.ship.reverseAcceleration) - #self.__speed=(forward and min(dt*(self.__speed + self.ship.acceleration), self.ship.maxSpeed) or - # reverse and min(dt*(self.__speed - self.ship.reverseAcceleration), self.ship.maxReverseSpeed)) - - avatarSlideSpeed=self.ship.acceleration*0.5 - #self.__slideSpeed=slide and ( - # (turnLeft and -avatarSlideSpeed) or - # (turnRight and avatarSlideSpeed)) - self.__slideSpeed=(forward or reverse) and ( - (slideLeft and -avatarSlideSpeed) or - (slideRight and avatarSlideSpeed)) - self.__rotationSpeed=not slide and ( - (turnLeft and self.ship.turnRate) or - (turnRight and -self.ship.turnRate)) - - # Add in Straight Sailing Multiplier - self.__speed *= straightSailBonus - - # Enable debug turbo mode - maxSpeed = self.ship.maxSpeed * straightSailBonus - debugRunning = inputState.isSet("debugRunning") - if debugRunning or base.localAvatar.getTurbo(): - self.__speed*=4.0 - self.__slideSpeed*=4.0 - self.__rotationSpeed*=1.25 - maxSpeed = self.ship.maxSpeed * 4.0 - - #self.__speed*=4.0 - #self.__slideSpeed*=4.0 - #self.__rotationSpeed*=1.25 - #maxSpeed = self.ship.maxSpeed * 4.0 - - #*# - self.currentTurning += self.__rotationSpeed - if self.currentTurning > self.ship.maxTurn: - self.currentTurning = self.ship.maxTurn - elif self.currentTurning < -self.ship.maxTurn: - self.currentTurning = -self.ship.maxTurn - if turnLeft or turnRight: - mult = .9 - elif forward or reverse: - mult = .82 - else: - mult = .8 - self.currentTurning *= mult - if self.currentTurning < 0.001 and self.currentTurning > -0.001: - self.currentTurning = 0.0 - self.__rotationSpeed = self.currentTurning - - - if self.wantDebugIndicator: - self.displayDebugInfo() - - if self.needToDeltaPos: - self.setPriorParentVector() - self.needToDeltaPos = 0 - - airborneHeight=self.getAirborneHeight() - if airborneHeight > self.highMark: - self.highMark = airborneHeight - if __debug__: - onScreenDebug.add("highMark", "% 10.4f"%(self.highMark,)) - #if airborneHeight < 0.1: #contact!=Vec3.zero(): - if 1: - if (airborneHeight > self.avatarRadius*0.5 - or physObject.getVelocity().getZ() > 0.0 - ): # Check stair angles before changing this. - # The avatar is airborne (maybe a lot or a tiny amount). - self.isAirborne = 1 - else: - # The avatar is very close to the ground (close - # enough to be considered on the ground). - if self.isAirborne and physObject.getVelocity().getZ() <= 0.0: - # the avatar has landed. - contactLength = contact.length() - if contactLength>self.__hardLandingForce: - messenger.send("shipJumpHardLand") - else: - messenger.send("shipJumpLand") - #self.priorParent.setVector(Vec3.zero()) - self.isAirborne = 0 - elif jump: - #self.__jumpButton=0 - messenger.send("shipJumpStart") - if 0: - # Jump away from walls and with with the slope normal. - jumpVec=Vec3(contact+Vec3.up()) - #jumpVec=Vec3(rotAvatarToPhys.xform(jumpVec)) - jumpVec.normalize() - else: - # Jump straight up, even if next to a wall. - jumpVec=Vec3.up() - jumpVec*=self.avatarControlJumpForce - physObject.addImpulse(Vec3(jumpVec)) - self.isAirborne = 1 # Avoid double impulse before fully airborne. - else: - self.isAirborne = 0 - if __debug__: - onScreenDebug.add("isAirborne", "%d"%(self.isAirborne,)) - else: - if contact!=Vec3.zero(): - # The avatar has touched something (but might - # not be on the ground). - contactLength = contact.length() - contact.normalize() - angle=contact.dot(Vec3.up()) - if angle>self.__standableGround: - # ...avatar is on standable ground. - if self.__oldContact==Vec3.zero(): - #if self.__oldAirborneHeight > 0.1: #self.__oldContact==Vec3.zero(): - # ...avatar was airborne. - self.jumpCount-=1 - if contactLength>self.__hardLandingForce: - messenger.send("jumpHardLand") - else: - messenger.send("jumpLand") - elif jump: - self.jumpCount+=1 - #self.__jumpButton=0 - messenger.send("jumpStart") - jump=Vec3(contact+Vec3.up()) - #jump=Vec3(rotAvatarToPhys.xform(jump)) - jump.normalize() - jump*=self.avatarControlJumpForce - physObject.addImpulse(Vec3(jump)) - - if contact!=self.__oldContact: - # We must copy the vector to preserve it: - self.__oldContact=Vec3(contact) - self.__oldAirborneHeight=airborneHeight - - #------------------------------ - #debugTempH=self.avatarNodePath.getH() - if __debug__: - q1=self.avatarNodePath.getQuat() - q2=physObject.getOrientation() - q1.normalize() - q2.normalize() - assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr()) - assert self.avatarNodePath.getPos().almostEqual( - physObject.getPosition(), 0.0001) - #------------------------------ - - # Check to see if we're moving at all: - physVel = physObject.getVelocity() - physVelLen = physVel.length() - if (physVelLen!=0. - or self.__speed - or self.__slideSpeed - or self.__rotationSpeed): - distance = dt * self.__speed - goForward = True - if (distance < 0): - goForward = False - slideDistance = dt * self.__slideSpeed - rotation = dt * self.__rotationSpeed - - # update pos: - # Take a step in the direction of our previous heading. - self.__vel=Vec3( - Vec3.forward() * distance + - Vec3.right() * slideDistance) - - # rotMat is the rotation matrix corresponding to - # our previous heading. - rotMat=Mat3.rotateMatNormaxis( - self.avatarNodePath.getH(), Vec3.up()) - step=rotMat.xform(self.__vel) - - #newVector = self.acForce.getLocalVector()+Vec3(step) - newVector = Vec3(step) - #newVector=Vec3(rotMat.xform(newVector)) - #maxLen = maxSpeed - if (goForward): - maxLen = self.ship.acceleration - else: - maxLen = self.ship.reverseAcceleration - if newVector.length() > maxLen: - newVector.normalize() - newVector *= maxLen - - - if __debug__: - onScreenDebug.add( - "newVector", newVector) - onScreenDebug.add( - "newVector length", newVector.length()) - base.controlForce.setVector(newVector) - assert base.controlForce.getLocalVector() == newVector - assert base.controlForce.getPhysicsObject() - assert base.controlForce.getPhysicsObject() == physObject - - - #momentum = self.momentumForce.getLocalVector() - #momentum *= 0.9 - #self.momentumForce.setVector(momentum) - - # update hpr: - o=physObject.getOrientation() - r=LRotationf() - r.setHpr(Vec3(rotation, 0.0, 0.0)) - physObject.setOrientation(o*r) - - # sync the change: - self.actorNode.updateTransform() - #assert self.avatarNodePath.getH()==debugTempH-rotation - messenger.send("avatarMoving") - else: - # even if there are no active inputs, we still might be moving - assert physObject.getVelocity().length() == 0. - #base.controlForce.setVector(Vec3.zero()) - goForward = True - - - #*# - speed = physVel - if (goForward): - if physVelLen > maxSpeed: - speed.normalize() - speed *= maxSpeed - else: - if physVelLen > self.ship.maxReverseSpeed: - speed.normalize() - speed *= self.ship.maxReverseSpeed - - #speed *= 1.0 - dt * 0.05 - - # modify based on sail damage - speed *= self.ship.Sp - speed /= self.ship.maxSp - ## physObject.setVelocity(speed) - - #rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up()) - #speed=rotMat.xform(speed) - # The momentumForce makes it feel like we are sliding on ice -- Joe - # f = Vec3(self.__vel) - # f.normalize() - # self.momentumForce.setVector(Vec3(f*(speed.length()*0.9))) - - - if __debug__: - q1=self.avatarNodePath.getQuat() - q2=physObject.getOrientation() - q1.normalize() - q2.normalize() - assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr() - assert self.avatarNodePath.getPos().almostEqual( - physObject.getPosition(), 0.0001) - - # Clear the contact vector so we can - # tell if we contact something next frame - self.actorNode.setContactVector(Vec3.zero()) - - self.__oldPosDelta = self.avatarNodePath.getPosDelta(render) - self.__oldDt = dt - assert hasattr(self.ship, 'worldVelocity') - self.ship.worldVelocity = self.__oldPosDelta*(1/self.__oldDt) - if self.wantDebugIndicator: - onScreenDebug.add("w __oldPosDelta vec", - self.__oldPosDelta.pPrintValues()) - onScreenDebug.add("w __oldPosDelta len", - "% 10.4f"%self.__oldPosDelta.length()) - onScreenDebug.add("w __oldDt", - "% 10.4f"%self.__oldDt) - onScreenDebug.add("w worldVelocity vec", - self.ship.worldVelocity.pPrintValues()) - onScreenDebug.add("w worldVelocity len", - "% 10.4f"%self.ship.worldVelocity.length()) - - # if hasattr(self.ship, 'sailBillow'): - # self.ship.sailBillow = self.sailsDeployed - - if hasattr(self.ship, 'currentTurning'): - self.ship.currentTurning = self.currentTurning - - return Task.cont - - def doDeltaPos(self): - assert self.debugPrint("doDeltaPos()") - self.needToDeltaPos = 1 - - def setPriorParentVector(self): - assert self.debugPrint("doDeltaPos()") - - #print "self.__oldDt", self.__oldDt, "self.__oldPosDelta", self.__oldPosDelta - if __debug__: - onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt) - onScreenDebug.add("self.__oldPosDelta", - self.__oldPosDelta.pPrintValues()) - - velocity = self.__oldPosDelta*(1/self.__oldDt)#*4.0 # *4.0 is a hack - assert self.debugPrint(" __oldPosDelta=%s"%(self.__oldPosDelta,)) - assert self.debugPrint(" velocity=%s"%(velocity,)) - self.priorParent.setVector(Vec3(velocity)) - if __debug__: - if self.wantDebugIndicator: - onScreenDebug.add("velocity", velocity.pPrintValues()) - - def reset(self): - assert self.debugPrint("reset()") - self.actorNode.getPhysicsObject().resetPosition( - self.avatarNodePath.getPos()) - self.priorParent.setVector(Vec3.zero()) - self.highMark = 0 - self.actorNode.setContactVector(Vec3.zero()) - if __debug__: - contact=self.actorNode.getContactVector() - onScreenDebug.add("priorParent po", self.priorParent.getVector( - self.actorNode.getPhysicsObject()).pPrintValues()) - onScreenDebug.add("highMark", "% 10.4f"%(self.highMark,)) - onScreenDebug.add("contact", contact.pPrintValues()) - - def getVelocity(self): - return self.__vel - - def enableAvatarControls(self): - """ - Activate the arrow keys, etc. - """ - assert self.debugPrint("enableAvatarControls()") - assert self.collisionsActive - - if __debug__: - #self.accept("control-f3", self.spawnTest) #*# - self.accept("f3", self.reset) # for debugging only. - - taskName = "AvatarControls-%s"%(id(self),) - # remove any old - taskMgr.remove(taskName) - # spawn the new task - taskMgr.add(self.handleAvatarControls, taskName, 25) - if self.physVelocityIndicator: - taskMgr.add( - self.avatarPhysicsIndicator, - "AvatarControlsIndicator%s"%(id(self),), 35) - - def disableAvatarControls(self): - """ - Ignore the arrow keys, etc. - """ - assert self.debugPrint("disableAvatarControls()") - taskName = "AvatarControls-%s"%(id(self),) - taskMgr.remove(taskName) - - taskName = "AvatarControlsIndicator%s"%(id(self),) - taskMgr.remove(taskName) - - if __debug__: - self.ignore("control-f3") #*# - self.ignore("f3") - - if __debug__: - def setupAvatarPhysicsIndicator(self): - if self.wantDebugIndicator: - indicator=loader.loadModel('phase_5/models/props/dagger') - #self.walkControls.setAvatarPhysicsIndicator(indicator) - - def debugPrint(self, message): - """for debugging""" - return self.notify.debug( - str(id(self))+' '+message)