From d6b6f36b0aa1651c937840c75b70416664d11908 Mon Sep 17 00:00:00 2001 From: Azaezel Date: Thu, 21 Jan 2016 18:14:15 -0600 Subject: [PATCH 1/4] rev 1 refactor for fitting rigidshape into the vehicle hierarchy. cleaned a few, but by no means all redundancies. DO NOTE THE FOLLOWING: ShapeBase::processTick(move); ShapeBase::interpolateTick(dt); to avoid side effects for now. properly those would be retooled down the line to be more inheritance-friendly. --- Engine/source/T3D/rigidShape.cpp | 57 ++++++++++++-------------- Engine/source/T3D/rigidShape.h | 5 --- Engine/source/T3D/vehicles/vehicle.cpp | 37 ++++------------- Engine/source/T3D/vehicles/vehicle.h | 21 +++------- 4 files changed, 39 insertions(+), 81 deletions(-) diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index 666048648..7d85fa6a5 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -1210,44 +1210,39 @@ 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. + ns.resolveCollision(cList[i].point, + cList[i].normal); + collided = true; + + // Keep track of objects we collide with + if (!isGhost() && c.object->getTypeMask() & ShapeBaseObjectType) { - - // 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()); - } + ShapeBase* col = static_cast(c.object); + queueCollision(col, v - col->getVelocity()); } } } - } while (colliding); + } return collided; } @@ -1264,7 +1259,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..ecd7953b1 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, diff --git a/Engine/source/T3D/vehicles/vehicle.cpp b/Engine/source/T3D/vehicles/vehicle.cpp index 1f18b426f..20be6e83a 100644 --- a/Engine/source/T3D/vehicles/vehicle.cpp +++ b/Engine/source/T3D/vehicles/vehicle.cpp @@ -782,14 +782,6 @@ bool Vehicle::onAdd() void Vehicle::onRemove() { 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); @@ -822,7 +805,7 @@ void Vehicle::processTick(const Move* move) { PROFILE_SCOPE( Vehicle_ProcessTick ); - Parent::processTick(move); + ShapeBase::processTick(move); // Warp to catch up to server if (mDelta.warpCount < mDelta.warpTicks) @@ -867,7 +850,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); @@ -887,7 +872,7 @@ void Vehicle::interpolateTick(F32 dt) { PROFILE_SCOPE( Vehicle_InterpolateTick ); - Parent::interpolateTick(dt); + ShapeBase::interpolateTick(dt); if(dt == 0.0f) setRenderPosition(mDelta.pos, mDelta.rot[1]); @@ -909,13 +894,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; } @@ -1199,7 +1177,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 @@ -1220,7 +1199,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. diff --git a/Engine/source/T3D/vehicles/vehicle.h b/Engine/source/T3D/vehicles/vehicle.h index 695c16686..cdc2c8202 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 { @@ -143,20 +137,15 @@ struct VehicleData: public ShapeBaseData //---------------------------------------------------------------------------- -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 From 0678817217685df8cffe7b941d445b9bcc973ca0 Mon Sep 17 00:00:00 2001 From: Azaezel Date: Thu, 21 Jan 2016 18:31:47 -0600 Subject: [PATCH 2/4] redundancy kill-off --- Engine/source/T3D/vehicles/vehicle.cpp | 157 ------------------------- Engine/source/T3D/vehicles/vehicle.h | 3 - 2 files changed, 160 deletions(-) diff --git a/Engine/source/T3D/vehicles/vehicle.cpp b/Engine/source/T3D/vehicles/vehicle.cpp index 20be6e83a..276310e95 100644 --- a/Engine/source/T3D/vehicles/vehicle.cpp +++ b/Engine/source/T3D/vehicles/vehicle.cpp @@ -1310,163 +1310,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->a->getObject() == this)? - state->b->getObject(): state->a->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 cdc2c8202..86da8693a 100644 --- a/Engine/source/T3D/vehicles/vehicle.h +++ b/Engine/source/T3D/vehicles/vehicle.h @@ -201,9 +201,6 @@ class Vehicle : public RigidShape 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); From d8f889f84043c882d73d486a1587df751bb73a20 Mon Sep 17 00:00:00 2001 From: Azaezel Date: Thu, 21 Jan 2016 19:04:58 -0600 Subject: [PATCH 3/4] backend fix: rigid on rigid collisions --- Engine/source/T3D/rigid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/T3D/rigid.cpp b/Engine/source/T3D/rigid.cpp index e2441441f..ad2512e43 100644 --- a/Engine/source/T3D/rigid.cpp +++ b/Engine/source/T3D/rigid.cpp @@ -173,7 +173,7 @@ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal, Rigid* rig applyImpulse(r1,impulse); impulse.neg(); - applyImpulse(r2,impulse); + rigid->applyImpulse(r2,impulse); return true; } From 6a930f3da122e179964d452b00d226aeae1f67ee Mon Sep 17 00:00:00 2001 From: Azaezel Date: Thu, 21 Jan 2016 19:05:48 -0600 Subject: [PATCH 4/4] rigid body on rigid body reactions --- Engine/source/T3D/rigidShape.cpp | 11 +++++++++-- Engine/source/T3D/rigidShape.h | 2 +- Engine/source/T3D/vehicles/vehicle.h | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index 7d85fa6a5..c057228ca 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -1230,8 +1230,15 @@ bool RigidShape::resolveCollision(Rigid& ns,CollisionList& cList) // Apply impulses to the rigid body to keep it from // penetrating the surface. - ns.resolveCollision(cList[i].point, - cList[i].normal); + 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; // Keep track of objects we collide with diff --git a/Engine/source/T3D/rigidShape.h b/Engine/source/T3D/rigidShape.h index ecd7953b1..6f6b9fcea 100644 --- a/Engine/source/T3D/rigidShape.h +++ b/Engine/source/T3D/rigidShape.h @@ -188,7 +188,6 @@ class RigidShape: public ShapeBase CollisionList mCollisionList; CollisionList mContacts; - Rigid mRigid; ShapeBaseConvex mConvex; S32 restCount; @@ -233,6 +232,7 @@ class RigidShape: public ShapeBase public: // Test code... static ClippedPolyList* sPolyList; + Rigid mRigid; // RigidShape(); diff --git a/Engine/source/T3D/vehicles/vehicle.h b/Engine/source/T3D/vehicles/vehicle.h index 86da8693a..244c39b2c 100644 --- a/Engine/source/T3D/vehicles/vehicle.h +++ b/Engine/source/T3D/vehicles/vehicle.h @@ -189,7 +189,6 @@ class Vehicle : public RigidShape CollisionList mCollisionList; CollisionList mContacts; - Rigid mRigid; ShapeBaseConvex mConvex; S32 restCount;