def handleKeyboardEvent(self, task): keys = self.keys dt = globalClock.getDt() impulse = Vec3(0, 0, 0) increment = self._impulseIncrement * dt above_limit = self.is_above_limit for key, vec in (("left", Vec3.left()), ("right", Vec3.right()), ("up", Vec3.forward()), ("down", Vec3.back())): if keys[key] and (not above_limit or self.is_braking(vec)): impulse += vec * increment self.addImpulse(impulse) # If Equismo was not hit by an enemy look at the movement direction. # Otherwise look at the enemy until Equismo turns around. if not self._hit: self.face(self.velocity) elif ((impulse.length() > 0) and (self.velocity.length() > 0.5) and (not self.is_braking(impulse))): self._hit = False self.doWalkAnimation(impulse) return task.cont
def onMouseMoveTransforming3D(self, vp): now = self.getPointOnGizmo() gizmoOrigin = self.getGizmoOrigin() gizmoDir = self.getGizmoDirection(self.widget.activeAxis.axisIdx) ref = Vec3.forward() if gizmoDir == ref: ref = Vec3.right() nowVec = Vec3(now - gizmoOrigin).normalized() origVec = Vec3(self.transformStart - gizmoOrigin).normalized() axisToHprAxis = { 0: 1, # pitch 1: 2, # roll 2: 0 # yaw } snap = not vp.mouseWatcher.isButtonDown(KeyboardButton.shift()) origAngle = origVec.signedAngleDeg( ref, self.getGizmoDirection(self.widget.activeAxis.axisIdx)) angle = nowVec.signedAngleDeg( ref, self.getGizmoDirection(self.widget.activeAxis.axisIdx)) hpr = Vec3(0) if snap: ang = round(-(angle - origAngle) / 15) * 15 else: ang = -(angle - origAngle) hpr[axisToHprAxis[self.widget.activeAxis.axisIdx]] = ang self.toolVisRoot.setHpr(hpr)
def updateCamera(self, x, y): factor = 0.01 dX = (self.mousePrevX - x) * factor dY = (self.mousePrevY - y) * factor if self.mouseDown1: self._rotateTheta(dX * math.pi * self.rotateMag) self._rotatePhi(-dY * math.pi * self.rotateMag) if self.mouseDown2: vecX = self.target.getRelativeVector(self.base.camera, Vec3.right()) vecY = self.target.getRelativeVector(self.base.camera, Vec3.forward()) vecY.setZ(0.0) vecY.normalize() offset = (vecX * dX * self.moveMag) + (vecY * dY * self.moveMag) self.target.setPos(self.target, offset) if self.mouseDown3: self.zoom(dY * self.zoomMag) self.mousePrevX = x self.mousePrevY = y # Update camera position position = Point3(0.0, 0.0, 0.0) position.setX(self.r * math.cos(self.theta) * math.sin(self.phi)) position.setY(self.r * math.sin(self.theta) * math.sin(self.phi)) position.setZ(self.r * math.cos(self.phi)) self.base.camera.setPos(position) self.base.camera.lookAt(self.target)
def updateCamera(self, task): if self.base.mouseWatcherNode.hasMouse(): # Register camera controls mouseX = self.base.mouseWatcherNode.getMouseX() mouseY = self.base.mouseWatcherNode.getMouseY() dX = self.mousePrevX - mouseX dY = self.mousePrevY - mouseY if self.mouseDown1: self.rotateTheta(dX * math.pi * self.rotateMag) self.rotatePhi(-dY * math.pi * self.rotateMag) if self.mouseDown2: vecX = self.target.getRelativeVector(self.base.camera, Vec3.right()) vecY = self.target.getRelativeVector(self.base.camera, Vec3.forward()) vecY.setZ(0.0) vecY.normalize() offset = (vecX * dX * self.moveMag) + (vecY * dY * self.moveMag) self.target.setPos(self.target, offset) if self.mouseDown3: self.zoom(dY * self.zoomMag) self.mousePrevX = mouseX self.mousePrevY = mouseY # Update camera position position = Point3(0.0, 0.0, 0.0) position.setX(self.r * math.cos(self.theta) * math.sin(self.phi)) position.setY(self.r * math.sin(self.theta) * math.sin(self.phi)) position.setZ(self.r * math.cos(self.phi)) self.base.camera.setPos(position) self.base.camera.lookAt(self.target) return task.cont
def updateCamera(self, task): if self.base.mouseWatcherNode.hasMouse(): # Register camera controls mouseX = self.base.mouseWatcherNode.getMouseX() mouseY = self.base.mouseWatcherNode.getMouseY() dX = self.mousePrevX - mouseX dY = self.mousePrevY - mouseY if self.mouseDown1: self.rotateTheta(dX * (math.pi / 2.0)) self.rotatePhi(-dY * (math.pi / 2.0)) if self.mouseDown2: self.offset.setX(self.offset.getX() + dX * 10) self.offset.setY(self.offset.getY() + dY * 10) if self.mouseDown3: self.zoom(dY * 50) self.mousePrevX = mouseX self.mousePrevY = mouseY # Update camera position self.position.setX(self.r * math.cos(self.theta) * math.sin(self.phi)) self.position.setY(self.r * math.sin(self.theta) * math.sin(self.phi)) self.position.setZ(self.r * math.cos(self.phi)) vecX = self.base.render.getRelativeVector(self.base.camera, Vec3.right()) vecY = self.base.render.getRelativeVector(self.base.camera, Vec3.forward()) vecY.setZ(0.0) vecY.normalize() offsetWorld = (vecX * self.offset.getX()) + (vecY * self.offset.getY()) self.base.camera.setPos(self.position + offsetWorld) self.base.camera.lookAt(self.target + offsetWorld) return task.cont
def handleAvatarControls(self, task): """ Check on the arrow keys and update the avatar. """ # get the button states: run = inputState.isSet("run") forward = inputState.isSet("forward") reverse = inputState.isSet("reverse") turnLeft = inputState.isSet("turnLeft") turnRight = inputState.isSet("turnRight") slideLeft = inputState.isSet("slideLeft") slideRight = inputState.isSet("slideRight") jump = inputState.isSet("jump") avatarControlForwardSpeed = 0 avatarControlReverseSpeed = 0 avatarControlSLeftSpeed = 0 avatarControlSRightSpeed = 0 if forward: if not self.hasSetForwardInitTime: self.forwardInitTime = globalClock.getFrameTime() self.hasSetForwardInitTime = True self.isAtZeroForward = False self.hasSetForwardStopTime = False timeSinceForwardSet = globalClock.getFrameTime() - self.forwardInitTime if timeSinceForwardSet == 0: avatarControlForwardSpeed = 0.0 else: avatarControlForwardSpeed = min((timeSinceForwardSet / self.avatarControlForwardSpeed) * 750, self.avatarControlForwardSpeed) else: if self.hasSetForwardInitTime: self.hasSetForwardInitTime = False if not self.hasSetForwardStopTime: self.forwardStopTime = globalClock.getFrameTime() self.hasSetForwardStopTime = True timeSinceForwardStop = globalClock.getFrameTime() - self.forwardStopTime if timeSinceForwardStop == 0: avatarControlForwardSpeed = 16.0 elif not self.isAtZeroForward: avatarControlForwardSpeed = self.avatarControlForwardSpeed - (timeSinceForwardStop * 50) if avatarControlForwardSpeed <= 0.5: avatarControlForwardSpeed = 0.0 self.isAtZeroForward = True self.hasSetForwardStopTime = False if reverse: if not self.hasSetReverseInitTime: self.reverseInitTime = globalClock.getFrameTime() self.hasSetReverseInitTime = True self.isAtZeroReverse = False self.hasSetReverseStopTime = False timeSinceReverseSet = globalClock.getFrameTime() - self.reverseInitTime if timeSinceReverseSet == 0: avatarControlReverseSpeed = 0.0 else: avatarControlReverseSpeed = min((timeSinceReverseSet / self.avatarControlReverseSpeed) * 400, self.avatarControlReverseSpeed) else: if self.hasSetReverseInitTime: self.hasSetReverseInitTime = False if not self.hasSetReverseStopTime: self.reverseStopTime = globalClock.getFrameTime() self.hasSetReverseStopTime = True timeSinceReverseStop = globalClock.getFrameTime() - self.reverseStopTime if timeSinceReverseStop == 0: avatarControlReverseSpeed = 16.0 elif not self.isAtZeroReverse: avatarControlReverseSpeed = self.avatarControlReverseSpeed - (timeSinceReverseStop * 20) if avatarControlReverseSpeed <= 0.5: avatarControlReverseSpeed = 0.0 self.isAtZeroReverse = True self.hasSetReverseStopTime = False if slideLeft: if not self.hasSetSLeftInitTime: self.sLeftInitTime = globalClock.getFrameTime() self.hasSetSLeftInitTime = True self.isAtZeroSLeft = False self.hasSetSLeftStopTime = False timeSinceSLeftSet = globalClock.getFrameTime() - self.sLeftInitTime if timeSinceSLeftSet == 0: avatarControlSLeftSpeed = 0.0 else: avatarControlSLeftSpeed = min((timeSinceSLeftSet / self.avatarControlForwardSpeed) * 750, self.avatarControlForwardSpeed) else: if self.hasSetSLeftInitTime: self.hasSetSLeftInitTime = False if not self.hasSetSLeftStopTime: self.sLeftStopTime = globalClock.getFrameTime() self.hasSetSLeftStopTime = True timeSinceSLeftStop = globalClock.getFrameTime() - self.sLeftStopTime if timeSinceSLeftStop == 0: avatarControlSLeftSpeed = 16.0 elif not self.isAtZeroSLeft: avatarControlSLeftSpeed = self.avatarControlForwardSpeed - (timeSinceSLeftStop * 50) if avatarControlSLeftSpeed <= 0.5: avatarControlSLeftSpeed = 0.0 self.isAtZeroSLeft = True self.hasSetSLeftStopTime = False if slideRight: if not self.hasSetSRightInitTime: self.sRightInitTime = globalClock.getFrameTime() self.hasSetSRightInitTime = True self.isAtZeroSRight = False self.hasSetSRightStopTime = False timeSinceSRightSet = globalClock.getFrameTime() - self.sRightInitTime if timeSinceSRightSet == 0: avatarControlSRightSpeed = 0.0 else: avatarControlSRightSpeed = min((timeSinceSRightSet / self.avatarControlForwardSpeed) * 750, self.avatarControlForwardSpeed) else: if self.hasSetSRightInitTime: self.hasSetSRightInitTime = False if not self.hasSetSRightStopTime: self.sRightStopTime = globalClock.getFrameTime() self.hasSetSRightStopTime = True timeSinceSRightStop = globalClock.getFrameTime() - self.sRightStopTime if timeSinceSRightStop == 0: avatarControlSRightSpeed = 16.0 elif not self.isAtZeroSRight: avatarControlSRightSpeed = self.avatarControlForwardSpeed - (timeSinceSRightStop * 50) if avatarControlSRightSpeed <= 0.5: avatarControlSRightSpeed = 0.0 self.isAtZeroSRight = True self.hasSetSRightStopTime = False # Check for Auto-Run #if 'localAvatar' in __builtins__: # if base.localAvatar and base.localAvatar.getAutoRun(): # forward = 1 # reverse = 0 # Determine what the speeds are based on the buttons: self.speed=(avatarControlForwardSpeed or -avatarControlReverseSpeed) # Slide speed is a scaled down version of forward speed # Note: you can multiply a factor in here if you want slide to # be slower than normal walk/run. Let's try full speed. #self.slideSpeed=(slideLeft and -self.avatarControlForwardSpeed*0.75 or # slideRight and self.avatarControlForwardSpeed*0.75) self.slideSpeed=(-avatarControlSLeftSpeed or avatarControlSRightSpeed) self.rotationSpeed=not (slideLeft or slideRight) and ( (turnLeft and self.avatarControlRotateSpeed) or (turnRight and -self.avatarControlRotateSpeed)) if self.speed and self.slideSpeed: self.speed *= GravityWalker.DiagonalFactor self.slideSpeed *= GravityWalker.DiagonalFactor debugRunning = inputState.isSet("debugRunning") if(debugRunning): self.speed*=base.debugRunningMultiplier self.slideSpeed*=base.debugRunningMultiplier self.rotationSpeed*=1.25 if self.needToDeltaPos: self.setPriorParentVector() self.needToDeltaPos = 0 if self.wantDebugIndicator: self.displayDebugInfo() if self.lifter.isOnGround(): if self.isAirborne: self.isAirborne = 0 assert self.debugPrint("isAirborne 0 due to isOnGround() true") impact = self.lifter.getImpactVelocity() if impact < -30.0: messenger.send("jumpHardLand") self.startJumpDelay(0.3) else: messenger.send("jumpLand") if impact < -5.0: self.startJumpDelay(0.2) # else, ignore the little potholes. assert self.isAirborne == 0 self.priorParent = Vec3.zero() if jump and self.mayJump: # The jump button is down and we're close # enough to the ground to jump. self.lifter.addVelocity(self.avatarControlJumpForce) messenger.send("jumpStart") self.isAirborne = 1 assert self.debugPrint("isAirborne 1 due to jump") else: if self.isAirborne == 0: assert self.debugPrint("isAirborne 1 due to isOnGround() false") self.isAirborne = 1 self.__oldPosDelta = self.avatarNodePath.getPosDelta(render) # How far did we move based on the amount of time elapsed? self.__oldDt = ClockObject.getGlobalClock().getDt() dt=self.__oldDt # Check to see if we're moving at all: self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero()) if self.moving: distance = dt * self.speed slideDistance = dt * self.slideSpeed rotation = dt * self.rotationSpeed # Take a step in the direction of our previous heading. if distance or slideDistance or self.priorParent != Vec3.zero(): # rotMat is the rotation matrix corresponding to # our previous heading. rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up()) if self.isAirborne: forward = Vec3.forward() else: contact = self.lifter.getContactNormal() forward = contact.cross(Vec3.right()) # Consider commenting out this normalize. If you do so # then going up and down slops is a touch slower and # steeper terrain can cut the movement in half. Without # the normalize the movement is slowed by the cosine of # the slope (i.e. it is multiplied by the sign as a # side effect of the cross product above). forward.normalize() self.vel=Vec3(forward * distance) if slideDistance: if self.isAirborne: right = Vec3.right() else: right = forward.cross(contact) # See note above for forward.normalize() right.normalize() self.vel=Vec3(self.vel + (right * slideDistance)) self.vel=Vec3(rotMat.xform(self.vel)) step=self.vel + (self.priorParent * dt) self.avatarNodePath.setFluidPos(Point3( self.avatarNodePath.getPos()+step)) self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation) else: self.vel.set(0.0, 0.0, 0.0) if self.moving or jump: messenger.send("avatarMoving") return Task.cont
def release(self): Gag.release(self) base.audio3d.attachSoundToObject(self.woosh, self.gag) base.playSfx(self.woosh, node=self.gag) if self.isLocal() and base.localAvatar.battleControls: if base.localAvatar.isFirstPerson(): # Add a small kick to the camera to give more feedback self.getFPSCam().addViewPunch( Vec3(random.uniform(.5, 1), random.uniform(-.5, -1), 0)) startPos = camera.getPos(render) + camera.getQuat( render).xform(Vec3.right()) push = 0.0 else: startPos = self.handJoint.getPos(render) push = (startPos - camera.getPos(render)).length() hitPos = PhysicsUtils.getHitPosFromCamera() else: startPos = self.handJoint.getPos(render) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) hitPos = quat.xform(Vec3.forward() * self.power) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, startPos, hitPos, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() throwDir = (hitPos - startPos).normalized() endPos = startPos + (throwDir * self.power) - (0, 0, 90) entity = self.gag if not entity: entity = self.build() gagRoot = render.attachNewNode('gagRoot') gagRoot.setPos(startPos) entity.reparentTo(render) entity.setPos(0, 0, 0) entity.headsUp(throwDir) rot = entity.getHpr(render) entity.reparentTo(gagRoot) entity.setHpr(rot[0], -90, 0) self.gag = None if not self.handJoint: self.handJoint = self.avatar.find('**/def_joint_right_hold') track = FlightProjectileInterval(gagRoot, startPos=startPos, endPos=endPos, gravityMult=1.07, duration=2.5) event = self.avatar.uniqueName('throwIvalDone') + '-' + str( hash(entity)) track.setDoneEvent(event) base.acceptOnce(event, self.__handlePieIvalDone, [entity]) track.start() if self.isLocal(): collider = self.buildCollisions(entity) self.entities.append([gagRoot, track, collider]) base.localAvatar.sendUpdate('usedGag', [self.id]) else: self.entities.append([gagRoot, track, NodePath()]) self.reset()
def __updateTask(self, task): # TODO -- This function does a lot of math, I measured it to take .5 ms on my laptop # That's a lot of time for something miniscule like sway and bob. dt = globalClock.getDt() time = globalClock.getFrameTime() if base.localAvatar.isFirstPerson(): eyePoint = base.localAvatar.getEyePoint() if base.localAvatar.walkControls.crouching: eyePoint[2] = eyePoint[2] / 2.0 eyePoint[2] = CIGlobals.lerpWithRatio(eyePoint[2], self.lastEyeHeight, 0.4) self.lastEyeHeight = eyePoint[2] camRootAngles = Vec3(0) # Mouse look around mw = base.mouseWatcherNode if mw.hasMouse(): md = base.win.getPointer(0) center = Point2(base.win.getXSize() / 2, base.win.getYSize() / 2) xDist = md.getX() - center.getX() yDist = md.getY() - center.getY() sens = self.__getMouseSensitivity() angular = -(xDist * sens) / dt base.localAvatar.walkControls.controller.setAngularMovement( angular) camRootAngles.setY(self.lastPitch - yDist * sens) if camRootAngles.getY() > FPSCamera.MaxP: camRootAngles.setY(FPSCamera.MaxP) yDist = 0 elif camRootAngles.getY() < FPSCamera.MinP: yDist = 0 camRootAngles.setY(FPSCamera.MinP) base.win.movePointer(0, int(center.getX()), int(center.getY())) if base.localAvatar.isFirstPerson(): # Camera / viewmodel bobbing vmBob = Point3(0) vmAngles = Vec3(0) vmRaise = Point3(0) camBob = Point3(0) maxSpeed = base.localAvatar.walkControls.BattleRunSpeed * 16.0 speed = base.localAvatar.walkControls.speeds.length() * 16.0 speed = max(-maxSpeed, min(maxSpeed, speed)) bobOffset = CIGlobals.remapVal(speed, 0, maxSpeed, 0.0, 1.0) self.bobTime += (time - self.lastBobTime) * bobOffset self.lastBobTime = time # Calculate the vertical bob cycle = self.bobTime - int( self.bobTime / self.BobCycleMax) * self.BobCycleMax cycle /= self.BobCycleMax if cycle < self.BobUp: cycle = math.pi * cycle / self.BobUp else: cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 - self.BobUp) verticalBob = speed * 0.005 verticalBob = verticalBob * 0.3 + verticalBob * 0.7 * math.sin( cycle) verticalBob = max(-7.0, min(4.0, verticalBob)) verticalBob /= 16.0 # Calculate the lateral bob cycle = self.bobTime - int( self.bobTime / self.BobCycleMax * 2) * self.BobCycleMax * 2 cycle /= self.BobCycleMax * 2 if cycle < self.BobUp: cycle = math.pi * cycle / self.BobUp else: cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 - self.BobUp) lateralBob = speed * 0.005 lateralBob = lateralBob * 0.3 + lateralBob * 0.7 * math.sin(cycle) lateralBob = max(-7.0, min(4.0, lateralBob)) lateralBob /= 16.0 # Apply bob, but scaled down a bit vmBob.set(lateralBob * 0.8, 0, verticalBob * 0.1) # Z bob a bit more vmBob[2] += verticalBob * 0.1 # Bob the angles vmAngles[2] += verticalBob * 0.5 vmAngles[1] -= verticalBob * 0.4 vmAngles[0] -= lateralBob * 0.3 # ================================================================ # Viewmodel lag/sway angles = self.camRoot.getHpr(render) quat = Quat() quat.setHpr(angles) invQuat = Quat() invQuat.invertFrom(quat) maxVMLag = 1.5 lagforward = quat.getForward() if dt != 0.0: lagdifference = lagforward - self.lastFacing lagspeed = 5.0 lagdiff = lagdifference.length() if (lagdiff > maxVMLag) and (maxVMLag > 0.0): lagscale = lagdiff / maxVMLag lagspeed *= lagscale self.lastFacing = CIGlobals.extrude(self.lastFacing, lagspeed * dt, lagdifference) self.lastFacing.normalize() lfLocal = invQuat.xform(lagdifference) vmBob = CIGlobals.extrude(vmBob, 5.0 / 16.0, lfLocal * -1.0) pitch = angles[1] if pitch > 180: pitch -= 360 elif pitch < -180: pitch += 360 vmBob = CIGlobals.extrude(vmBob, pitch * (0.035 / 16), Vec3.forward()) vmBob = CIGlobals.extrude(vmBob, pitch * (0.03 / 16), Vec3.right()) vmBob = CIGlobals.extrude(vmBob, pitch * (0.02 / 16), Vec3.up()) # ================================================================ vmRaise.set( 0, 0, 0 ) #(0, abs(camRootAngles.getY()) * -0.002, camRootAngles.getY() * 0.002) camBob.set(0, 0, 0) # Apply bob, raise, and sway to the viewmodel. self.viewModel.setPos(vmBob + vmRaise + self.lastVMPos) self.vmRoot2.setHpr(vmAngles) self.camRoot.setPos(eyePoint + camBob) newPitch = camRootAngles.getY() if abs(newPitch - self.lastPitch) > self.PitchUpdateEpsilon: # Broadcast where our head is looking head = base.localAvatar.getPart("head") if head and not head.isEmpty(): # Constrain the head pitch a little bit so it doesn't look like their head snapped headPitch = max(-47, newPitch) headPitch = min(75, headPitch) base.localAvatar.b_setLookPitch(headPitch) self.lastPitch = newPitch if base.localAvatar.isFirstPerson(): # Apply punch angle self.decayPunchAngle() camRootAngles += self.punchAngle self.camRoot.setHpr(camRootAngles) return task.cont
def moveRight(self): vp = base.viewportMgr.activeViewport if not vp or not vp.is2D(): return self.updatePos(self.pos + self.getMoveDelta(Vec3.right(), vp))