mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
from marauder: sleep threshold work
This commit is contained in:
parent
d5a111e9ff
commit
a0bd5dd426
2 changed files with 88 additions and 14 deletions
|
|
@ -46,6 +46,11 @@ Rigid::Rigid()
|
||||||
restitution = 0.3f;
|
restitution = 0.3f;
|
||||||
friction = 0.5f;
|
friction = 0.5f;
|
||||||
atRest = false;
|
atRest = false;
|
||||||
|
|
||||||
|
sleepLinearThreshold = 0.0004f;
|
||||||
|
sleepAngThreshold = 0.0004f;
|
||||||
|
sleepTimeThreshold = 0.75f;
|
||||||
|
sleepTimer = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rigid::clearForces()
|
void Rigid::clearForces()
|
||||||
|
|
@ -57,9 +62,18 @@ void Rigid::clearForces()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Rigid::integrate(F32 delta)
|
void Rigid::integrate(F32 delta)
|
||||||
{
|
{
|
||||||
// Update Angular position
|
if (atRest && force.isZero() && torque.isZero())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 1. advance momentum
|
||||||
|
angMomentum += torque * delta;
|
||||||
|
linMomentum += force * delta;
|
||||||
|
linVelocity = linMomentum * oneOverMass;
|
||||||
|
|
||||||
|
// 2. advance orientation if ang vel significant
|
||||||
F32 angle = angVelocity.len();
|
F32 angle = angVelocity.len();
|
||||||
if (angle != 0.0f) {
|
if (mFabs(angle)> POINT_EPSILON)
|
||||||
|
{
|
||||||
QuatF dq;
|
QuatF dq;
|
||||||
F32 sinHalfAngle;
|
F32 sinHalfAngle;
|
||||||
mSinCos(angle * delta * -0.5f, sinHalfAngle, dq.w);
|
mSinCos(angle * delta * -0.5f, sinHalfAngle, dq.w);
|
||||||
|
|
@ -73,22 +87,29 @@ void Rigid::integrate(F32 delta)
|
||||||
|
|
||||||
// Rotate the position around the center of mass
|
// Rotate the position around the center of mass
|
||||||
Point3F lp = linPosition - worldCenterOfMass;
|
Point3F lp = linPosition - worldCenterOfMass;
|
||||||
dq.mulP(lp,&linPosition);
|
dq.mulP(lp, &linPosition);
|
||||||
linPosition += worldCenterOfMass;
|
linPosition += worldCenterOfMass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update angular momentum
|
// 3. advance position
|
||||||
angMomentum = angMomentum + torque * delta;
|
linPosition += linVelocity * delta;
|
||||||
|
|
||||||
// Update linear position, momentum
|
// 4. rebuild world inertia
|
||||||
linPosition = linPosition + linVelocity * delta;
|
if (mFabs(angle) > POINT_EPSILON)
|
||||||
linMomentum = linMomentum + force * delta;
|
{
|
||||||
linVelocity = linMomentum * oneOverMass;
|
updateInertialTensor();
|
||||||
|
}
|
||||||
|
|
||||||
// Update dependent state variables
|
// 5. refresh ang velocity
|
||||||
updateInertialTensor();
|
updateAngularVelocity();
|
||||||
updateVelocity();
|
|
||||||
|
|
||||||
|
// 6. CoM update
|
||||||
updateCenterOfMass();
|
updateCenterOfMass();
|
||||||
|
|
||||||
|
// 7. check if we can sleep
|
||||||
|
trySleep(delta);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rigid::updateVelocity()
|
void Rigid::updateVelocity()
|
||||||
|
|
@ -118,7 +139,7 @@ void Rigid::updateCenterOfMass()
|
||||||
void Rigid::applyImpulse(const Point3F &r, const Point3F &impulse)
|
void Rigid::applyImpulse(const Point3F &r, const Point3F &impulse)
|
||||||
{
|
{
|
||||||
if (impulse.lenSquared() < mass) return;
|
if (impulse.lenSquared() < mass) return;
|
||||||
atRest = false;
|
wake();
|
||||||
|
|
||||||
// Linear momentum and velocity
|
// Linear momentum and velocity
|
||||||
linMomentum += impulse;
|
linMomentum += impulse;
|
||||||
|
|
@ -278,6 +299,47 @@ void Rigid::translateCenterOfMass(const Point3F &oldPos,const Point3F &newPos)
|
||||||
objectInertia(2,1) = objectInertia(1,2);
|
objectInertia(2,1) = objectInertia(1,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rigid::trySleep(F32 dt)
|
||||||
|
{
|
||||||
|
// If there is active force/torque, don’t sleep
|
||||||
|
if (!force.isZero() || !torque.isZero())
|
||||||
|
{
|
||||||
|
sleepTimer = 0.0f; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const F32 linV2 = linVelocity.lenSquared();
|
||||||
|
const F32 angV2 = angVelocity.lenSquared();
|
||||||
|
|
||||||
|
if (linV2 < sleepLinearThreshold && angV2 < sleepAngThreshold)
|
||||||
|
{
|
||||||
|
sleepTimer += dt;
|
||||||
|
if (sleepTimer >= sleepTimeThreshold)
|
||||||
|
{
|
||||||
|
setAtRest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sleepTimer = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rigid::setSleepThresholds(F32 linVel2, F32 angVel2, F32 timeToSleep)
|
||||||
|
{
|
||||||
|
sleepLinearThreshold = linVel2;
|
||||||
|
sleepAngThreshold = angVel2;
|
||||||
|
sleepTimeThreshold = timeToSleep;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rigid::wake()
|
||||||
|
{
|
||||||
|
if (atRest)
|
||||||
|
{
|
||||||
|
atRest = false;
|
||||||
|
sleepTimer = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Rigid::getVelocity(const Point3F& r, Point3F* v)
|
void Rigid::getVelocity(const Point3F& r, Point3F* v)
|
||||||
{
|
{
|
||||||
mCross(angVelocity, r, v);
|
mCross(angVelocity, r, v);
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,18 @@ public:
|
||||||
F32 oneOverMass; ///< 1 / mass
|
F32 oneOverMass; ///< 1 / mass
|
||||||
F32 restitution; ///< Collision restitution
|
F32 restitution; ///< Collision restitution
|
||||||
F32 friction; ///< Friction coefficient
|
F32 friction; ///< Friction coefficient
|
||||||
|
|
||||||
|
// sleep threshold parameters
|
||||||
|
F32 sleepLinearThreshold; ///< M/S ^ 2
|
||||||
|
F32 sleepAngThreshold; ///< R/S ^ 2
|
||||||
|
F32 sleepTimeThreshold; ///< Seconds
|
||||||
|
F32 sleepTimer;
|
||||||
|
|
||||||
bool atRest;
|
bool atRest;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void translateCenterOfMass(const Point3F &oldPos,const Point3F &newPos);
|
void translateCenterOfMass(const Point3F &oldPos,const Point3F &newPos);
|
||||||
|
void trySleep(F32 dt);
|
||||||
public:
|
public:
|
||||||
//
|
//
|
||||||
Rigid();
|
Rigid();
|
||||||
|
|
@ -94,6 +101,11 @@ public:
|
||||||
|
|
||||||
bool checkRestCondition();
|
bool checkRestCondition();
|
||||||
void setAtRest();
|
void setAtRest();
|
||||||
|
|
||||||
|
//
|
||||||
|
void setSleepThresholds(F32 linVel2, F32 angVel2, F32 timeToSleep);
|
||||||
|
void wake();
|
||||||
|
TORQUE_FORCEINLINE void updateAngularVelocity() { invWorldInertia.mulV(angMomentum, &angVelocity); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue