void PlayerPhysicsObject::handleInput(float delta) { std::vector<int> playerAttributes = itrPhysics_3.ownerAt(attributeIndex_)->getAttributes(ATTRIBUTE_PLAYER); if(playerAttributes.size() > 1) { ERROR_MESSAGEBOX("More than one controller for one player. Not tested.") } for(unsigned int i=0; i<playerAttributes.size(); i++) { AttributePtr<Attribute_Player> ptr_player = ptr_player = itrPlayer.at(playerAttributes.at(i)); AttributePtr<Attribute_Input> ptr_input = ptr_player->ptr_input; AttributePtr<Attribute_Health> health = ptr_player->ptr_health; if(health->health <= 0) { continue; } //-------------------------------------------------------------------------------------- //Look and move //-------------------------------------------------------------------------------------- yaw_ += ptr_input->rotation.x; btVector3 move = ptr_player->currentSpeed*btVector3(ptr_input->position.x, 0, ptr_input->position.y); //lower player speed when recently damaged if(ptr_player->timeSinceLastDamageTaken < 1.0f) { move *= 0.75f; } //Move player move = move.rotate(btVector3(0,1,0),yaw_); move = btVector3(move.x(), getLinearVelocity().y(), move.z()); setLinearVelocity(move); //Rotate player btTransform world; world = getWorldTransform(); world.setRotation(btQuaternion(yaw_,0,0)); setWorldTransform(world); //Jetpack if(ptr_player->jetpack) { float jetpackPower = -getGravity().y()*1.5f; world = getWorldTransform(); btVector3 velocity = getLinearVelocity(); if(world.getOrigin().y() < 18.0f) { setLinearVelocity(btVector3(move.x(), velocity.y()+jetpackPower*delta, move.z())); } } else if(ptr_input->jump && ptr_player->hovering) //Jump { float jumpPower = 600.0f; applyCentralImpulse(btVector3(0.0f, jumpPower, 0.0f)); //applyCentralForce(btVector3(0.0f, jumpPower, 0.0f)); } } }
void PlayerPhysicsObject::hover(float delta, float hoverHeight) { float deltaHeightMaximum = 0.0f; btVector3 offset[] = {btVector3( 0.15f, 0.0f, 0.15f), btVector3( 0.15f, 0.0f, -0.15f), btVector3(-0.15f, 0.0f, 0.15f), btVector3(-0.15f, 0.0f, -0.15f) }; for(unsigned int i=0; i<4; i++) { btVector3 from = btVector3(0.0f, 0.0f, 0.0f); btVector3 to = (from - btVector3(0.0f,hoverHeight*2.0f,0.0f)) + offset[i]; from += offset[i]; from += getWorldTransform().getOrigin(); to += getWorldTransform().getOrigin(); btQuaternion btqt = getWorldTransform().getRotation(); btCollisionWorld::ClosestRayResultCallback ray(from,to); ray.m_collisionFilterGroup = XKILL_Enums::PhysicsAttributeType::RAY; ray.m_collisionFilterMask = XKILL_Enums::PhysicsAttributeType::WORLD; dynamicsWorld_->rayTest(from,to,ray); //cast ray from player position straight down if(ray.hasHit()) { btVector3 point = from.lerp(to,ray.m_closestHitFraction); float length = (point - from).length(); float deltaHeight = hoverHeight-length; if(deltaHeight > deltaHeightMaximum) { deltaHeightMaximum = deltaHeight; } } debugDrawer_->drawLine(from, to, btVector3(0.2f, 1.0f, 0.2f)); } bool isHovering = false; if(deltaHeightMaximum > 0.0f) { btTransform worldTransform; worldTransform = getWorldTransform(); worldTransform.setOrigin(worldTransform.getOrigin() + btVector3(0.0f,deltaHeightMaximum,0.0f)*delta/0.25f); setWorldTransform(worldTransform); setLinearVelocity(getLinearVelocity()+btVector3(0.0f,-getLinearVelocity().y(),0.0f)); isHovering = true; } std::vector<int> playerAttributes = itrPhysics_3.ownerAt(attributeIndex_)->getAttributes(ATTRIBUTE_PLAYER); for(unsigned int i=0; i<playerAttributes.size(); i++) { AttributePtr<Attribute_Player> ptr_player = itrPlayer.at(playerAttributes.at(i)); ptr_player->hovering = isHovering; } }
void PhysicalPlayer::applyTurning(double amount) { if(!onGround) return; rigidBody->activate(); double constant = GET_SETTING("physics.constant.turn", 1.0); double centripetalConstant = GET_SETTING("physics.constant.centripetal", 1.0); //double leanConstant = GET_SETTING("physics.constant.lean", 1.0); Math::Matrix matrix = getTransformation(); Math::Point forwardAxis = matrix * Math::Point(0.0, 0.0, 1.0, 0.0); Math::Point centripetalAxis = matrix * Math::Point(-1.0, 0.0, 0.0, 0.0); forwardAxis.normalize(); centripetalAxis.normalize(); double speed = getLinearVelocity().length(); #if 0 // turn in the opposite direction when travelling backwards if (getLinearVelocity().dotProduct(forwardAxis) < 0) { speed = -speed; } #endif double speedFactor = GET_SETTING("physics.turning.speedfactor", 0.5); double speedThreshhold = GET_SETTING("physics.turning.speedthreshhold", 15.0); double falloffFactor = GET_SETTING("physics.turning.fallofffactor", 0.25); double turning_factor = GET_SETTING("physics.turning.constant", 1.0); if (speed <= speedThreshhold) { turning_factor += sqrt(speed/speedThreshhold)*(speed*speedFactor); } else { turning_factor += (speedThreshhold*speedFactor)*(1.0/(1.0+(speed-speedThreshhold)*falloffFactor)); } // turn in the opposite direction when travelling backwards if (getLinearVelocity().dotProduct(forwardAxis) < 0) { turning_factor = -turning_factor; } if(getSliding()) { centripetalConstant *= GET_SETTING("physics.slipstate.centripetalfactor", 1.0); constant *= GET_SETTING("physics.slipstate.turnfactor", 1.0); } applyForce(centripetalAxis * centripetalConstant * turning_factor * amount); applyTorque(-getUpDirection() * constant * turning_factor * amount); // twist the car in response to a sharp turn //applyTorque(getFrontDirection() * leanConstant * turning_factor * amount); updatePhysicalInfo(); }
void PhysicalPlayer::applyAcceleration(double acceleration) { if(!onGround) return; rigidBody->activate(); double constant = GET_SETTING("physics.constant.accel", 1.0); double brakeConstant = GET_SETTING("physics.constant.brake", 5.0); btTransform transform = rigidBody->getWorldTransform(); btMatrix3x3 matrix(transform.getRotation()); Math::Point orientation = Converter::toPoint(matrix * Converter::toVector(Math::Point(0.0, 0.0, 1.0) * constant)); //LOG(PHYSICS, "accel at " << Misc::Sleeper::getTimeMilliseconds()); if(getSliding()) { constant *= GET_SETTING("physics.slipstate.accelfactor", 1.0); } if (acceleration >= 0.0 || getLinearVelocity().dotProduct(orientation) < 0.0) { double paintInfluence = (speedBoost - 1.0) * GET_SETTING("game.paint.boostinfluence", 1.0) + 1.0; applyForce(orientation * constant * acceleration * paintInfluence * traction); } else { applyForce(orientation * brakeConstant * acceleration * traction); } updatePhysicalInfo(); }
glm::vec3 ObjectAction::getLinearVelocity() { auto rigidBody = getRigidBody(); if (!rigidBody) { return glm::vec3(0.0f); } return bulletToGLM(rigidBody->getLinearVelocity()); }
b2BodyDef Body::getBodyDef() { b2BodyDef bodyDef; if (!mBody) { // Default static properties bodyDef.type = static_cast<b2BodyType>(StaticBody); bodyDef.active = true; bodyDef.linearDamping = 0.0f; bodyDef.angularDamping = 0.0f; bodyDef.gravityScale = 1.0f; // Default dynamic properties bodyDef.linearVelocity = b2Vec2(0.0f, 0.0f); bodyDef.angularVelocity = 0.0f; } else { bodyDef.type = static_cast<b2BodyType>(getBodyType()); bodyDef.active = isActive(); bodyDef.linearDamping = getLinearDamping(); bodyDef.angularDamping = getAngularDamping(); bodyDef.gravityScale = getGravityScale(); bodyDef.linearVelocity = Box2dUtil::toB2Vec2(getLinearVelocity()); bodyDef.angularVelocity = getAngleInRadians(); } bodyDef.userData = this; return bodyDef; }
void PhysicsObject::writeNonSynchronizedPhysicsObjectDataToPhysicsAttribute() { AttributePtr<Attribute_Physics> ptr_physics = itrPhysics_.at(attributeIndex_); ptr_physics->angularVelocity = convert(&getAngularVelocity()); ptr_physics->collisionFilterGroup = getCollisionFilterGroup(); ptr_physics->collisionResponse = (getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE) == 0; ptr_physics->gravity = convert(&getGravity()); ptr_physics->linearVelocity = convert(&getLinearVelocity()); //ptr_physics->collisionFilterMask = //ptr_physics->mass = physicsObject->getInvMass(); //only mass inverse is stored in physics object //ptr_physics->meshID = //not stored in physics object }
void btRigidBody::setCenterOfMassTransform(const btTransform& xform) { if (isKinematicObject()) { m_interpolationWorldTransform = m_worldTransform; }else { m_interpolationWorldTransform = xform; } m_interpolationLinearVelocity = getLinearVelocity(); m_interpolationAngularVelocity = getAngularVelocity(); m_worldTransform = xform; updateInertiaTensor(); }
void PhysicsObject::hover(float delta, float hoverHeight) { btVector3 from = getWorldTransform().getOrigin(); btVector3 to = from - btVector3(0.0f,hoverHeight*2.0f,0.0f); btCollisionWorld::ClosestRayResultCallback ray(from,to); ray.m_collisionFilterGroup = XKILL_Enums::PhysicsAttributeType::RAY; ray.m_collisionFilterMask = XKILL_Enums::PhysicsAttributeType::WORLD; dynamicsWorld_->rayTest(from,to,ray); //cast ray from player position straight down if(ray.hasHit()) { btVector3 point = from.lerp(to,ray.m_closestHitFraction); float length = (point - from).length(); float something = hoverHeight-length; if(something > 0.0f) { btTransform worldTransform; worldTransform = getWorldTransform(); worldTransform.setOrigin(worldTransform.getOrigin() + btVector3(0.0f,something,0.0f)*delta/0.25f); setWorldTransform(worldTransform); setLinearVelocity(getLinearVelocity()+btVector3(0.0f,-getLinearVelocity().y(),0.0f)); } } }
void b3GpuPgsConstraintSolver::initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb) { solverBody->m_deltaLinearVelocity.setValue(0.f, 0.f, 0.f); solverBody->m_deltaAngularVelocity.setValue(0.f, 0.f, 0.f); solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); b3Assert(rb); // solverBody->m_worldTransform = getWorldTransform(rb); solverBody->internalSetInvMass(b3MakeVector3(rb->m_invMass, rb->m_invMass, rb->m_invMass)); solverBody->m_originalBodyIndex = bodyIndex; solverBody->m_angularFactor = b3MakeVector3(1, 1, 1); solverBody->m_linearFactor = b3MakeVector3(1, 1, 1); solverBody->m_linearVelocity = getLinearVelocity(rb); solverBody->m_angularVelocity = getAngularVelocity(rb); }
void btRigidBody::proceedToTransform(const btTransform& newTrans) { if (isKinematicObject()) { m_interpolationWorldTransform = m_worldTransform; } else { m_interpolationWorldTransform = newTrans; } m_interpolationLinearVelocity = getLinearVelocity(); m_interpolationAngularVelocity = getAngularVelocity(); m_worldTransform = newTrans; updateInertiaTensor(); }
void btRigidBody::internalWritebackVelocity(btScalar timeStep) { (void) timeStep; if (m_inverseMass) { setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity); setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity); //correct the position/orientation based on push/turn recovery btTransform newTransform; btTransformUtil::integrateTransform(getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform); setWorldTransform(newTransform); //m_originalBody->setCompanionId(-1); } // m_deltaLinearVelocity.setZero(); // m_deltaAngularVelocity .setZero(); // m_pushVelocity.setZero(); // m_turnVelocity.setZero(); }
//----------------------------------------------------------------------------// const PxTransform& MotionGenerator::update(float time, float dt) { float transformedTime = mAnimationSpeed * time; float transformedDt = mAnimationSpeed * dt; mTransform.p += mCenter; PxVec3 omega = transformedDt * getAngularVelocity(transformedTime); PxQuat qw = computeQuatFromAngularVelocity(omega); mTransform.q = qw * mTransform.q; mTransform.q.normalize(); mTransform.p -= mCenter; mTransform.p += transformedDt * getLinearVelocity(transformedTime); return mTransform; }
//============================================================================== void EndEffector::updateWorldJacobianClassicDeriv() const { const math::Jacobian& dJ_parent = mBodyNode->getJacobianClassicDeriv(); const math::Jacobian& J_parent = mBodyNode->getWorldJacobian(); const Eigen::Vector3d& v_local = getLinearVelocity(mBodyNode, Frame::World()); const Eigen::Vector3d& w_parent = mBodyNode->getAngularVelocity(); const Eigen::Vector3d& p = (getWorldTransform().translation() - mBodyNode->getWorldTransform().translation()).eval(); mWorldJacobianClassicDeriv = dJ_parent; mWorldJacobianClassicDeriv.bottomRows<3>().noalias() += J_parent.topRows<3>().colwise().cross(v_local + w_parent.cross(p)) + dJ_parent.topRows<3>().colwise().cross(p); mIsWorldJacobianClassicDerivDirty = false; }
void btRigidBody::setCenterOfMassTransform(const btTransform& xform) { btAssert(!std::isnan(xform.getOrigin().getX())); btAssert(!std::isnan(xform.getOrigin().getY())); btAssert(!std::isnan(xform.getOrigin().getZ())); btAssert(!std::isnan(xform.getRotation().getX())); btAssert(!std::isnan(xform.getRotation().getY())); btAssert(!std::isnan(xform.getRotation().getZ())); btAssert(!std::isnan(xform.getRotation().getW())); if (isStaticOrKinematicObject()) { m_interpolationWorldTransform = m_worldTransform; } else { m_interpolationWorldTransform = xform; } m_interpolationLinearVelocity = getLinearVelocity(); m_interpolationAngularVelocity = getAngularVelocity(); m_worldTransform = xform; updateInertiaTensor(); }
void RigidBody::_copyFrom(const ComponentBase *model) { init(); auto m = (RigidBody*)model; #ifdef EDITOR_ENABLED editorUpdate(); if (editorStruct) { editorStruct->copyDatas(m); editorStruct->refreshDatas(this); Link *link = entity.getLinkPtr(); if (isKinematic()) { auto p = posFromMat4(link->getGlobalTransform()); setPosition(posFromMat4(link->getGlobalTransform())); setRotation(link->getOrientation()); // global orientation not supported } } #else setAngularDrag(m->getAngularDrag()); setAngularVelocity(m->getAngularVelocity()); setCenterOfMass(m->getCenterOfMass()); setLinearDrag(m->getLinearDrag()); setLinearVelocity(m->getLinearVelocity()); setMass(m->getMass()); setDiagonalInertiaTensor(m->getDiagonalInertiaTensor()); setMaxAngularVelocity(m->getMaxAngularVelocity()); setMaxDepenetrationVelocity(m->getMaxDepenetrationVelocity()); affectByGravity(m->isAffectedByGravity()); setPosition(m->getPosition()); setRotation(m->getRotation()); setAsKinematic(m->isKinematic()); setCollisionDetectionMode(m->getCollisionDetectionMode()); #endif }
int PhysicObject::methodsBridge(lua_State* luaVM) { if (isCurrentMethod("applyImpulse")) { applyImpulse(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3)), CVector(lua_tonumber(luaVM, 4), lua_tonumber(luaVM, 5), lua_tonumber(luaVM, 6))); return 0; } if (isCurrentMethod("applyForce")) { applyForce(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3)), CVector(lua_tonumber(luaVM, 4), lua_tonumber(luaVM, 5), lua_tonumber(luaVM, 6))); return 0; } if (isCurrentMethod("setLinearVelocity")) { setLinearVelocity(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getLinearVelocity")) { luaPushVector(luaVM, getLinearVelocity().x, getLinearVelocity().y, getLinearVelocity().z); return 1; } if (isCurrentMethod("setMass")) { setMass(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getMass")) { lua_pushnumber(luaVM, getMass()); return 1; } if (isCurrentMethod("setCollisionShapeType")) { setCollisionShapeType((CollisionShapeType)lua_tointeger(luaVM, 1)); return 0; } if (isCurrentMethod("getCollisionShapeType")) { lua_pushinteger(luaVM, getCollisionShapeType()); return 1; } if (isCurrentMethod("enablePhysics")) { enablePhysics(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isEnabledPhysics")) { lua_pushboolean(luaVM, isEnabledPhysics()); return 1; } if (isCurrentMethod("setAngularFactor")) { setAngularFactor(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getAngularFactor")) { luaPushVector(luaVM, getAngularFactor().x, getAngularFactor().y, getAngularFactor().z); return 1; } if (isCurrentMethod("setLinearFactor")) { setLinearFactor(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getLinearFactor")) { luaPushVector(luaVM, getLinearFactor().x, getLinearFactor().y, getLinearFactor().z); return 1; } if (isCurrentMethod("setTrigger")) { setTrigger(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isTrigger")) { lua_pushboolean(luaVM, isTrigger()); return 1; } if (isCurrentMethod("getCollisionShape")) { if (getCollisionShape() == NULL) { lua_pushnil(luaVM); } else { lua_getglobal(luaVM, getCollisionShape()->getGOID().c_str()); } return 1; } if (isCurrentMethod("setCollisionShape")) { if (lua_isnil(luaVM, 1)) { setCollisionShape(NULL); return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOCollisionShape* o = (GOCollisionShape*)lua_tointeger(luaVM, -1); setCollisionShape(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("setEnableDeactivation")) { setEnableDeactivation(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isEnableDeactivation")) { lua_pushboolean(luaVM, isEnableDeactivation()); return 1; } if (isCurrentMethod("setFriction")) { setFriction(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getFriction")) { lua_pushnumber(luaVM, getFriction()); return 1; } if (isCurrentMethod("setRestitution")) { setRestitution(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getRestitution")) { lua_pushnumber(luaVM, getRestitution()); return 1; } if (isCurrentMethod("setLinearDumping")) { setLinearDumping(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getLinearDumping")) { lua_pushnumber(luaVM, getLinearDumping()); return 1; } if (isCurrentMethod("setAngularDumping")) { setAngularDumping(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getAngularDumping")) { lua_pushnumber(luaVM, getAngularDumping()); return 1; } if (isCurrentMethod("setAngularVelocity")) { setAngularVelocity(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getAngularVelocity")) { CVector av = getAngularVelocity(); luaPushVector(luaVM, av.x, av.y, av.z); return 1; } if (isCurrentMethod("addConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); addConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("getConstraints")) { lua_newtable(luaVM); int tableIndex = lua_gettop(luaVM); vector<GOConstraint*> objs; for (unsigned int i = 0; i < constraints.size(); ++i) { if (constraints.at(i)->id == "undefined" || constraints.at(i)->id == "") continue; objs.push_back(constraints.at(i)); } for (unsigned int i = 0; i < objs.size(); ++i) { lua_pushinteger(luaVM, i+1); lua_getglobal(luaVM, objs.at(i)->id.c_str()); lua_settable (luaVM, tableIndex); } return 1; } if (isCurrentMethod("removeConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); removeConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("removeAllConstrains")) { removeAllConstraints(); return 0; } if (isCurrentMethod("secondObjectForConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); secondObjectForConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("isSecondObjectForConstraints")) { lua_newtable(luaVM); int tableIndex = lua_gettop(luaVM); vector<GOConstraint*> objs; for (unsigned int i = 0; i < secondObjectForConstraints.size(); ++i) { if (secondObjectForConstraints.at(i)->id == "undefined" || secondObjectForConstraints.at(i)->id == "") continue; objs.push_back(secondObjectForConstraints.at(i)); } for (unsigned int i = 0; i < objs.size(); ++i) { lua_pushinteger(luaVM, i+1); lua_getglobal(luaVM, objs.at(i)->id.c_str()); lua_settable (luaVM, tableIndex); } return 1; } if (isCurrentMethod("notUseAsSecondObjectForConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); notUseAsSecondObjectForConstraint(o); lua_pop(luaVM, -1); return 0; } return LuaBridge::methodsBridge(luaVM); }
void Player::updateAnimation(SimTime t) { viewThread->SetSequence(crouching ? crouchLooksSequence : looksSequence); if (viewThread) { float pos = 0.5 + (-viewPitch / MaxPitch) * 0.5; if(viewThread->getPosition() != pos) viewThread->SetPosition(pos); } if(!myThread) return; float curPos = myThread->getPosition(); int newAnimation; // = -1; bool done = (data->animData[currentAnimation].direction > 0 ? curPos >= 0.99 : curPos <= 0.01 ); bool interruptable = done || myThread->getSequence().fCyclic; if(!isGhost()) { if (dead) { if(!done) myThread->AdvanceTime(t); } else { if (done) { serverAnimation = -1; currentAnimation = -1; } if(serverAnimation != -1) myThread->AdvanceTime(t); else { int newAnimation = ANIM_IDLE; if(crouching && !jetting && !falling && !mount && !dead) newAnimation = ANIM_CROUCH_IDLE; if(newAnimation != currentAnimation) { currentAnimation = newAnimation; myThread->SetSequence(animIndex[newAnimation]); myThread->SetPosition(newAnimation == ANIM_CROUCH_IDLE ? 1 : 0); } } } int flags = data->animData[currentAnimation].viewFlags; if (flags & AnimData::FirstPerson) { image.shape->setOverride(2); viewThread->setPriority(-1); } else { image.shape->setOverride(0); viewThread->setPriority(5000); } clearAnimTransform (); image.shape->animate(); return; } float time = t; if(transitionTime != 0) { if(transitionTime > time) { myThread->AdvanceTime(time); transitionTime -= time; time = 0; } else { myThread->AdvanceTime(transitionTime); time -= transitionTime; transitionTime = 0; } } if(time != 0) { if(!pickNewAnimation) // check for current animation done pickNewAnimation = interruptable && !dead; newAnimation = pickAnimation(); if (data->animData[currentAnimation].priority < data->animData[newAnimation].priority) pickNewAnimation = true; bool hasPriority = currentAnimation != -1 && data->animData[currentAnimation].priority > data->animData[newAnimation].priority; bool holdPose = data->animData[currentAnimation].viewFlags & AnimData::HoldPose; bool priorityOverride = hasPriority && (!interruptable || holdPose); if(!pickNewAnimation || newAnimation == currentAnimation || priorityOverride) { if(offsetList[currentAnimation].hasOffset) { // rotate velocity into player's coordinate system: Point3F relVel; m_mul( getLinearVelocity(), getInvRotation(), &relVel); float lspeed = m_dot(relVel, offsetList[currentAnimation].dir); // anim travels offsetList.dist in 1 second // we want to slow/speed it by (lspeed / animspeed) * time; // only play if we were on the ground recently if(lastContactCount < 8) { float speedRatio = lspeed / offsetList[currentAnimation].dist; if(speedRatio < 0.66) speedRatio = 0.66f; else if(speedRatio > 1.5) speedRatio = 1.5; myThread->AdvanceTime( float(time) * speedRatio * data->animData[currentAnimation].direction); } else { if(gAnimateTransitions) { float curPos = myThread->getPosition(); if(curPos > 0.1) { playerTransition.fStartSequence = animIndex[currentAnimation]; playerTransition.fEndSequence = animIndex[currentAnimation]; playerTransition.fStartPosition = curPos; playerTransition.fEndPosition = 0; playerTransition.fDuration = 0.045; transitionTime = 0.04; if(!myThread->SetTransition(&playerTransition)) { myThread->SetSequence(animIndex[currentAnimation]); myThread->SetPosition(0); } else myThread->AdvanceTime(0.005); } } else myThread->SetPosition(0); } } else myThread->AdvanceTime( float(time) * data->animData[currentAnimation].direction); if(pickNewAnimation && done && !myThread->getSequence().fCyclic) myThread->SetPosition (data->animData[currentAnimation].direction > 0 ? 1.0 : 0.0); } else { // got a new animation // make a transition: float endpos; if (data->animData[newAnimation].direction > 0 && newAnimation != ANIM_CROUCH_IDLE) endpos = 0.01; else endpos = 0.99; if(gAnimateTransitions) { playerTransition.fStartSequence = animIndex[currentAnimation]; playerTransition.fEndSequence = animIndex[newAnimation]; playerTransition.fStartPosition = myThread->getPosition() + 0.01; playerTransition.fEndPosition = endpos; playerTransition.fDuration = 0.12; transitionTime = 0.13; currentAnimation = newAnimation; if(!myThread->SetTransition(&playerTransition)) { currentAnimation = newAnimation; myThread->SetSequence(animIndex[currentAnimation]); myThread->SetPosition(endpos); } else myThread->AdvanceTime(0.01); // FIXME! no crouch root animation } else { currentAnimation = newAnimation; myThread->SetSequence(animIndex[currentAnimation]); myThread->SetPosition(endpos); } } } myThread->UpdateSubscriberList (); // update the jet flame animation here if(flameThread) { if(currentAnimation == ANIM_JET && jetting) flameThread->AdvanceTime(t); else flameThread->SetPosition(0.0); } updateShieldThread (t); if(image.shape) { if (viewThread) { int flags = data->animData[currentAnimation].viewFlags; if (isFirstPersonView()) { if (flags & AnimData::FirstPerson) { image.shape->setOverride(2); viewThread->setPriority(-1); } else { image.shape->setOverride(0); viewThread->setPriority(5000); } } else { if (cg.psc->getControlObject() == this) { // Chase cam view if (flags & AnimData::ChaseCam) { image.shape->setOverride(1); viewThread->setPriority(-1); } else { image.shape->setOverride(0); viewThread->setPriority(5000); } } else { if (flags & AnimData::ThirdPerson) { image.shape->setOverride(1); viewThread->setPriority(-1); } else { image.shape->setOverride(0); viewThread->setPriority(5000); } } } } if (cg.player == this) { clearAnimTransform (); image.shape->animate(); } } }
b3Vector3 getVelocityInLocalPoint(b3RigidBodyData* rb, const b3Vector3& rel_pos) { //we also calculate lin/ang velocity for kinematic objects return getLinearVelocity(rb) + getAngularVelocity(rb).cross(rel_pos); }
int Player::pickAnimation() { if (newAnimTime > wg->currentTime) return currentAnimation; newAnimTime = wg->currentTime + 65; // death forces the player animation to an appropriate one if(dead) return currentAnimation; if (mount) { if (mountPoint == 1) return mount->getMountPose(); else return ANIM_APC_RIDE; } if(jetting || (lastPlayerMove.jetting && !didContact())) return ANIM_JET; if(falling) return ANIM_FALL; if (!crouching && pdaing || (!getControlClient() && !mount && !aiControlled)) return ANIM_PDA; // not one of the instant picks... so lets see which one it is // rotate the velocity vector into object space: Point3F relVel; m_mul( getLinearVelocity(), getInvRotation(), &relVel); float curMax = 0.35f; // check for moves: if(crouching) { int animPick = ANIM_CROUCH_IDLE; for(int i = ANIM_CROUCH_MOVE_FIRST; i <= ANIM_CROUCH_MOVE_LAST; i++) { if(offsetList[i].hasOffset) { float vel = m_dot(relVel, offsetList[i].dir); if(vel > curMax) { curMax = vel; animPick = i; } } } return animPick; } else { int animPick = ANIM_IDLE; for(int i = ANIM_MOVE_FIRST; i <= ANIM_MOVE_LAST; i++) { if(offsetList[i].hasOffset) { float vel = m_dot(relVel, offsetList[i].dir); if(vel > curMax) { curMax = vel; animPick = i; } } } return animPick; } }