mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 09:04:38 +00:00
commit
d8102a9591
5 changed files with 42 additions and 70 deletions
|
|
@ -156,7 +156,7 @@ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal, Rigid* rig
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Compute impulse
|
// Compute impulse
|
||||||
F32 d, n = -nv * (2.0f + restitution * rigid->restitution);
|
F32 d, n = -nv * (1.0+(restitution + rigid->restitution)*0.5);
|
||||||
Point3F a1,b1,c1;
|
Point3F a1,b1,c1;
|
||||||
mCross(r1,normal,&a1);
|
mCross(r1,normal,&a1);
|
||||||
invWorldInertia.mulV(a1,&b1);
|
invWorldInertia.mulV(a1,&b1);
|
||||||
|
|
|
||||||
|
|
@ -900,9 +900,11 @@ bool RigidShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||||
mRigid.restitution = mDataBlock->body.restitution;
|
mRigid.restitution = mDataBlock->body.restitution;
|
||||||
mRigid.setCenterOfMass(mDataBlock->massCenter);
|
mRigid.setCenterOfMass(mDataBlock->massCenter);
|
||||||
|
|
||||||
// Ignores massBox, just set sphere for now. Derived objects
|
// Set inertial tensor, default for the RigidShape is sphere
|
||||||
// can set what they want.
|
if (mDataBlock->massBox.x > 0 && mDataBlock->massBox.y > 0 && mDataBlock->massBox.z > 0)
|
||||||
mRigid.setObjectInertia();
|
mRigid.setObjectInertia(mDataBlock->massBox);
|
||||||
|
else
|
||||||
|
mRigid.setObjectInertia(mObjBox.maxExtents - mObjBox.minExtents);
|
||||||
|
|
||||||
scriptOnNewDataBlock();
|
scriptOnNewDataBlock();
|
||||||
|
|
||||||
|
|
@ -1115,9 +1117,9 @@ void RigidShape::updatePos(F32 dt)
|
||||||
if (mCollisionList.getCount())
|
if (mCollisionList.getCount())
|
||||||
{
|
{
|
||||||
F32 k = mRigid.getKineticEnergy();
|
F32 k = mRigid.getKineticEnergy();
|
||||||
F32 G = mNetGravity * dt;
|
F32 G = mNetGravity;
|
||||||
F32 Kg = 0.5 * mRigid.mass * G * G;
|
F32 Kg = 0.5 * mRigid.mass * G * G;
|
||||||
if (k < sRestTol * Kg && ++restCount > sRestCount)
|
if (k < sRestTol * Kg* dt && ++restCount > sRestCount)
|
||||||
mRigid.setAtRest();
|
mRigid.setAtRest();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1205,8 +1207,12 @@ void RigidShape::updatePos(F32 dt)
|
||||||
|
|
||||||
void RigidShape::updateForces(F32 dt)
|
void RigidShape::updateForces(F32 dt)
|
||||||
{
|
{
|
||||||
if (mDisableMove) return;
|
if (mDisableMove)
|
||||||
|
{
|
||||||
|
mRigid.linVelocity = Point3F::Zero;
|
||||||
|
mRigid.angMomentum = Point3F::Zero;
|
||||||
|
return;
|
||||||
|
}
|
||||||
Point3F torque(0, 0, 0);
|
Point3F torque(0, 0, 0);
|
||||||
Point3F force(0, 0, mRigid.mass * mNetGravity);
|
Point3F force(0, 0, mRigid.mass * mNetGravity);
|
||||||
|
|
||||||
|
|
@ -1222,10 +1228,6 @@ void RigidShape::updateForces(F32 dt)
|
||||||
|
|
||||||
mRigid.force = force;
|
mRigid.force = force;
|
||||||
mRigid.torque = torque;
|
mRigid.torque = torque;
|
||||||
|
|
||||||
// If we're still atRest, make sure we're not accumulating anything
|
|
||||||
if ((force.lenSquared() < mDataBlock->contactTol)&& (force.lenSquared() < mDataBlock->contactTol))
|
|
||||||
mRigid.setAtRest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1260,8 +1262,7 @@ bool RigidShape::updateCollision(F32 dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve collisions
|
// Resolve collisions
|
||||||
bool collided = resolveCollision(mRigid,mCollisionList);
|
bool collided = resolveCollision(mRigid,mCollisionList, dt);
|
||||||
resolveContacts(mRigid,mCollisionList,dt);
|
|
||||||
return collided;
|
return collided;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1271,7 +1272,7 @@ bool RigidShape::updateCollision(F32 dt)
|
||||||
Handle collision impacts, as opposed to contacts. Impulses are calculated based
|
Handle collision impacts, as opposed to contacts. Impulses are calculated based
|
||||||
on standard collision resolution formulas.
|
on standard collision resolution formulas.
|
||||||
*/
|
*/
|
||||||
bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList, F32 dt)
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(RigidShape_resolveCollision);
|
PROFILE_SCOPE(RigidShape_resolveCollision);
|
||||||
// Apply impulses to resolve collision
|
// Apply impulses to resolve collision
|
||||||
|
|
@ -1279,6 +1280,11 @@ bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
||||||
for (S32 i = 0; i < cList.getCount(); i++)
|
for (S32 i = 0; i < cList.getCount(); i++)
|
||||||
{
|
{
|
||||||
Collision& c = cList[i];
|
Collision& c = cList[i];
|
||||||
|
if (c.object == this)
|
||||||
|
{
|
||||||
|
//Con::printf("IMPOSSIBLE!!!!--------------------------------> Self-collision event?");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (c.distance < mDataBlock->collisionTol)
|
if (c.distance < mDataBlock->collisionTol)
|
||||||
{
|
{
|
||||||
// Velocity into surface
|
// Velocity into surface
|
||||||
|
|
@ -1288,9 +1294,7 @@ bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
||||||
F32 vn = mDot(v, c.normal);
|
F32 vn = mDot(v, c.normal);
|
||||||
|
|
||||||
// Only interested in velocities greater than sContactTol,
|
// Only interested in velocities greater than sContactTol,
|
||||||
// velocities less than that will be dealt with as contacts
|
if (mFabs(vn) > mDataBlock->contactTol)
|
||||||
// "constraints".
|
|
||||||
if (vn < -mDataBlock->contactTol)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// Apply impulses to the rigid body to keep it from
|
// Apply impulses to the rigid body to keep it from
|
||||||
|
|
@ -1313,45 +1317,15 @@ bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
||||||
queueCollision(col, v - col->getVelocity());
|
queueCollision(col, v - col->getVelocity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// velocities less than that will be dealt with as contacts
|
||||||
}
|
// "constraints".
|
||||||
|
else
|
||||||
return collided;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Resolve contact forces
|
|
||||||
Resolve contact forces using the "penalty" method. Forces are generated based
|
|
||||||
on the depth of penetration and the moment of inertia at the point of contact.
|
|
||||||
*/
|
|
||||||
bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE(RigidShape_resolveContacts);
|
|
||||||
// Use spring forces to manage contact constraints.
|
|
||||||
bool collided = false;
|
|
||||||
Point3F t,p(0,0,0),l(0,0,0);
|
|
||||||
for (S32 i = 0; i < cList.getCount(); i++)
|
|
||||||
{
|
|
||||||
const Collision& c = cList[i];
|
|
||||||
if (c.distance < mDataBlock->collisionTol)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Velocity into the surface
|
|
||||||
Point3F v,r;
|
|
||||||
ns.getOriginVector(c.point,&r);
|
|
||||||
ns.getVelocity(r,&v);
|
|
||||||
F32 vn = mDot(v,c.normal);
|
|
||||||
|
|
||||||
// Only interested in velocities less than mDataBlock->contactTol,
|
|
||||||
// velocities greater than that are dealt with as collisions.
|
|
||||||
if (mFabs(vn) < mDataBlock->contactTol)
|
|
||||||
{
|
{
|
||||||
collided = true;
|
Point3F t;
|
||||||
|
|
||||||
// Penetration force. This is actually a spring which
|
// Penetration force. This is actually a spring which
|
||||||
// will seperate the body from the collision surface.
|
// will seperate the body from the collision surface.
|
||||||
F32 zi = 2 * mFabs(mRigid.getZeroImpulse(r,c.normal));
|
F32 zi = 2 * mFabs(mRigid.getZeroImpulse(r, c.normal) / dt);
|
||||||
F32 s = (mDataBlock->collisionTol - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
|
F32 s = mMax((mDataBlock->collisionTol - c.distance) * zi - ((vn / 2.0) * zi),0.0f);
|
||||||
Point3F f = c.normal * s;
|
Point3F f = c.normal * s;
|
||||||
|
|
||||||
// Friction impulse, calculated as a function of the
|
// Friction impulse, calculated as a function of the
|
||||||
|
|
@ -1362,7 +1336,7 @@ bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
|
||||||
if (s > 0 && ul)
|
if (s > 0 && ul)
|
||||||
{
|
{
|
||||||
uv /= -ul;
|
uv /= -ul;
|
||||||
F32 u = ul * ns.getZeroImpulse(r,uv);
|
F32 u = ul * ns.getZeroImpulse(r, uv) / dt;
|
||||||
s *= mRigid.friction;
|
s *= mRigid.friction;
|
||||||
if (u > s)
|
if (u > s)
|
||||||
u = s;
|
u = s;
|
||||||
|
|
@ -1370,20 +1344,17 @@ bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate forces
|
// Accumulate forces
|
||||||
p += f;
|
mCross(r, f, &t);
|
||||||
mCross(r,f,&t);
|
ns.linMomentum += f * dt;
|
||||||
l += t;
|
ns.angMomentum += t * dt;
|
||||||
|
ns.updateVelocity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contact constraint forces act over time...
|
|
||||||
ns.linMomentum += p * dt;
|
|
||||||
ns.angMomentum += l * dt;
|
|
||||||
ns.updateVelocity();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return collided;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -1693,6 +1664,8 @@ void RigidShape::initPersistFields()
|
||||||
docsURL;
|
docsURL;
|
||||||
addField("disableMove", TypeBool, Offset(mDisableMove, RigidShape),
|
addField("disableMove", TypeBool, Offset(mDisableMove, RigidShape),
|
||||||
"When this flag is set, the vehicle will ignore throttle changes.");
|
"When this flag is set, the vehicle will ignore throttle changes.");
|
||||||
|
addField("isAtRest", TypeBool, Offset(mRigid.atRest, RigidShape),
|
||||||
|
"Debug read of the rest state. do not set");
|
||||||
Parent::initPersistFields();
|
Parent::initPersistFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,7 @@ class RigidShape: public ShapeBase
|
||||||
bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
||||||
void updatePos(F32 dt);
|
void updatePos(F32 dt);
|
||||||
bool updateCollision(F32 dt);
|
bool updateCollision(F32 dt);
|
||||||
bool resolveCollision(Rigid& ns,CollisionList& cList);
|
bool resolveCollision(Rigid& ns,CollisionList& cList, F32 dt);
|
||||||
bool resolveContacts(Rigid& ns,CollisionList& cList,F32 dt);
|
|
||||||
bool resolveDisplacement(Rigid& ns,CollisionState *state,F32 dt);
|
bool resolveDisplacement(Rigid& ns,CollisionState *state,F32 dt);
|
||||||
void checkTriggers();
|
void checkTriggers();
|
||||||
static void findCallback(SceneObject* obj,void * key);
|
static void findCallback(SceneObject* obj,void * key);
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class SFXProfile;
|
||||||
|
|
||||||
typedef void* Light;
|
typedef void* Light;
|
||||||
|
|
||||||
const F32 gGravity = -20;
|
const F32 gGravity = -9.8f;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -807,9 +807,9 @@ void Vehicle::updatePos(F32 dt)
|
||||||
if (mCollisionList.getCount())
|
if (mCollisionList.getCount())
|
||||||
{
|
{
|
||||||
F32 k = mRigid.getKineticEnergy();
|
F32 k = mRigid.getKineticEnergy();
|
||||||
F32 G = mNetGravity * dt;
|
F32 G = mNetGravity;
|
||||||
F32 Kg = 0.5 * mRigid.mass * G * G;
|
F32 Kg = 0.5 * mRigid.mass * G * G;
|
||||||
if (k < sRestTol * Kg && ++restCount > sRestCount)
|
if (k < sRestTol * Kg * dt && ++restCount > sRestCount)
|
||||||
mRigid.setAtRest();
|
mRigid.setAtRest();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue