void CPhysicsObject::SetMass(float mass) { btVector3 btvec = m_pObject->getInvInertiaDiagLocal(); // Invert the inverse intertia to get inertia btvec.setX(SAFE_DIVIDE(1.0, btvec.x())); btvec.setY(SAFE_DIVIDE(1.0, btvec.y())); btvec.setZ(SAFE_DIVIDE(1.0, btvec.z())); m_pObject->setMassProps(mass, btvec); }
void CPhysicsObject::SetInertia(const Vector &inertia) { btVector3 btvec; ConvertDirectionToBull(inertia, btvec); btvec = btvec.absolute(); btvec.setX(SAFE_DIVIDE(1.0f, btvec.x())); btvec.setY(SAFE_DIVIDE(1.0f, btvec.y())); btvec.setZ(SAFE_DIVIDE(1.0f, btvec.z())); m_pObject->setInvInertiaDiagLocal(btvec); m_pObject->updateInertiaTensor(); }
void CShadowController::DetachObject() { btRigidBody* body = btRigidBody::upcast(m_pObject->GetObject()); btVector3 btvec = body->getInvInertiaDiagLocal(); btvec.setX(SAFE_DIVIDE(1.0, btvec.x())); btvec.setY(SAFE_DIVIDE(1.0, btvec.y())); btvec.setZ(SAFE_DIVIDE(1.0, btvec.z())); body->setMassProps(m_savedMass, btvec); m_pObject->SetMaterialIndex(m_savedMaterialIndex); body->setCollisionFlags(body->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); body->setActivationState(ACTIVE_TAG); }
Vector CPhysicsObject::GetInertia() const { btVector3 btvec = m_pObject->getInvInertiaDiagLocal(); // Invert the inverse inertia to get inertia btvec.setX(SAFE_DIVIDE(1.0f, btvec.x())); btvec.setY(SAFE_DIVIDE(1.0f, btvec.y())); btvec.setZ(SAFE_DIVIDE(1.0f, btvec.z())); Vector hlvec; ConvertDirectionToHL(btvec, hlvec); VectorAbs(hlvec, hlvec); return hlvec; }
void CPhysicsObject::SetMass(float mass) { if (IsStatic()) return; m_fMass = mass; btVector3 inertia = m_pObject->getInvInertiaDiagLocal(); // Inverse the inverse to get the not inverse (unless in the case that the not inverse is inverse, therefore you must inverse the universe) inertia.setX(SAFE_DIVIDE(1.0f, inertia.x())); inertia.setY(SAFE_DIVIDE(1.0f, inertia.y())); inertia.setZ(SAFE_DIVIDE(1.0f, inertia.z())); m_pObject->setMassProps(mass, inertia); }
void CPhysicsObject::SetMaterialIndex(int materialIndex) { surfacedata_t *pSurface = g_SurfaceDatabase.GetSurfaceData(materialIndex); if (pSurface) { m_materialIndex = materialIndex; m_pObject->setFriction(pSurface->physics.friction); //m_pObject->setRollingFriction(pSurface->physics.friction); m_pObject->setRestitution(min(pSurface->physics.elasticity, 1)); // FIXME: Figure out how to convert damping values. // ratio = (mass / volume) / density // or (actual density) / (prop density) m_fBuoyancyRatio = SAFE_DIVIDE(SAFE_DIVIDE(m_fMass, m_fVolume), pSurface->physics.density); } }
void CShadowController::DetachObject() { if (!m_pObject) return; btRigidBody *body = btRigidBody::upcast(m_pObject->GetObject()); btVector3 btvec = body->getInvInertiaDiagLocal(); btvec.setX(SAFE_DIVIDE(1.0f, btvec.x())); btvec.setY(SAFE_DIVIDE(1.0f, btvec.y())); btvec.setZ(SAFE_DIVIDE(1.0f, btvec.z())); body->setMassProps(m_savedMass, btvec); m_pObject->SetMaterialIndex(m_savedMaterialIndex); body->setActivationState(ACTIVE_TAG); m_pObject->DetachEventListener(this); m_pObject = NULL; }
void CShadowController::AttachObject() { btRigidBody* body = btRigidBody::upcast(m_pObject->GetObject()); m_savedMass = SAFE_DIVIDE(1, body->getInvMass()); m_savedMaterialIndex = m_pObject->GetMaterialIndex(); m_pObject->SetMaterialIndex(MATERIAL_INDEX_SHADOW); if ( !m_allowPhysicsMovement ) { m_pObject->SetMass(1e6f); m_pObject->EnableGravity(false); } body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); body->setActivationState(DISABLE_DEACTIVATION); }
void CShadowController::AttachObject() { if (!m_pObject) return; btRigidBody *body = btRigidBody::upcast(m_pObject->GetObject()); m_savedMass = SAFE_DIVIDE(1, body->getInvMass()); m_savedMaterialIndex = m_pObject->GetMaterialIndex(); m_pObject->SetMaterialIndex(MATERIAL_INDEX_SHADOW); if (!AllowsTranslation()) { m_pObject->SetMass(0); m_pObject->EnableGravity(false); } body->setActivationState(DISABLE_DEACTIVATION); m_pObject->AttachEventListener(this); }
void CPlayerController::CalculateVelocity(float dt) { btRigidBody *body = m_pObject->GetObject(); m_secondsToArrival -= dt; if (m_secondsToArrival < 0) m_secondsToArrival = 0; float psiScale = m_pEnv->GetInvPSIScale(); btTransform transform; ((btMassCenterMotionState *)body->getMotionState())->getGraphicTransform(transform); btVector3 deltaPos = m_targetPosition - transform.getOrigin(); ComputeController(m_linVelocity, deltaPos, m_maxSpeed, SAFE_DIVIDE(psiScale, dt), m_dampFactor); // Apply gravity velocity for stepping. /* if (m_onground) { btVector3 gravVel = body->getGravity() * dt; m_linVelocity += gravVel; } */ }
float CPhysicsObject::GetInvMass() const { return SAFE_DIVIDE(1, m_fMass); }
float CPhysicsObject::GetMass() const { btScalar invmass = m_pObject->getInvMass(); return SAFE_DIVIDE(1.0, invmass); }
float ComputeShadowControllerBull(btRigidBody *object, shadowcontrol_params_t ¶ms, float secondsToArrival, float dt) { // Fraction of the movement we need to complete by this tick float fraction = 1; if (secondsToArrival > 0) { fraction = dt / secondsToArrival; if (fraction > 1) fraction = 1; } secondsToArrival -= dt; if (secondsToArrival < 0) secondsToArrival = 0; if (fraction <= 0) return secondsToArrival; float scale = SAFE_DIVIDE(fraction, dt); btTransform transform = object->getWorldTransform(); transform *= ((btMassCenterMotionState *)object->getMotionState())->m_centerOfMassOffset.inverse(); //------------------- // Translation //------------------- btVector3 posbull = transform.getOrigin(); btVector3 delta_position = params.targetPosition - posbull; // Teleportation // If our distance is greater than teleport distance, teleport instead. if (params.teleportDistance > 0) { btScalar qdist; if (!params.lastPosition.isZero()) { btVector3 tmpDelta = posbull - params.lastPosition; qdist = tmpDelta.length2(); } else { qdist = delta_position.length2(); } if (qdist > params.teleportDistance * params.teleportDistance) { transform.setOrigin(params.targetPosition); transform.setRotation(params.targetRotation); object->setWorldTransform(transform * ((btMassCenterMotionState *)object->getMotionState())->m_centerOfMassOffset); } } btVector3 speed = object->getLinearVelocity(); ComputeController(speed, delta_position, btVector3(params.maxSpeed, params.maxSpeed, params.maxSpeed), scale, params.dampFactor); object->setLinearVelocity(speed); params.lastPosition = posbull + (speed * dt); //------------------- // Rotation //------------------- btVector3 axis; btScalar angle; btTransformUtil::calculateDiffAxisAngleQuaternion(transform.getRotation(), params.targetRotation, axis, angle); // So we don't end up having a huge delta angle (such as instead of doing 379 deg turn, do a -1 deg turn) if (angle > M_PI) { angle -= btScalar(2 * M_PI); } btVector3 deltaAngles = axis * angle; btVector3 rot_speed = object->getAngularVelocity(); ComputeController(rot_speed, deltaAngles, btVector3(params.maxAngular, params.maxAngular, params.maxAngular), scale, params.dampFactor); object->setAngularVelocity(rot_speed); object->activate(); return secondsToArrival; }