mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 00:54:54 +00:00
Merge branch 'rigidshapeReorg' of https://github.com/Azaezel/Torque3D into alpha40_ReactiveRigidReorg
# Conflicts: # Engine/source/T3D/rigid.cpp # Engine/source/T3D/vehicles/vehicle.cpp
This commit is contained in:
commit
245994dbdd
4 changed files with 44 additions and 240 deletions
|
|
@ -1215,44 +1215,46 @@ on standard collision resolution formulas.
|
||||||
bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList)
|
||||||
{
|
{
|
||||||
// Apply impulses to resolve collision
|
// Apply impulses to resolve collision
|
||||||
bool colliding, collided = false;
|
bool collided = false;
|
||||||
|
for (S32 i = 0; i < cList.getCount(); i++)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
colliding = false;
|
Collision& c = cList[i];
|
||||||
for (S32 i = 0; i < cList.getCount(); i++)
|
if (c.distance < mDataBlock->collisionTol)
|
||||||
{
|
{
|
||||||
Collision& c = cList[i];
|
// Velocity into surface
|
||||||
if (c.distance < mDataBlock->collisionTol)
|
Point3F v, r;
|
||||||
|
ns.getOriginVector(c.point, &r);
|
||||||
|
ns.getVelocity(r, &v);
|
||||||
|
F32 vn = mDot(v, c.normal);
|
||||||
|
|
||||||
|
// Only interested in velocities greater than sContactTol,
|
||||||
|
// velocities less than that will be dealt with as contacts
|
||||||
|
// "constraints".
|
||||||
|
if (vn < -mDataBlock->contactTol)
|
||||||
{
|
{
|
||||||
// Velocity into surface
|
|
||||||
Point3F v,r;
|
|
||||||
ns.getOriginVector(c.point,&r);
|
|
||||||
ns.getVelocity(r,&v);
|
|
||||||
F32 vn = mDot(v,c.normal);
|
|
||||||
|
|
||||||
// Only interested in velocities greater than sContactTol,
|
// Apply impulses to the rigid body to keep it from
|
||||||
// velocities less than that will be dealt with as contacts
|
// penetrating the surface.
|
||||||
// "constraints".
|
if (c.object->getTypeMask() & VehicleObjectType)
|
||||||
if (vn < -mDataBlock->contactTol)
|
|
||||||
{
|
{
|
||||||
|
RigidShape* otherRigid = dynamic_cast<RigidShape*>(c.object);
|
||||||
|
if (otherRigid)
|
||||||
|
ns.resolveCollision(cList[i].point, cList[i].normal, &otherRigid->mRigid);
|
||||||
|
else
|
||||||
|
ns.resolveCollision(cList[i].point, cList[i].normal);
|
||||||
|
}
|
||||||
|
else ns.resolveCollision(cList[i].point, cList[i].normal);
|
||||||
|
collided = true;
|
||||||
|
|
||||||
// Apply impulses to the rigid body to keep it from
|
// Keep track of objects we collide with
|
||||||
// penetrating the surface.
|
if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType)
|
||||||
ns.resolveCollision(cList[i].point,
|
{
|
||||||
cList[i].normal);
|
ShapeBase* col = static_cast<ShapeBase*>(c.object);
|
||||||
colliding = collided = true;
|
queueCollision(col, v - col->getVelocity());
|
||||||
|
|
||||||
// Keep track of objects we collide with
|
|
||||||
if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType)
|
|
||||||
{
|
|
||||||
ShapeBase* col = static_cast<ShapeBase*>(c.object);
|
|
||||||
queueCollision(col,v - col->getVelocity());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (colliding);
|
}
|
||||||
|
|
||||||
return collided;
|
return collided;
|
||||||
}
|
}
|
||||||
|
|
@ -1269,7 +1271,7 @@ bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
|
||||||
Point3F t,p(0,0,0),l(0,0,0);
|
Point3F t,p(0,0,0),l(0,0,0);
|
||||||
for (S32 i = 0; i < cList.getCount(); i++)
|
for (S32 i = 0; i < cList.getCount(); i++)
|
||||||
{
|
{
|
||||||
Collision& c = cList[i];
|
const Collision& c = cList[i];
|
||||||
if (c.distance < mDataBlock->collisionTol)
|
if (c.distance < mDataBlock->collisionTol)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,11 +146,6 @@ class RigidShape: public ShapeBase
|
||||||
SimObjectPtr<ParticleEmitter> mDustTrailEmitter;
|
SimObjectPtr<ParticleEmitter> mDustTrailEmitter;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum CollisionFaceFlags
|
|
||||||
{
|
|
||||||
BodyCollision = BIT(0),
|
|
||||||
WheelCollision = BIT(1),
|
|
||||||
};
|
|
||||||
enum MaskBits {
|
enum MaskBits {
|
||||||
PositionMask = Parent::NextFreeMask << 0,
|
PositionMask = Parent::NextFreeMask << 0,
|
||||||
EnergyMask = Parent::NextFreeMask << 1,
|
EnergyMask = Parent::NextFreeMask << 1,
|
||||||
|
|
@ -193,7 +188,6 @@ class RigidShape: public ShapeBase
|
||||||
|
|
||||||
CollisionList mCollisionList;
|
CollisionList mCollisionList;
|
||||||
CollisionList mContacts;
|
CollisionList mContacts;
|
||||||
Rigid mRigid;
|
|
||||||
ShapeBaseConvex mConvex;
|
ShapeBaseConvex mConvex;
|
||||||
S32 restCount;
|
S32 restCount;
|
||||||
|
|
||||||
|
|
@ -238,6 +232,7 @@ class RigidShape: public ShapeBase
|
||||||
public:
|
public:
|
||||||
// Test code...
|
// Test code...
|
||||||
static ClippedPolyList* sPolyList;
|
static ClippedPolyList* sPolyList;
|
||||||
|
Rigid mRigid;
|
||||||
|
|
||||||
//
|
//
|
||||||
RigidShape();
|
RigidShape();
|
||||||
|
|
|
||||||
|
|
@ -816,14 +816,6 @@ void Vehicle::onRemove()
|
||||||
SAFE_DELETE(mPhysicsRep);
|
SAFE_DELETE(mPhysicsRep);
|
||||||
|
|
||||||
U32 i=0;
|
U32 i=0;
|
||||||
for( i=0; i<VehicleData::VC_NUM_DUST_EMITTERS; i++ )
|
|
||||||
{
|
|
||||||
if( mDustEmitterList[i] )
|
|
||||||
{
|
|
||||||
mDustEmitterList[i]->deleteWhenEmpty();
|
|
||||||
mDustEmitterList[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i=0; i<VehicleData::VC_NUM_DAMAGE_EMITTERS; i++ )
|
for( i=0; i<VehicleData::VC_NUM_DAMAGE_EMITTERS; i++ )
|
||||||
{
|
{
|
||||||
|
|
@ -834,15 +826,6 @@ void Vehicle::onRemove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i=0; i<VehicleData::VC_NUM_SPLASH_EMITTERS; i++ )
|
|
||||||
{
|
|
||||||
if( mSplashEmitterList[i] )
|
|
||||||
{
|
|
||||||
mSplashEmitterList[i]->deleteWhenEmpty();
|
|
||||||
mSplashEmitterList[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mWorkingQueryBox.minExtents.set(-1e9f, -1e9f, -1e9f);
|
mWorkingQueryBox.minExtents.set(-1e9f, -1e9f, -1e9f);
|
||||||
mWorkingQueryBox.maxExtents.set(-1e9f, -1e9f, -1e9f);
|
mWorkingQueryBox.maxExtents.set(-1e9f, -1e9f, -1e9f);
|
||||||
|
|
||||||
|
|
@ -903,7 +886,9 @@ void Vehicle::processTick(const Move* move)
|
||||||
// Update the physics based on the integration rate
|
// Update the physics based on the integration rate
|
||||||
S32 count = mDataBlock->integration;
|
S32 count = mDataBlock->integration;
|
||||||
--mWorkingQueryBoxCountDown;
|
--mWorkingQueryBoxCountDown;
|
||||||
updateWorkingCollisionSet(getCollisionMask());
|
|
||||||
|
if (!mDisableMove)
|
||||||
|
updateWorkingCollisionSet(getCollisionMask());
|
||||||
for (U32 i = 0; i < count; i++)
|
for (U32 i = 0; i < count; i++)
|
||||||
updatePos(TickSec / count);
|
updatePos(TickSec / count);
|
||||||
|
|
||||||
|
|
@ -952,13 +937,6 @@ void Vehicle::advanceTime(F32 dt)
|
||||||
|
|
||||||
updateLiftoffDust( dt );
|
updateLiftoffDust( dt );
|
||||||
updateDamageSmoke( dt );
|
updateDamageSmoke( dt );
|
||||||
updateFroth(dt);
|
|
||||||
|
|
||||||
// Update 3rd person camera offset. Camera update is done
|
|
||||||
// here as it's a client side only animation.
|
|
||||||
mCameraOffset -=
|
|
||||||
(mCameraOffset * mDataBlock->cameraDecay +
|
|
||||||
mRigid.linVelocity * mDataBlock->cameraLag) * dt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1244,7 +1222,8 @@ void Vehicle::updatePos(F32 dt)
|
||||||
|
|
||||||
// Update collision information based on our current pos.
|
// Update collision information based on our current pos.
|
||||||
bool collided = false;
|
bool collided = false;
|
||||||
if (!mRigid.atRest) {
|
if (!mRigid.atRest && !mDisableMove)
|
||||||
|
{
|
||||||
collided = updateCollision(dt);
|
collided = updateCollision(dt);
|
||||||
|
|
||||||
// Now that all the forces have been processed, lets
|
// Now that all the forces have been processed, lets
|
||||||
|
|
@ -1265,7 +1244,7 @@ void Vehicle::updatePos(F32 dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Integrate forward
|
// Integrate forward
|
||||||
if (!mRigid.atRest)
|
if (!mRigid.atRest && !mDisableMove)
|
||||||
mRigid.integrate(dt);
|
mRigid.integrate(dt);
|
||||||
|
|
||||||
// Deal with client and server scripting, sounds, etc.
|
// Deal with client and server scripting, sounds, etc.
|
||||||
|
|
@ -1376,163 +1355,6 @@ bool Vehicle::updateCollision(F32 dt)
|
||||||
return collided;
|
return collided;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
/** Resolve collision impacts
|
|
||||||
Handle collision impacts, as opposed to contacts. Impulses are calculated based
|
|
||||||
on standard collision resolution formulas.
|
|
||||||
*/
|
|
||||||
bool Vehicle::resolveCollision(Rigid& ns,CollisionList& cList)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE( Vehicle_ResolveCollision );
|
|
||||||
|
|
||||||
// Apply impulses to resolve collision
|
|
||||||
bool collided = false;
|
|
||||||
for (S32 i = 0; i < cList.getCount(); i++)
|
|
||||||
{
|
|
||||||
Collision& c = cList[i];
|
|
||||||
if (c.distance < mDataBlock->collisionTol)
|
|
||||||
{
|
|
||||||
// Velocity into surface
|
|
||||||
Point3F v,r;
|
|
||||||
ns.getOriginVector(c.point,&r);
|
|
||||||
ns.getVelocity(r,&v);
|
|
||||||
F32 vn = mDot(v,c.normal);
|
|
||||||
|
|
||||||
// Only interested in velocities greater than sContactTol,
|
|
||||||
// velocities less than that will be dealt with as contacts
|
|
||||||
// "constraints".
|
|
||||||
if (vn < -mDataBlock->contactTol)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Apply impulses to the rigid body to keep it from
|
|
||||||
// penetrating the surface.
|
|
||||||
ns.resolveCollision(cList[i].point,
|
|
||||||
cList[i].normal);
|
|
||||||
collided = true;
|
|
||||||
|
|
||||||
// Keep track of objects we collide with
|
|
||||||
if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType)
|
|
||||||
{
|
|
||||||
ShapeBase* col = static_cast<ShapeBase*>(c.object);
|
|
||||||
queueCollision(col,v - col->getVelocity());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Vehicle::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE( Vehicle_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;
|
|
||||||
|
|
||||||
// Penetration force. This is actually a spring which
|
|
||||||
// will seperate the body from the collision surface.
|
|
||||||
F32 zi = 2 * mFabs(mRigid.getZeroImpulse(r,c.normal));
|
|
||||||
F32 s = (mDataBlock->collisionTol - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
|
|
||||||
Point3F f = c.normal * s;
|
|
||||||
|
|
||||||
// Friction impulse, calculated as a function of the
|
|
||||||
// amount of force it would take to stop the motion
|
|
||||||
// perpendicular to the normal.
|
|
||||||
Point3F uv = v - (c.normal * vn);
|
|
||||||
F32 ul = uv.len();
|
|
||||||
if (s > 0 && ul)
|
|
||||||
{
|
|
||||||
uv /= -ul;
|
|
||||||
F32 u = ul * ns.getZeroImpulse(r,uv);
|
|
||||||
s *= mRigid.friction;
|
|
||||||
if (u > s)
|
|
||||||
u = s;
|
|
||||||
f += uv * u;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate forces
|
|
||||||
p += f;
|
|
||||||
mCross(r,f,&t);
|
|
||||||
l += t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contact constraint forces act over time...
|
|
||||||
ns.linMomentum += p * dt;
|
|
||||||
ns.angMomentum += l * dt;
|
|
||||||
ns.updateVelocity();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool Vehicle::resolveDisplacement(Rigid& ns,CollisionState *state, F32 dt)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE( Vehicle_ResolveDisplacement );
|
|
||||||
|
|
||||||
SceneObject* obj = (state->mA->getObject() == this)?
|
|
||||||
state->mB->getObject(): state->mA->getObject();
|
|
||||||
|
|
||||||
if (obj->isDisplacable() && ((obj->getTypeMask() & ShapeBaseObjectType) != 0))
|
|
||||||
{
|
|
||||||
// Try to displace the object by the amount we're trying to move
|
|
||||||
Point3F objNewMom = ns.linVelocity * obj->getMass() * 1.1f;
|
|
||||||
Point3F objOldMom = obj->getMomentum();
|
|
||||||
Point3F objNewVel = objNewMom / obj->getMass();
|
|
||||||
|
|
||||||
Point3F myCenter;
|
|
||||||
Point3F theirCenter;
|
|
||||||
getWorldBox().getCenter(&myCenter);
|
|
||||||
obj->getWorldBox().getCenter(&theirCenter);
|
|
||||||
if (mDot(myCenter - theirCenter, objNewMom) >= 0.0f || objNewVel.len() < 0.01)
|
|
||||||
{
|
|
||||||
objNewMom = (theirCenter - myCenter);
|
|
||||||
objNewMom.normalize();
|
|
||||||
objNewMom *= 1.0f * obj->getMass();
|
|
||||||
objNewVel = objNewMom / obj->getMass();
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->setMomentum(objNewMom);
|
|
||||||
if (obj->displaceObject(objNewVel * 1.1f * dt) == true)
|
|
||||||
{
|
|
||||||
// Queue collision and change in velocity
|
|
||||||
VectorF dv = (objOldMom - objNewMom) / obj->getMass();
|
|
||||||
queueCollision(static_cast<ShapeBase*>(obj), dv);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Vehicle::updateWorkingCollisionSet(const U32 mask)
|
void Vehicle::updateWorkingCollisionSet(const U32 mask)
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,7 @@
|
||||||
#define _VEHICLE_H_
|
#define _VEHICLE_H_
|
||||||
|
|
||||||
#ifndef _SHAPEBASE_H_
|
#ifndef _SHAPEBASE_H_
|
||||||
#include "T3D/shapeBase.h"
|
#include "T3D/rigidShape.h"
|
||||||
#endif
|
|
||||||
#ifndef _RIGID_H_
|
|
||||||
#include "T3D/rigid.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _BOXCONVEX_H_
|
|
||||||
#include "collision/boxConvex.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
|
|
@ -41,9 +35,9 @@ class Vehicle;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct VehicleData: public ShapeBaseData
|
struct VehicleData : public RigidShapeData
|
||||||
{
|
{
|
||||||
typedef ShapeBaseData Parent;
|
typedef RigidShapeData Parent;
|
||||||
|
|
||||||
struct Body {
|
struct Body {
|
||||||
enum Sounds {
|
enum Sounds {
|
||||||
|
|
@ -146,20 +140,15 @@ struct VehicleData: public ShapeBaseData
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class PhysicsBody;
|
class PhysicsBody;
|
||||||
|
|
||||||
class Vehicle: public ShapeBase
|
class Vehicle : public RigidShape
|
||||||
{
|
{
|
||||||
typedef ShapeBase Parent;
|
typedef RigidShape Parent;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum CollisionFaceFlags {
|
enum CollisionFaceFlags {
|
||||||
BodyCollision = 0x1,
|
BodyCollision = 0x1,
|
||||||
WheelCollision = 0x2,
|
WheelCollision = 0x2,
|
||||||
};
|
};
|
||||||
enum MaskBits {
|
|
||||||
PositionMask = Parent::NextFreeMask << 0,
|
|
||||||
EnergyMask = Parent::NextFreeMask << 1,
|
|
||||||
NextFreeMask = Parent::NextFreeMask << 2
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StateDelta {
|
struct StateDelta {
|
||||||
Move move; ///< Last move from server
|
Move move; ///< Last move from server
|
||||||
|
|
@ -205,7 +194,6 @@ class Vehicle: public ShapeBase
|
||||||
|
|
||||||
CollisionList mCollisionList;
|
CollisionList mCollisionList;
|
||||||
CollisionList mContacts;
|
CollisionList mContacts;
|
||||||
Rigid mRigid;
|
|
||||||
ShapeBaseConvex mConvex;
|
ShapeBaseConvex mConvex;
|
||||||
S32 restCount;
|
S32 restCount;
|
||||||
|
|
||||||
|
|
@ -217,9 +205,6 @@ class Vehicle: public ShapeBase
|
||||||
virtual bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
virtual 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 resolveContacts(Rigid& ns,CollisionList& cList,F32 dt);
|
|
||||||
bool resolveDisplacement(Rigid& ns,CollisionState *state,F32 dt);
|
|
||||||
bool findContacts(Rigid& ns,CollisionList& cList);
|
bool findContacts(Rigid& ns,CollisionList& cList);
|
||||||
void checkTriggers();
|
void checkTriggers();
|
||||||
static void findCallback(SceneObject* obj,void * key);
|
static void findCallback(SceneObject* obj,void * key);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue