This commit is contained in:
Daniel Gibson 2025-04-09 13:48:54 +02:00 committed by GitHub
commit aaa0376e9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 426 additions and 84 deletions

View file

@ -665,6 +665,11 @@ void idExplodable::Event_Explode( idEntity *activator ) {
idSpring
Enhancements (like Save/Restore functions) taken from FraggingFree by IvanTheB
https://github.com/IvanTheB/fraggingfree-dhewm3-sdk
https://www.moddb.com/mods/fragging-free
===============================================================================
*/
@ -672,37 +677,58 @@ CLASS_DECLARATION( idEntity, idSpring )
EVENT( EV_PostSpawn, idSpring::Event_LinkSpring )
END_CLASS
/*
================
idSpring::idSpring
================
*/
idSpring::idSpring( void ){
ent1 = NULL;
ent2 = NULL;
id1 = 0;
id2 = 0;
p1 = vec3_origin;
p2 = vec3_origin;
enabled = false;
}
/*
================
idSpring::Think
================
*/
void idSpring::Think( void ) {
idVec3 start, end, origin;
idMat3 axis;
// run physics
RunPhysics();
if ( thinkFlags & TH_THINK ) {
// evaluate force
spring.Evaluate( gameLocal.time );
if ( enabled && ent1.GetEntity() && ent2.GetEntity() ) {
// evaluate force
spring.Evaluate( gameLocal.time );
start = p1;
if ( ent1->GetPhysics() ) {
axis = ent1->GetPhysics()->GetAxis();
origin = ent1->GetPhysics()->GetOrigin();
start = origin + start * axis;
if ( g_debugMover.GetBool() ) { //ivan
idVec3 start, end, origin;
idMat3 axis;
start = p1;
if ( ent1.GetEntity()->GetPhysics() ) {
axis = ent1.GetEntity()->GetPhysics()->GetAxis();
origin = ent1.GetEntity()->GetPhysics()->GetOrigin();
start = origin + start * axis;
}
end = p2;
if ( ent2.GetEntity()->GetPhysics() ) {
axis = ent2.GetEntity()->GetPhysics()->GetAxis();
origin = ent2.GetEntity()->GetPhysics()->GetOrigin();
end = origin + p2 * axis;
}
gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true );
}
} else {
BecomeInactive( TH_THINK );
}
end = p2;
if ( ent2->GetPhysics() ) {
axis = ent2->GetPhysics()->GetAxis();
origin = ent2->GetPhysics()->GetOrigin();
end = origin + p2 * axis;
}
gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true );
}
Present();
@ -721,8 +747,8 @@ void idSpring::Event_LinkSpring( void ) {
if ( name1.Length() ) {
ent1 = gameLocal.FindEntity( name1 );
if ( !ent1 ) {
gameLocal.Error( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() );
if ( !ent1.GetEntity() ) {
gameLocal.Warning( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() );
}
}
else {
@ -731,15 +757,20 @@ void idSpring::Event_LinkSpring( void ) {
if ( name2.Length() ) {
ent2 = gameLocal.FindEntity( name2 );
if ( !ent2 ) {
gameLocal.Error( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() );
if ( !ent2.GetEntity() ) {
gameLocal.Warning( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() );
}
}
else {
ent2 = gameLocal.entities[ENTITYNUM_WORLD];
}
spring.SetPosition( ent1->GetPhysics(), id1, p1, ent2->GetPhysics(), id2, p2 );
BecomeActive( TH_THINK );
if ( ent1.GetEntity() && ent2.GetEntity() ) {
spring.SetPosition( ent1.GetEntity()->GetPhysics(), id1, p1, ent2.GetEntity()->GetPhysics(), id2, p2 );
if( enabled ){
BecomeActive( TH_THINK );
}
}
}
/*
@ -748,8 +779,10 @@ idSpring::Spawn
================
*/
void idSpring::Spawn( void ) {
float Kstretch, damping, restLength;
float Kstretch, Kcompress, damping, restLength, maxLength;
bool pullEnt1 = true;
enabled = !spawnArgs.GetBool( "start_off" );
spawnArgs.GetInt( "id1", "0", id1 );
spawnArgs.GetInt( "id2", "0", id2 );
spawnArgs.GetVector( "point1", "0 0 0", p1 );
@ -757,14 +790,69 @@ void idSpring::Spawn( void ) {
spawnArgs.GetFloat( "constant", "100.0f", Kstretch );
spawnArgs.GetFloat( "damping", "10.0f", damping );
spawnArgs.GetFloat( "restlength", "0.0f", restLength );
spawnArgs.GetFloat( "maxLength", "200.0f", maxLength );
// DG: added compress and pullEntity1 so the corresponding parameter of idForce_Spring can be set
spawnArgs.GetFloat( "compress", "0.0f", Kcompress );
spawnArgs.GetBool( "pullEnt1", "1", pullEnt1 );
spring.InitSpring( Kstretch, 0.0f, damping, restLength );
spring.InitSpring( Kstretch, Kcompress, damping, restLength, maxLength, pullEnt1 );
ent1 = ent2 = NULL;
PostEventMS( &EV_PostSpawn, 0 );
}
/*
===============
idSpring::Activate
================
*/
void idSpring::Event_Activate( idEntity *activator ) {
enabled = !enabled;
if ( enabled ) {
BecomeActive( TH_THINK );
} else {
BecomeInactive( TH_THINK );
}
}
/*
================
idSpring::Save
================
*/
void idSpring::Save( idSaveGame *savefile ) const {
ent1.Save( savefile );
ent2.Save( savefile );
savefile->WriteInt( id1 );
savefile->WriteInt( id2 );
savefile->WriteVec3( p1 );
savefile->WriteVec3( p2 );
savefile->WriteBool( enabled );
savefile->WriteStaticObject( spring );
}
/*
================
idSpring::Restore
================
*/
void idSpring::Restore( idRestoreGame *savefile ) {
ent1.Restore( savefile );
ent2.Restore( savefile );
savefile->ReadInt( id1 );
savefile->ReadInt( id2 );
savefile->ReadVec3( p1 );
savefile->ReadVec3( p2 );
savefile->ReadBool( enabled );
savefile->ReadStaticObject( spring );
PostEventMS( &EV_PostSpawn, 0 ); //initialize the spring asap but not now!
}
/*
===============================================================================

View file

@ -203,6 +203,11 @@ private:
idSpring
Enhancements (like Save/Restore functions) taken from FraggingFree by IvanTheB
https://github.com/IvanTheB/fraggingfree-dhewm3-sdk
https://www.moddb.com/mods/fragging-free
===============================================================================
*/
@ -210,20 +215,26 @@ class idSpring : public idEntity {
public:
CLASS_PROTOTYPE( idSpring );
void Spawn( void );
idSpring(); //ivan
void Spawn( void );
virtual void Think( void );
void Save( idSaveGame *savefile ) const; //ivan
void Restore( idRestoreGame *savefile ); //ivan
virtual void Think( void );
private:
idEntity * ent1;
idEntity * ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
idEntityPtr<idEntity> ent1;
idEntityPtr<idEntity> ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
bool enabled; //ivan
void Event_LinkSpring( void );
void Event_LinkSpring( void );
void Event_Activate( idEntity *activator );
};

View file

@ -28,6 +28,7 @@ If you have questions concerning this license or the applicable additional terms
#include "sys/platform.h"
#include "physics/Physics.h"
#include "gamesys/SaveGame.h"
#include "physics/Force_Spring.h"
@ -44,6 +45,9 @@ idForce_Spring::idForce_Spring( void ) {
Kcompress = 100.0f;
damping = 0.0f;
restLength = 0.0f;
maxLength = 0.0f; // added by ivan for FraggingFree
pullEntity1 = false; // added by ivan for FraggingFree
physics1 = NULL;
id1 = 0;
p1 = vec3_zero;
@ -60,16 +64,72 @@ idForce_Spring::~idForce_Spring
idForce_Spring::~idForce_Spring( void ) {
}
//ivan start
/*
================
idForce_Spring::Save
================
*/
void idForce_Spring::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( Kstretch );
savefile->WriteFloat( Kcompress );
savefile->WriteFloat( damping );
savefile->WriteFloat( restLength );
savefile->WriteFloat( maxLength );
savefile->WriteBool( pullEntity1 );
/*
//Not saved:
savefile->WriteInt( id1 );
savefile->WriteInt( id2 );
savefile->WriteVec3( p1 );
savefile->WriteVec3( p2 );
physics1
physics2
*/
}
/*
================
idForce_Spring::Restore
================
*/
void idForce_Spring::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( Kstretch );
savefile->ReadFloat( Kcompress );
savefile->ReadFloat( damping );
savefile->ReadFloat( restLength );
savefile->ReadFloat( maxLength );
savefile->ReadBool( pullEntity1 );
/*
// Owner needs to call SetPosition before Evaluate!!
//Not saved:
savefile->ReadInt( id1 );
savefile->ReadInt( id2 );
savefile->ReadVec3( p1 );
savefile->ReadVec3( p2 );
physics1
physics2
*/
}
//ivan end
/*
================
idForce_Spring::InitSpring
================
*/
void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength ) {
void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength, float maxLength, bool pullEntity1 ) {
this->Kstretch = Kstretch;
this->Kcompress = Kcompress;
this->damping = damping;
this->restLength = restLength;
this->maxLength = maxLength;
this->pullEntity1 = pullEntity1;
}
/*
@ -125,11 +185,15 @@ void idForce_Spring::Evaluate( int time ) {
dampingForce = ( damping * ( ((velocity2 - velocity1) * force) / (force * force) ) ) * force;
length = force.Normalize();
if ( length > maxLength ) { //ff1.3
length = maxLength;
}
// if the spring is stretched
if ( length > restLength ) {
if ( Kstretch > 0.0f ) {
force = ( Square( length - restLength ) * Kstretch ) * force - dampingForce;
if ( physics1 ) {
if ( pullEntity1 && physics1 ) {
physics1->AddForce( id1, pos1, force );
}
if ( physics2 ) {
@ -140,7 +204,7 @@ void idForce_Spring::Evaluate( int time ) {
else {
if ( Kcompress > 0.0f ) {
force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce;
if ( physics1 ) {
if ( pullEntity1 && physics1 ) {
physics1->AddForce( id1, pos1, -force );
}
if ( physics2 ) {

View file

@ -46,8 +46,14 @@ public:
idForce_Spring( void );
virtual ~idForce_Spring( void );
// initialize the spring
void InitSpring( float Kstretch, float Kcompress, float damping, float restLength );
//ivan start
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
//ivan end
// initialize the spring - ivan added some arguments for FraggingFree
void InitSpring( float Kstretch, float Kcompress, float damping, float restLength, float maxLength, bool pullEntity1 );
// set the entities and positions on these entities the spring is attached to
void SetPosition( idPhysics *physics1, int id1, const idVec3 &p1,
idPhysics *physics2, int id2, const idVec3 &p2 );
@ -63,6 +69,8 @@ private:
float Kcompress;
float damping;
float restLength;
float maxLength; // added by FraggingFree
bool pullEntity1; // added by FraggingFree
// positioning
idPhysics * physics1; // first physics object

View file

@ -639,6 +639,11 @@ void idExplodable::Event_Explode( idEntity *activator ) {
idSpring
Enhancements (like Save/Restore functions) taken from FraggingFree by IvanTheB
https://github.com/IvanTheB/fraggingfree-dhewm3-sdk
https://www.moddb.com/mods/fragging-free
===============================================================================
*/
@ -646,37 +651,58 @@ CLASS_DECLARATION( idEntity, idSpring )
EVENT( EV_PostSpawn, idSpring::Event_LinkSpring )
END_CLASS
/*
================
idSpring::idSpring
================
*/
idSpring::idSpring( void ){
ent1 = NULL;
ent2 = NULL;
id1 = 0;
id2 = 0;
p1 = vec3_origin;
p2 = vec3_origin;
enabled = false;
}
/*
================
idSpring::Think
================
*/
void idSpring::Think( void ) {
idVec3 start, end, origin;
idMat3 axis;
// run physics
RunPhysics();
if ( thinkFlags & TH_THINK ) {
// evaluate force
spring.Evaluate( gameLocal.time );
if ( enabled && ent1.GetEntity() && ent2.GetEntity() ) {
// evaluate force
spring.Evaluate( gameLocal.time );
start = p1;
if ( ent1->GetPhysics() ) {
axis = ent1->GetPhysics()->GetAxis();
origin = ent1->GetPhysics()->GetOrigin();
start = origin + start * axis;
if ( g_debugMover.GetBool() ) { //ivan
idVec3 start, end, origin;
idMat3 axis;
start = p1;
if ( ent1.GetEntity()->GetPhysics() ) {
axis = ent1.GetEntity()->GetPhysics()->GetAxis();
origin = ent1.GetEntity()->GetPhysics()->GetOrigin();
start = origin + start * axis;
}
end = p2;
if ( ent2.GetEntity()->GetPhysics() ) {
axis = ent2.GetEntity()->GetPhysics()->GetAxis();
origin = ent2.GetEntity()->GetPhysics()->GetOrigin();
end = origin + p2 * axis;
}
gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true );
}
} else {
BecomeInactive( TH_THINK );
}
end = p2;
if ( ent2->GetPhysics() ) {
axis = ent2->GetPhysics()->GetAxis();
origin = ent2->GetPhysics()->GetOrigin();
end = origin + p2 * axis;
}
gameRenderWorld->DebugLine( idVec4(1, 1, 0, 1), start, end, 0, true );
}
Present();
@ -695,8 +721,8 @@ void idSpring::Event_LinkSpring( void ) {
if ( name1.Length() ) {
ent1 = gameLocal.FindEntity( name1 );
if ( !ent1 ) {
gameLocal.Error( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() );
if ( !ent1.GetEntity() ) {
gameLocal.Warning( "idSpring '%s' at (%s): cannot find first entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name1.c_str() );
}
}
else {
@ -705,15 +731,20 @@ void idSpring::Event_LinkSpring( void ) {
if ( name2.Length() ) {
ent2 = gameLocal.FindEntity( name2 );
if ( !ent2 ) {
gameLocal.Error( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() );
if ( !ent2.GetEntity() ) {
gameLocal.Warning( "idSpring '%s' at (%s): cannot find second entity '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), name2.c_str() );
}
}
else {
ent2 = gameLocal.entities[ENTITYNUM_WORLD];
}
spring.SetPosition( ent1->GetPhysics(), id1, p1, ent2->GetPhysics(), id2, p2 );
BecomeActive( TH_THINK );
if ( ent1.GetEntity() && ent2.GetEntity() ) {
spring.SetPosition( ent1.GetEntity()->GetPhysics(), id1, p1, ent2.GetEntity()->GetPhysics(), id2, p2 );
if( enabled ){
BecomeActive( TH_THINK );
}
}
}
/*
@ -722,8 +753,10 @@ idSpring::Spawn
================
*/
void idSpring::Spawn( void ) {
float Kstretch, damping, restLength;
float Kstretch, Kcompress, damping, restLength, maxLength;
bool pullEnt1 = true;
enabled = !spawnArgs.GetBool( "start_off" );
spawnArgs.GetInt( "id1", "0", id1 );
spawnArgs.GetInt( "id2", "0", id2 );
spawnArgs.GetVector( "point1", "0 0 0", p1 );
@ -731,14 +764,69 @@ void idSpring::Spawn( void ) {
spawnArgs.GetFloat( "constant", "100.0f", Kstretch );
spawnArgs.GetFloat( "damping", "10.0f", damping );
spawnArgs.GetFloat( "restlength", "0.0f", restLength );
spawnArgs.GetFloat( "maxLength", "200.0f", maxLength );
// DG: added compress and pullEntity1 so the corresponding parameter of idForce_Spring can be set
spawnArgs.GetFloat( "compress", "0.0f", Kcompress );
spawnArgs.GetBool( "pullEnt1", "1", pullEnt1 );
spring.InitSpring( Kstretch, 0.0f, damping, restLength );
spring.InitSpring( Kstretch, Kcompress, damping, restLength, maxLength, pullEnt1 );
ent1 = ent2 = NULL;
PostEventMS( &EV_PostSpawn, 0 );
}
/*
===============
idSpring::Activate
================
*/
void idSpring::Event_Activate( idEntity *activator ) {
enabled = !enabled;
if ( enabled ) {
BecomeActive( TH_THINK );
} else {
BecomeInactive( TH_THINK );
}
}
/*
================
idSpring::Save
================
*/
void idSpring::Save( idSaveGame *savefile ) const {
ent1.Save( savefile );
ent2.Save( savefile );
savefile->WriteInt( id1 );
savefile->WriteInt( id2 );
savefile->WriteVec3( p1 );
savefile->WriteVec3( p2 );
savefile->WriteBool( enabled );
savefile->WriteStaticObject( spring );
}
/*
================
idSpring::Restore
================
*/
void idSpring::Restore( idRestoreGame *savefile ) {
ent1.Restore( savefile );
ent2.Restore( savefile );
savefile->ReadInt( id1 );
savefile->ReadInt( id2 );
savefile->ReadVec3( p1 );
savefile->ReadVec3( p2 );
savefile->ReadBool( enabled );
savefile->ReadStaticObject( spring );
PostEventMS( &EV_PostSpawn, 0 ); //initialize the spring asap but not now!
}
/*
===============================================================================

View file

@ -198,6 +198,11 @@ private:
idSpring
Enhancements (like Save/Restore functions) taken from FraggingFree by IvanTheB
https://github.com/IvanTheB/fraggingfree-dhewm3-sdk
https://www.moddb.com/mods/fragging-free
===============================================================================
*/
@ -205,20 +210,26 @@ class idSpring : public idEntity {
public:
CLASS_PROTOTYPE( idSpring );
void Spawn( void );
idSpring(); //ivan
void Spawn( void );
virtual void Think( void );
void Save( idSaveGame *savefile ) const; //ivan
void Restore( idRestoreGame *savefile ); //ivan
virtual void Think( void );
private:
idEntity * ent1;
idEntity * ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
idEntityPtr<idEntity> ent1;
idEntityPtr<idEntity> ent2;
int id1;
int id2;
idVec3 p1;
idVec3 p2;
idForce_Spring spring;
bool enabled; //ivan
void Event_LinkSpring( void );
void Event_LinkSpring( void );
void Event_Activate( idEntity *activator );
};

View file

@ -28,6 +28,7 @@ If you have questions concerning this license or the applicable additional terms
#include "sys/platform.h"
#include "physics/Physics.h"
#include "gamesys/SaveGame.h"
#include "physics/Force_Spring.h"
@ -44,6 +45,9 @@ idForce_Spring::idForce_Spring( void ) {
Kcompress = 100.0f;
damping = 0.0f;
restLength = 0.0f;
maxLength = 0.0f; // added by ivan for FraggingFree
pullEntity1 = false; // added by ivan for FraggingFree
physics1 = NULL;
id1 = 0;
p1 = vec3_zero;
@ -60,16 +64,72 @@ idForce_Spring::~idForce_Spring
idForce_Spring::~idForce_Spring( void ) {
}
//ivan start
/*
================
idForce_Spring::Save
================
*/
void idForce_Spring::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( Kstretch );
savefile->WriteFloat( Kcompress );
savefile->WriteFloat( damping );
savefile->WriteFloat( restLength );
savefile->WriteFloat( maxLength );
savefile->WriteBool( pullEntity1 );
/*
//Not saved:
savefile->WriteInt( id1 );
savefile->WriteInt( id2 );
savefile->WriteVec3( p1 );
savefile->WriteVec3( p2 );
physics1
physics2
*/
}
/*
================
idForce_Spring::Restore
================
*/
void idForce_Spring::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( Kstretch );
savefile->ReadFloat( Kcompress );
savefile->ReadFloat( damping );
savefile->ReadFloat( restLength );
savefile->ReadFloat( maxLength );
savefile->ReadBool( pullEntity1 );
/*
// Owner needs to call SetPosition before Evaluate!!
//Not saved:
savefile->ReadInt( id1 );
savefile->ReadInt( id2 );
savefile->ReadVec3( p1 );
savefile->ReadVec3( p2 );
physics1
physics2
*/
}
//ivan end
/*
================
idForce_Spring::InitSpring
================
*/
void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength ) {
void idForce_Spring::InitSpring( float Kstretch, float Kcompress, float damping, float restLength, float maxLength, bool pullEntity1 ) {
this->Kstretch = Kstretch;
this->Kcompress = Kcompress;
this->damping = damping;
this->restLength = restLength;
this->maxLength = maxLength;
this->pullEntity1 = pullEntity1;
}
/*
@ -125,11 +185,15 @@ void idForce_Spring::Evaluate( int time ) {
dampingForce = ( damping * ( ((velocity2 - velocity1) * force) / (force * force) ) ) * force;
length = force.Normalize();
if ( length > maxLength ) { //ff1.3
length = maxLength;
}
// if the spring is stretched
if ( length > restLength ) {
if ( Kstretch > 0.0f ) {
force = ( Square( length - restLength ) * Kstretch ) * force - dampingForce;
if ( physics1 ) {
if ( pullEntity1 && physics1 ) {
physics1->AddForce( id1, pos1, force );
}
if ( physics2 ) {
@ -140,7 +204,7 @@ void idForce_Spring::Evaluate( int time ) {
else {
if ( Kcompress > 0.0f ) {
force = ( Square( length - restLength ) * Kcompress ) * force - dampingForce;
if ( physics1 ) {
if ( pullEntity1 && physics1 ) {
physics1->AddForce( id1, pos1, -force );
}
if ( physics2 ) {

View file

@ -46,8 +46,14 @@ public:
idForce_Spring( void );
virtual ~idForce_Spring( void );
// initialize the spring
void InitSpring( float Kstretch, float Kcompress, float damping, float restLength );
//ivan start
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
//ivan end
// initialize the spring - ivan added some arguments for FraggingFree
void InitSpring( float Kstretch, float Kcompress, float damping, float restLength, float maxLength, bool pullEntity1 );
// set the entities and positions on these entities the spring is attached to
void SetPosition( idPhysics *physics1, int id1, const idVec3 &p1,
idPhysics *physics2, int id2, const idVec3 &p2 );
@ -63,6 +69,8 @@ private:
float Kcompress;
float damping;
float restLength;
float maxLength; // added by FraggingFree
bool pullEntity1; // added by FraggingFree
// positioning
idPhysics * physics1; // first physics object