mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
174 lines
5.8 KiB
C++
174 lines
5.8 KiB
C++
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prey_local.h"
|
|
|
|
CLASS_DECLARATION( idForce, hhForce_Converge )
|
|
END_CLASS
|
|
|
|
|
|
hhForce_Converge::hhForce_Converge( void ) {
|
|
restoreFactor = 1.0f;
|
|
restoreForceSlack = 1.0f;
|
|
restoreTime = 0.1f;
|
|
ent = NULL;
|
|
physics = NULL;
|
|
axisEnt = NULL;
|
|
bShuttle = false;
|
|
}
|
|
|
|
hhForce_Converge::~hhForce_Converge( void ) {
|
|
}
|
|
|
|
void hhForce_Converge::Save(idSaveGame *savefile) const {
|
|
ent.Save(savefile);
|
|
axisEnt.Save(savefile);
|
|
savefile->WriteVec3( target );
|
|
savefile->WriteVec3( offset );
|
|
savefile->WriteInt( bodyID );
|
|
savefile->WriteFloat( restoreTime );
|
|
savefile->WriteFloat( restoreFactor );
|
|
savefile->WriteFloat( restoreForceSlack );
|
|
savefile->WriteBool( bShuttle );
|
|
}
|
|
|
|
void hhForce_Converge::Restore( idRestoreGame *savefile ) {
|
|
ent.Restore(savefile);
|
|
axisEnt.Restore(savefile);
|
|
savefile->ReadVec3( target );
|
|
savefile->ReadVec3( offset );
|
|
savefile->ReadInt( bodyID );
|
|
savefile->ReadFloat( restoreTime );
|
|
savefile->ReadFloat( restoreFactor );
|
|
savefile->ReadFloat( restoreForceSlack );
|
|
savefile->ReadBool( bShuttle );
|
|
|
|
physics = NULL; // HUMANHEAD mdl: Updated each frame
|
|
}
|
|
|
|
void hhForce_Converge::Evaluate( int time ) {
|
|
|
|
// Get the physics of ent each frame, in case their physics object was changed.
|
|
physics = ent.IsValid() ? ent->GetPhysics() : NULL;
|
|
|
|
// Apply convergent force
|
|
if (physics) {
|
|
idVec3 p = physics->GetOrigin( bodyID ) + offset * physics->GetAxis( bodyID );
|
|
idVec3 x = p - target;
|
|
|
|
if (axisEnt.IsValid()) {
|
|
idBounds bounds = ent->GetPhysics()->GetBounds();
|
|
idVec3 rightPt = ent->GetOrigin() + (ent->GetAxis()[0] * bounds[0].x);
|
|
idVec3 axisRightPt = axisEnt->GetOrigin() + (axisEnt->GetAxis()[1] * bounds[1].x);
|
|
|
|
idVec3 leftPt = ent->GetOrigin() + (ent->GetAxis()[0] * bounds[1].x);
|
|
idVec3 axisLeftPt = axisEnt->GetOrigin() + (axisEnt->GetAxis()[1] * bounds[0].x);
|
|
|
|
//gameRenderWorld->DebugLine(idVec4(1, 0, 0, 1), rightPt, axisRightPt, 100);
|
|
|
|
p = rightPt;
|
|
x = p - axisRightPt;
|
|
|
|
x *= restoreForceSlack; //allow a linear buildup based on the distance of the target point
|
|
|
|
idVec3 v = physics->GetLinearVelocity();
|
|
float m = physics->GetMass();
|
|
float b = idMath::Sqrt(4*restoreFactor*m);
|
|
idVec3 force = -restoreFactor*x - b*v; // use with addforce, k=200000
|
|
physics->AddForce(bodyID, p, force * 0.5f ); // Great to show mass variations
|
|
|
|
//gameRenderWorld->DebugLine(idVec4(1, 0, 0, 1), leftPt, axisLeftPt, 100);
|
|
|
|
p = leftPt;
|
|
x = p - axisLeftPt;
|
|
|
|
x *= restoreForceSlack; //allow a linear buildup based on the distance of the target point
|
|
|
|
force = axisLeftPt - leftPt;
|
|
force *= m * 4;
|
|
physics->AddForce(bodyID, p, force ); // Great to show mass variations
|
|
return;
|
|
}
|
|
|
|
x *= restoreForceSlack; //allow a linear buildup based on the distance of the target point
|
|
|
|
if (ent->IsType(idAFEntity_Base::Type)) { // Actors use velocity method since their masses are unrealistic, ragdolls need it too
|
|
if (!ent->fl.tooHeavyForTractor) {
|
|
// Velocity method: cover distance in fixed time
|
|
idVec3 velocity = -x / restoreTime; // Use with SetLinearVelocity()
|
|
if (ent->IsType(idActor::Type)) { //if a player is affected by this force..
|
|
//..do not allow him to build up velocity into his ground plane
|
|
if (ent->GetPhysics()->IsType(idPhysics_Player::Type) && ent->GetPhysics()->HasGroundContacts()) {
|
|
velocity.x *= -ent->GetPhysics()->GetGravityNormal().x;
|
|
velocity.y *= -ent->GetPhysics()->GetGravityNormal().y;
|
|
velocity.z *= -ent->GetPhysics()->GetGravityNormal().z;
|
|
}
|
|
}
|
|
physics->SetLinearVelocity(velocity, bodyID);
|
|
}
|
|
else {
|
|
// Entities that are too heavy get no force, just give feedback force
|
|
}
|
|
} else {
|
|
float m = physics->GetMass();
|
|
if (bShuttle && m < 1500.0f) { // Different equation for picking up low mass objects with the shuttle
|
|
idVec3 v = physics->GetLinearVelocity();
|
|
float springFactor = restoreFactor*0.0002f;
|
|
float dampFactor = idMath::Sqrt(springFactor);
|
|
idVec3 force = (-x * springFactor * m) - (v * dampFactor * m);
|
|
physics->AddForce(bodyID, p, force );
|
|
} else { // Critically Damped spring: m*a = -k*x - b*v ; b = 2 * sqrt(m*k)
|
|
idVec3 v = physics->GetLinearVelocity();
|
|
float m = physics->GetMass();
|
|
float b = idMath::Sqrt(4.0f*restoreFactor*m);
|
|
idVec3 force = -restoreFactor*x - b*v; // use with addforce, k=200000
|
|
physics->AddForce(bodyID, p, force ); // Great to show mass variations
|
|
}
|
|
}
|
|
/* else { // Impulse method
|
|
idVec3 v = physics->GetLinearVelocity();
|
|
float b = idMath::Sqrt(4*restoreFactor);
|
|
impulse = -restoreFactor*x - b*v; // Use with applyimpulse, k=50000
|
|
physics->ApplyImpulse(bodyID, p, impulse ); // Worked for all but some moveables (k=50000)
|
|
}
|
|
else { // Mass scaled force method, applies varying force to keep constant velocity
|
|
idVec3 v = physics->GetLinearVelocity();
|
|
float m = physics->GetMass();
|
|
float b = idMath::Sqrt(4*restoreFactor);
|
|
impulse = (-restoreFactor*x - b*v) * m; // use with addforce, k=500
|
|
physics->AddForce(bodyID, p, impulse ); // Works for all but ragdolls (k=500)
|
|
}
|
|
}*/
|
|
}
|
|
}
|
|
|
|
void hhForce_Converge::RemovePhysics( const idPhysics *phys ) {
|
|
// physics of ent is stored each evaluate so we can compare pointers directly, rather than querying
|
|
// ent about it's physics. This is done because typically, physics objects are reported as removed
|
|
// during deconstruction of the entities.
|
|
if (ent.IsValid() && phys == physics) {
|
|
SetEntity(NULL);
|
|
}
|
|
}
|
|
|
|
void hhForce_Converge::SetRestoreTime( float time ) {
|
|
restoreTime = idMath::ClampFloat(0.02f, time, time);
|
|
}
|
|
|
|
void hhForce_Converge::SetTarget(idVec3 &newTarget) {
|
|
target = newTarget;
|
|
}
|
|
|
|
void hhForce_Converge::SetEntity(idEntity *entity, int id, const idVec3 &point) {
|
|
ent = entity;
|
|
bodyID = id;
|
|
offset = point;
|
|
physics = NULL;
|
|
}
|
|
|
|
void hhForce_Converge::SetAxisEntity(idEntity *entity) {
|
|
axisEnt = entity;
|
|
}
|
|
|