diff --git a/Engine/source/T3D/rigid.cpp b/Engine/source/T3D/rigid.cpp index 3dea66a6a..7b84a7e18 100644 --- a/Engine/source/T3D/rigid.cpp +++ b/Engine/source/T3D/rigid.cpp @@ -363,4 +363,6 @@ void Rigid::setAtRest() linMomentum.set(0.0f,0.0f,0.0f); angVelocity.set(0.0f,0.0f,0.0f); angMomentum.set(0.0f,0.0f,0.0f); + force.set(0.0f, 0.0f, 0.0f); + torque.set(0.0f, 0.0f, 0.0f); } diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index cfdd8258f..217d5f2df 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -1117,7 +1117,7 @@ void RigidShape::updatePos(F32 dt) if (mCollisionList.getCount()) { F32 k = mRigid.getKineticEnergy(); - F32 G = mNetGravity* dt; + F32 G = mNetGravity* dt * TickMs / mDataBlock->integration; F32 Kg = 0.5 * mRigid.mass * G * G; if (k < sRestTol * Kg && ++restCount > sRestCount) mRigid.setAtRest(); @@ -1494,10 +1494,12 @@ void RigidShape::writePacketData(GameConnection *connection, BitStream *stream) Parent::writePacketData(connection, stream); mathWrite(*stream, mRigid.linPosition); - mathWrite(*stream, mRigid.angPosition); - mathWrite(*stream, mRigid.linMomentum); - mathWrite(*stream, mRigid.angMomentum); - stream->writeFlag(mRigid.atRest); + if (!stream->writeFlag(mRigid.atRest)) + { + mathWrite(*stream, mRigid.angPosition); + mathWrite(*stream, mRigid.linMomentum); + mathWrite(*stream, mRigid.angMomentum); + } stream->writeFlag(mContacts.getCount() == 0); stream->writeFlag(mDisableMove); @@ -1509,14 +1511,20 @@ void RigidShape::readPacketData(GameConnection *connection, BitStream *stream) Parent::readPacketData(connection, stream); mathRead(*stream, &mRigid.linPosition); - mathRead(*stream, &mRigid.angPosition); - mathRead(*stream, &mRigid.linMomentum); - mathRead(*stream, &mRigid.angMomentum); - mRigid.atRest = stream->readFlag(); + if (stream->readFlag()) + { + mRigid.setAtRest(); + } + else + { + mathRead(*stream, &mRigid.angPosition); + mathRead(*stream, &mRigid.linMomentum); + mathRead(*stream, &mRigid.angMomentum); + mRigid.updateInertialTensor(); + mRigid.updateVelocity(); + } if (stream->readFlag()) mContacts.clear(); - mRigid.updateInertialTensor(); - mRigid.updateVelocity(); mDisableMove = stream->readFlag(); stream->setCompressionPoint(mRigid.linPosition); @@ -1541,10 +1549,12 @@ U32 RigidShape::packUpdate(NetConnection *con, U32 mask, BitStream *stream) stream->writeFlag(mask & ForceMoveMask); stream->writeCompressedPoint(mRigid.linPosition); - mathWrite(*stream, mRigid.angPosition); - mathWrite(*stream, mRigid.linMomentum); - mathWrite(*stream, mRigid.angMomentum); - stream->writeFlag(mRigid.atRest); + if (!stream->writeFlag(mRigid.atRest)) + { + mathWrite(*stream, mRigid.angPosition); + mathWrite(*stream, mRigid.linMomentum); + mathWrite(*stream, mRigid.angMomentum); + } } if(stream->writeFlag(mask & FreezeMask)) @@ -1574,11 +1584,18 @@ void RigidShape::unpackUpdate(NetConnection *con, BitStream *stream) // Read in new position and momentum values stream->readCompressedPoint(&mRigid.linPosition); - mathRead(*stream, &mRigid.angPosition); - mathRead(*stream, &mRigid.linMomentum); - mathRead(*stream, &mRigid.angMomentum); - mRigid.atRest = stream->readFlag(); - mRigid.updateVelocity(); + + if (stream->readFlag()) + { + mRigid.setAtRest(); + } + else + { + mathRead(*stream, &mRigid.angPosition); + mathRead(*stream, &mRigid.linMomentum); + mathRead(*stream, &mRigid.angMomentum); + mRigid.updateVelocity(); + } if (!forceUpdate && isProperlyAdded()) { @@ -1631,6 +1648,7 @@ void RigidShape::unpackUpdate(NetConnection *con, BitStream *stream) mDelta.warpCount = mDelta.warpTicks = 0; setPosition(mRigid.linPosition, mRigid.angPosition); } + mRigid.updateCenterOfMass(); } if(stream->readFlag()) diff --git a/Engine/source/T3D/vehicles/vehicle.cpp b/Engine/source/T3D/vehicles/vehicle.cpp index a1e4a426a..721bf2fba 100644 --- a/Engine/source/T3D/vehicles/vehicle.cpp +++ b/Engine/source/T3D/vehicles/vehicle.cpp @@ -807,7 +807,7 @@ void Vehicle::updatePos(F32 dt) if (mCollisionList.getCount()) { F32 k = mRigid.getKineticEnergy(); - F32 G = mNetGravity* dt; + F32 G = mNetGravity* dt * TickMs / mDataBlock->integration; F32 Kg = 0.5 * mRigid.mass * G * G; if (k < sRestTol * Kg && ++restCount > sRestCount) mRigid.setAtRest(); @@ -959,16 +959,6 @@ U32 Vehicle::packUpdate(NetConnection *con, U32 mask, BitStream *stream) stream->writeFloat(pitch,9); mDelta.move.pack(stream); - if (stream->writeFlag(mask & PositionMask)) - { - stream->writeCompressedPoint(mRigid.linPosition); - mathWrite(*stream, mRigid.angPosition); - mathWrite(*stream, mRigid.linMomentum); - mathWrite(*stream, mRigid.angMomentum); - stream->writeFlag(mRigid.atRest); - } - - stream->writeFloat(mClampF(getEnergyValue(), 0.f, 1.f), 8); return retMask; @@ -989,73 +979,6 @@ void Vehicle::unpackUpdate(NetConnection *con, BitStream *stream) mSteering.y = (2 * pitch * mDataBlock->maxSteeringAngle) - mDataBlock->maxSteeringAngle; mDelta.move.unpack(stream); - if (stream->readFlag()) - { - mPredictionCount = sMaxPredictionTicks; - F32 speed = mRigid.linVelocity.len(); - mDelta.warpRot[0] = mRigid.angPosition; - - // Read in new position and momentum values - stream->readCompressedPoint(&mRigid.linPosition); - mathRead(*stream, &mRigid.angPosition); - mathRead(*stream, &mRigid.linMomentum); - mathRead(*stream, &mRigid.angMomentum); - mRigid.atRest = stream->readFlag(); - mRigid.updateVelocity(); - - if (isProperlyAdded()) - { - // Determine number of ticks to warp based on the average - // of the client and server velocities. - Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt; - mDelta.warpOffset = mRigid.linPosition - cp; - - // Calc the distance covered in one tick as the average of - // the old speed and the new speed from the server. - F32 dt,as = (speed + mRigid.linVelocity.len()) * 0.5 * TickSec; - - // Cal how many ticks it will take to cover the warp offset. - // If it's less than what's left in the current tick, we'll just - // warp in the remaining time. - if (!as || (dt = mDelta.warpOffset.len() / as) > sMaxWarpTicks) - dt = mDelta.dt + sMaxWarpTicks; - else - dt = (dt <= mDelta.dt)? mDelta.dt : mCeil(dt - mDelta.dt) + mDelta.dt; - - // Adjust current frame interpolation - if (mDelta.dt) { - mDelta.pos = cp + (mDelta.warpOffset * (mDelta.dt / dt)); - mDelta.posVec = (cp - mDelta.pos) / mDelta.dt; - QuatF cr; - cr.interpolate(mDelta.rot[1],mDelta.rot[0],mDelta.dt); - mDelta.rot[1].interpolate(cr,mRigid.angPosition,mDelta.dt / dt); - mDelta.rot[0].extrapolate(mDelta.rot[1],cr,mDelta.dt); - } - - // Calculated multi-tick warp - mDelta.warpCount = 0; - mDelta.warpTicks = (S32)(mFloor(dt)); - if (mDelta.warpTicks) - { - mDelta.warpOffset = mRigid.linPosition - mDelta.pos; - mDelta.warpOffset /= (F32)mDelta.warpTicks; - mDelta.warpRot[0] = mDelta.rot[1]; - mDelta.warpRot[1] = mRigid.angPosition; - } - } - else - { - // Set the vehicle to the server position - mDelta.dt = 0; - mDelta.pos = mRigid.linPosition; - mDelta.posVec.set(0,0,0); - mDelta.rot[1] = mDelta.rot[0] = mRigid.angPosition; - mDelta.warpCount = mDelta.warpTicks = 0; - setPosition(mRigid.linPosition, mRigid.angPosition); - } - mRigid.updateCenterOfMass(); - } - setEnergyLevel(stream->readFloat(8) * mDataBlock->maxEnergy); } diff --git a/Engine/source/T3D/vehicles/wheeledVehicle.cpp b/Engine/source/T3D/vehicles/wheeledVehicle.cpp index 7771fb39d..23b3bc045 100644 --- a/Engine/source/T3D/vehicles/wheeledVehicle.cpp +++ b/Engine/source/T3D/vehicles/wheeledVehicle.cpp @@ -315,6 +315,7 @@ WheeledVehicleData::WheeledVehicleData() dMemset(&wheel, 0, sizeof(wheel)); for (S32 i = 0; i < MaxSounds; i++) INIT_SOUNDASSET_ARRAY(WheeledVehicleSounds, i); + mDownForce = 0; } @@ -477,6 +478,8 @@ void WheeledVehicleData::initPersistFields() addField("brakeTorque", TypeF32, Offset(brakeTorque, WheeledVehicleData), "@brief Torque applied when braking.\n\n" "This controls how fast the vehicle will stop when the brakes are applied." ); + addField("downforce", TypeF32, Offset(mDownForce, WheeledVehicleData), + "downward force based on velocity."); endGroup("Steering"); } @@ -500,6 +503,7 @@ void WheeledVehicleData::packData(BitStream* stream) stream->write(engineTorque); stream->write(engineBrake); stream->write(brakeTorque); + stream->write(mDownForce); } void WheeledVehicleData::unpackData(BitStream* stream) @@ -519,6 +523,7 @@ void WheeledVehicleData::unpackData(BitStream* stream) stream->read(&engineTorque); stream->read(&engineBrake); stream->read(&brakeTorque); + stream->read(&mDownForce); } @@ -920,6 +925,18 @@ void WheeledVehicle::updateForces(F32 dt) Wheel* wend = &mWheel[mDataBlock->wheelCount]; mRigid.clearForces(); + //calculate here so we can stiffen the springs a bit based on + //the final amount of downforce + //get the speed + F32 downForce = mRigid.linVelocity.lenSquared() <= 1 ? 1 : mRigid.linVelocity.lenSquared(); + //grab the datablock var + downForce *= mDataBlock->mDownForce; + //make it a smaller number so we can multiply gravity by it + downForce = mSqrt(downForce); + downForce *= TickSec; + //ensure that it is not smaller then one, cause mulltiplying gravity by fractions is baaaad + downForce = downForce < 1 ? 1 : downForce; + // Calculate vertical load for friction. Divide up the spring // forces across all the wheels that are in contact with // the ground. @@ -955,6 +972,8 @@ void WheeledVehicle::updateForces(F32 dt) // Spring force & damping F32 spring = wheel->spring->force * (1 - wheel->extension); + spring += (spring * downForce); + if (wheel->extension == 0) //spring fully compressed { // Apply impulses to the rigid body to keep it from @@ -1110,7 +1129,7 @@ void WheeledVehicle::updateForces(F32 dt) mRigid.force += mAppliedForce; // Container drag & buoyancy - mRigid.force += Point3F(0, 0, mRigid.mass * mNetGravity); + mRigid.force += Point3F(0, 0, mRigid.mass * mNetGravity * downForce); mRigid.force -= mRigid.linVelocity * mDrag; mRigid.torque -= mRigid.angMomentum * mDrag; diff --git a/Engine/source/T3D/vehicles/wheeledVehicle.h b/Engine/source/T3D/vehicles/wheeledVehicle.h index 61ddce65f..45161db12 100644 --- a/Engine/source/T3D/vehicles/wheeledVehicle.h +++ b/Engine/source/T3D/vehicles/wheeledVehicle.h @@ -141,6 +141,7 @@ struct WheeledVehicleData: public VehicleData ClippedPolyList rigidBody; // Extracted from shape S32 brakeLightSequence; // Brakes S32 steeringSequence; // Steering animation + F32 mDownForce; // WheeledVehicleData();