mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
235 lines
9.7 KiB
C++
235 lines
9.7 KiB
C++
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prey_local.h"
|
|
|
|
|
|
//#define DEBUG_VEHICLE_PHYSICS 1
|
|
#define VEHICLE_DEBUG if(g_vehicleDebug.GetInteger()) gameLocal.Printf
|
|
#if DEBUG_VEHICLE_PHYSICS
|
|
#define CheckSolid(a, b, c, d, e, f) DoCheckSolid(a, b, c, d, e, f)
|
|
#else
|
|
#define CheckSolid(a, b, c, d, e, f) 0
|
|
#endif
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// CheckSolid: utility function for checking for collision errors
|
|
//
|
|
//-------------------------------------------------------------
|
|
bool DoCheckSolid(const char *text, idVec3 &pos, idClipModel *clipModel, int clipMask, idMat3 &axis, idEntity *pass) {
|
|
int myContents = gameLocal.clip.Contents(pos, clipModel, axis, clipMask, pass);
|
|
if( myContents ) {
|
|
VEHICLE_DEBUG("%s\n", text);
|
|
VEHICLE_DEBUG(" position: %s\n", pos.ToString());
|
|
VEHICLE_DEBUG(" orientation: %s\n", axis.ToAngles().ToString());
|
|
VEHICLE_DEBUG(" contents: %d\n", myContents);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
CLASS_DECLARATION( hhPhysics_RigidBodySimple, hhPhysics_Vehicle )
|
|
END_CLASS
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// hhPhysics_Vehicle::VehicleMotion
|
|
//
|
|
//-------------------------------------------------------------
|
|
bool hhPhysics_Vehicle::VehicleMotion(trace_t &collision, const idVec3 &start, const idVec3 &end, const idMat3 &axis) {
|
|
trace_t translationalTrace;
|
|
idVec3 move = end - start;
|
|
idVec3 curPosition = start;
|
|
idMat3 curAxis = axis;
|
|
|
|
memset(&collision, 0, sizeof(collision)); // sanity
|
|
|
|
collision.fraction = 1.0f; // Assume success until proven otherwise
|
|
|
|
//
|
|
// try to slide move
|
|
//
|
|
for(int i = 0; i < 3; i++ ) {
|
|
|
|
gameLocal.clip.Translation( translationalTrace, curPosition, curPosition + move, clipModel, curAxis, clipMask, self );
|
|
curPosition = translationalTrace.endpos;
|
|
|
|
CheckSolid(va("SlideMoved (%d) into something solid during slidemove!", i), curPosition, clipModel, clipMask, curAxis, self);
|
|
|
|
// Keep the shortest frac
|
|
if (translationalTrace.fraction < collision.fraction) {
|
|
collision.fraction = translationalTrace.fraction;
|
|
collision.c = translationalTrace.c;
|
|
}
|
|
|
|
if ( translationalTrace.fraction == 1.0f ) {
|
|
break;
|
|
}
|
|
|
|
// Shorten the move by the amount moved
|
|
move *= (1.0f - translationalTrace.fraction);
|
|
|
|
// project movement and momentum onto the sliding surface
|
|
move.ProjectOntoPlane( translationalTrace.c.normal, OVERCLIP );
|
|
}
|
|
|
|
collision.endAxis = curAxis;
|
|
collision.endpos = curPosition;
|
|
|
|
return collision.fraction < 1.0f;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// hhPhysics_Vehicle::CheckForCollisions
|
|
//
|
|
// Evaluate the impulse based rigid body physics.
|
|
// in the event of a collision, tries to do a slide move
|
|
//-------------------------------------------------------------
|
|
bool hhPhysics_Vehicle::CheckForCollisions( const float deltaTime, rigidBodyPState_t &next, trace_t &collision ) {
|
|
bool collided = false;
|
|
|
|
CheckSolid("Before VehicleMotion: in something solid!", current.i.position, clipModel, clipMask, current.i.orientation, self);
|
|
|
|
collided = VehicleMotion( collision, current.i.position, next.i.position, current.i.orientation );
|
|
if( collided ) {
|
|
// set the next state to the state at the moment of impact
|
|
next.i.position = collision.endpos;
|
|
next.i.orientation = collision.endAxis;
|
|
collided = true;
|
|
}
|
|
|
|
CheckSolid("After VehicleMotion: in something solid!", next.i.position, clipModel, clipMask, next.i.orientation, self);
|
|
|
|
return collided;
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhPhysics_Vehicle::SetFriction
|
|
================
|
|
*/
|
|
void hhPhysics_Vehicle::SetFriction( const float linear, const float angular, const float contact ) {
|
|
//don't cap the friction for the vehicle
|
|
linearFriction = linear;
|
|
angularFriction = angular;
|
|
contactFriction = contact;
|
|
}
|
|
|
|
const float VEH_VELOCITY_MAX = 16000;
|
|
const int VEH_VELOCITY_TOTAL_BITS = 16;
|
|
const int VEH_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( VEH_VELOCITY_MAX ) ) + 1;
|
|
const int VEH_VELOCITY_MANTISSA_BITS = VEH_VELOCITY_TOTAL_BITS - 1 - VEH_VELOCITY_EXPONENT_BITS;
|
|
const float VEH_MOMENTUM_MAX = 1e20f;
|
|
const int VEH_MOMENTUM_TOTAL_BITS = 16;
|
|
const int VEH_MOMENTUM_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( VEH_MOMENTUM_MAX ) ) + 1;
|
|
const int VEH_MOMENTUM_MANTISSA_BITS = VEH_MOMENTUM_TOTAL_BITS - 1 - VEH_MOMENTUM_EXPONENT_BITS;
|
|
const float VEH_FORCE_MAX = 1e20f;
|
|
const int VEH_FORCE_TOTAL_BITS = 16;
|
|
const int VEH_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( VEH_FORCE_MAX ) ) + 1;
|
|
const int VEH_FORCE_MANTISSA_BITS = VEH_FORCE_TOTAL_BITS - 1 - VEH_FORCE_EXPONENT_BITS;
|
|
|
|
/*
|
|
================
|
|
hhPhysics_Vehicle::WriteToSnapshot
|
|
================
|
|
*/
|
|
void hhPhysics_Vehicle::WriteToSnapshot( idBitMsgDelta &msg ) const {
|
|
idCQuat quat, localQuat;
|
|
|
|
quat = current.i.orientation.ToCQuat();
|
|
localQuat = current.localAxis.ToCQuat();
|
|
|
|
msg.WriteFloat( gravityVector.x );
|
|
msg.WriteFloat( gravityVector.y );
|
|
msg.WriteFloat( gravityVector.z );
|
|
|
|
msg.WriteBits(dropToFloor, 1);
|
|
|
|
msg.WriteLong( current.atRest );
|
|
msg.WriteFloat( current.i.position[0] );
|
|
msg.WriteFloat( current.i.position[1] );
|
|
msg.WriteFloat( current.i.position[2] );
|
|
msg.WriteFloat( quat.x );
|
|
msg.WriteFloat( quat.y );
|
|
msg.WriteFloat( quat.z );
|
|
msg.WriteFloat( current.i.linearMomentum[0], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteFloat( current.i.linearMomentum[1], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteFloat( current.i.linearMomentum[2], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteFloat( current.i.angularMomentum[0], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteFloat( current.i.angularMomentum[1], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteFloat( current.i.angularMomentum[2], VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( current.i.position[0], current.localOrigin[0] );
|
|
msg.WriteDeltaFloat( current.i.position[1], current.localOrigin[1] );
|
|
msg.WriteDeltaFloat( current.i.position[2], current.localOrigin[2] );
|
|
msg.WriteDeltaFloat( quat.x, localQuat.x );
|
|
msg.WriteDeltaFloat( quat.y, localQuat.y );
|
|
msg.WriteDeltaFloat( quat.z, localQuat.z );
|
|
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalForce[0], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalForce[1], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalForce[2], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalTorque[0], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalTorque[1], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
msg.WriteDeltaFloat( 0.0f, current.externalTorque[2], VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhPhysics_Vehicle::ReadFromSnapshot
|
|
================
|
|
*/
|
|
void hhPhysics_Vehicle::ReadFromSnapshot( const idBitMsgDelta &msg ) {
|
|
idCQuat quat, localQuat;
|
|
|
|
idVec3 newGrav;
|
|
newGrav.x = msg.ReadFloat();
|
|
newGrav.y = msg.ReadFloat();
|
|
newGrav.z = msg.ReadFloat();
|
|
|
|
SetGravity(newGrav);
|
|
|
|
dropToFloor = !!msg.ReadBits(1);
|
|
|
|
current.atRest = msg.ReadLong();
|
|
current.i.position[0] = msg.ReadFloat();
|
|
current.i.position[1] = msg.ReadFloat();
|
|
current.i.position[2] = msg.ReadFloat();
|
|
quat.x = msg.ReadFloat();
|
|
quat.y = msg.ReadFloat();
|
|
quat.z = msg.ReadFloat();
|
|
current.i.linearMomentum[0] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.i.linearMomentum[1] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.i.linearMomentum[2] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.i.angularMomentum[0] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.i.angularMomentum[1] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.i.angularMomentum[2] = msg.ReadFloat( VEH_MOMENTUM_EXPONENT_BITS, VEH_MOMENTUM_MANTISSA_BITS );
|
|
current.localOrigin[0] = msg.ReadDeltaFloat( current.i.position[0] );
|
|
current.localOrigin[1] = msg.ReadDeltaFloat( current.i.position[1] );
|
|
current.localOrigin[2] = msg.ReadDeltaFloat( current.i.position[2] );
|
|
localQuat.x = msg.ReadDeltaFloat( quat.x );
|
|
localQuat.y = msg.ReadDeltaFloat( quat.y );
|
|
localQuat.z = msg.ReadDeltaFloat( quat.z );
|
|
current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, VEH_VELOCITY_EXPONENT_BITS, VEH_VELOCITY_MANTISSA_BITS );
|
|
current.externalForce[0] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
current.externalForce[1] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
current.externalForce[2] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
current.externalTorque[0] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
current.externalTorque[1] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
current.externalTorque[2] = msg.ReadDeltaFloat( 0.0f, VEH_FORCE_EXPONENT_BITS, VEH_FORCE_MANTISSA_BITS );
|
|
|
|
current.i.orientation = quat.ToMat3();
|
|
current.localAxis = localQuat.ToMat3();
|
|
|
|
if ( clipModel ) {
|
|
clipModel->Link( gameLocal.clip, self, clipModel->GetId(), current.i.position, current.i.orientation );
|
|
}
|
|
}
|