diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index 69144461f..e2ba4606c 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -1215,44 +1215,46 @@ on standard collision resolution formulas. bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList) { // Apply impulses to resolve collision - bool colliding, collided = false; - - do + bool collided = false; + for (S32 i = 0; i < cList.getCount(); i++) { - colliding = false; - for (S32 i = 0; i < cList.getCount(); i++) + Collision& c = cList[i]; + if (c.distance < mDataBlock->collisionTol) { - 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) { - // 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. + if (c.object->getTypeMask() & VehicleObjectType) { + RigidShape* otherRigid = dynamic_cast(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 - // penetrating the surface. - ns.resolveCollision(cList[i].point, - cList[i].normal); - colliding = collided = true; - - // Keep track of objects we collide with - if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType) - { - ShapeBase* col = static_cast(c.object); - queueCollision(col,v - col->getVelocity()); - } + // Keep track of objects we collide with + if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType) + { + ShapeBase* col = static_cast(c.object); + queueCollision(col, v - col->getVelocity()); } } } - } while (colliding); + } 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); for (S32 i = 0; i < cList.getCount(); i++) { - Collision& c = cList[i]; + const Collision& c = cList[i]; if (c.distance < mDataBlock->collisionTol) { diff --git a/Engine/source/T3D/rigidShape.h b/Engine/source/T3D/rigidShape.h index d82145a67..6f6b9fcea 100644 --- a/Engine/source/T3D/rigidShape.h +++ b/Engine/source/T3D/rigidShape.h @@ -146,11 +146,6 @@ class RigidShape: public ShapeBase SimObjectPtr mDustTrailEmitter; protected: - enum CollisionFaceFlags - { - BodyCollision = BIT(0), - WheelCollision = BIT(1), - }; enum MaskBits { PositionMask = Parent::NextFreeMask << 0, EnergyMask = Parent::NextFreeMask << 1, @@ -193,7 +188,6 @@ class RigidShape: public ShapeBase CollisionList mCollisionList; CollisionList mContacts; - Rigid mRigid; ShapeBaseConvex mConvex; S32 restCount; @@ -238,6 +232,7 @@ class RigidShape: public ShapeBase public: // Test code... static ClippedPolyList* sPolyList; + Rigid mRigid; // RigidShape(); diff --git a/Engine/source/T3D/vehicles/vehicle.cpp b/Engine/source/T3D/vehicles/vehicle.cpp index 739fd2671..9d7809a26 100644 --- a/Engine/source/T3D/vehicles/vehicle.cpp +++ b/Engine/source/T3D/vehicles/vehicle.cpp @@ -816,14 +816,6 @@ void Vehicle::onRemove() SAFE_DELETE(mPhysicsRep); U32 i=0; - for( i=0; ideleteWhenEmpty(); - mDustEmitterList[i] = NULL; - } - } for( i=0; ideleteWhenEmpty(); - mSplashEmitterList[i] = NULL; - } - } - mWorkingQueryBox.minExtents.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 S32 count = mDataBlock->integration; --mWorkingQueryBoxCountDown; - updateWorkingCollisionSet(getCollisionMask()); + + if (!mDisableMove) + updateWorkingCollisionSet(getCollisionMask()); for (U32 i = 0; i < count; i++) updatePos(TickSec / count); @@ -952,13 +937,6 @@ void Vehicle::advanceTime(F32 dt) updateLiftoffDust( 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. bool collided = false; - if (!mRigid.atRest) { + if (!mRigid.atRest && !mDisableMove) + { collided = updateCollision(dt); // Now that all the forces have been processed, lets @@ -1265,7 +1244,7 @@ void Vehicle::updatePos(F32 dt) } // Integrate forward - if (!mRigid.atRest) + if (!mRigid.atRest && !mDisableMove) mRigid.integrate(dt); // Deal with client and server scripting, sounds, etc. @@ -1376,163 +1355,6 @@ bool Vehicle::updateCollision(F32 dt) 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(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(obj), dv); - return true; - } - } - - return false; -} - - //---------------------------------------------------------------------------- void Vehicle::updateWorkingCollisionSet(const U32 mask) diff --git a/Engine/source/T3D/vehicles/vehicle.h b/Engine/source/T3D/vehicles/vehicle.h index dd8619fd6..490e1a5a8 100644 --- a/Engine/source/T3D/vehicles/vehicle.h +++ b/Engine/source/T3D/vehicles/vehicle.h @@ -24,13 +24,7 @@ #define _VEHICLE_H_ #ifndef _SHAPEBASE_H_ -#include "T3D/shapeBase.h" -#endif -#ifndef _RIGID_H_ -#include "T3D/rigid.h" -#endif -#ifndef _BOXCONVEX_H_ -#include "collision/boxConvex.h" +#include "T3D/rigidShape.h" #endif class ParticleEmitter; @@ -41,9 +35,9 @@ class Vehicle; //---------------------------------------------------------------------------- -struct VehicleData: public ShapeBaseData +struct VehicleData : public RigidShapeData { - typedef ShapeBaseData Parent; + typedef RigidShapeData Parent; struct Body { enum Sounds { @@ -146,20 +140,15 @@ struct VehicleData: public ShapeBaseData //---------------------------------------------------------------------------- class PhysicsBody; -class Vehicle: public ShapeBase +class Vehicle : public RigidShape { - typedef ShapeBase Parent; + typedef RigidShape Parent; protected: enum CollisionFaceFlags { BodyCollision = 0x1, WheelCollision = 0x2, }; - enum MaskBits { - PositionMask = Parent::NextFreeMask << 0, - EnergyMask = Parent::NextFreeMask << 1, - NextFreeMask = Parent::NextFreeMask << 2 - }; struct StateDelta { Move move; ///< Last move from server @@ -205,7 +194,6 @@ class Vehicle: public ShapeBase CollisionList mCollisionList; CollisionList mContacts; - Rigid mRigid; ShapeBaseConvex mConvex; S32 restCount; @@ -217,9 +205,6 @@ class Vehicle: public ShapeBase virtual bool onNewDataBlock( GameBaseData *dptr, bool reload ); void updatePos(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); void checkTriggers(); static void findCallback(SceneObject* obj,void * key);