etqw-sdk/source/game/vehicles/TransportComponents.h

1134 lines
37 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __GAME_VEHICLE_COMPONENTS_H__
#define __GAME_VEHICLE_COMPONENTS_H__
#include "../effects/Effects.h"
#include "../effects/WaterEffects.h"
#include "VehicleSuspension.h"
#include "Transport.h"
class sdVehicle;
class sdVehicleInput;
class sdDeclVehiclePart;
class sdTransport_AF;
class sdDeclAFPart;
class sdDeclRigidBodyPart;
class sdDeclVehiclePartSimple;
class sdDeclRigidBodyWheel;
class sdDeclRigidBodyHover;
class sdDeclRigidBodyRotor;
class sdTransport;
class sdTransport_RB;
class sdVehicle_RigidBody;
class sdVehicleSuspension;
class sdVehicleRigidBodyVtol;
class sdVehicleRigidBodyAntiGrav;
class sdPhysics_RigidBodyMultiple;
class sdVehicleDriveObject : public idClass {
public:
CLASS_PROTOTYPE( sdVehicleDriveObject );
sdVehicleDriveObject( void );
virtual ~sdVehicleDriveObject( void );
virtual int GetBodyId( void ) = 0;
virtual void GetBounds( idBounds& bounds ) = 0;
virtual void UpdatePrePhysics( const sdVehicleInput& input ) = 0;
virtual void UpdatePostPhysics( const sdVehicleInput& input ) = 0;
virtual void GetWorldOrigin( idVec3& vec ) = 0;
virtual void GetWorldAxis( idMat3& axis ) = 0;
virtual void GetWorldPhysicsOrigin( idVec3& vec ) { GetWorldOrigin( vec ); }
virtual void GetWorldPhysicsAxis( idMat3& axis ) { GetWorldAxis( axis ); }
virtual void Detach( bool createDebris, bool decay ) = 0;
virtual void Reattach( void ) = 0;
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision ) = 0;
virtual void Decay( void ) = 0;
virtual int Repair( int repair ) = 0;
virtual bool CanDamage( void ) = 0;
virtual const partDamageInfo_t* GetDamageInfo( void ) const = 0;
virtual int EvaluateContacts( contactInfo_t* list, contactInfoExt_t* listExt, int max ) { return 0; }
virtual int AddCustomConstraints( constraintInfo_t* list, int max ) { return 0; }
virtual void PostInit( void );
virtual bool UpdateSuspensionIK( void ) { return false; }
virtual void ClearSuspensionIK( void ) { ; }
virtual bool Mask( int mask ) const { return false; }
virtual bool DestroyFirst( void ) const { return false; }
virtual void CheckWater( const idVec3& waterBodyOrg, const idMat3& waterBodyAxis, idCollisionModel* waterBodyModel ) { ; }
virtual const sdDeclSurfaceType* GetSurfaceType( void ) const { return NULL; }
virtual sdTransport* GetParent( void ) const = 0;
virtual bool HasPhysics( void ) const { return false; }
bool IsHidden( void ) const { return hidden; }
void Hide( void );
void Show( void );
const char* Name( void ) const { return name; }
virtual idScriptObject* GetScriptObject( void ) const { return scriptObject; }
virtual void SetThrust( float thrust ) {};
virtual bool IsNetworked() { return false; }
virtual void ApplyNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& newState ) { ; }
virtual void ReadNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, const idBitMsg& msg ) const { ; }
virtual void WriteNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, idBitMsg& msg ) const { ; }
virtual bool CheckNetworkStateChanges( networkStateMode_t mode, const sdEntityStateNetworkData& baseState ) const { return false; }
virtual sdEntityStateNetworkData* CreateNetworkStructure( networkStateMode_t mode ) const { return NULL; }
virtual bool GoesInPartList() { return true; }
protected:
virtual void CreateExplosionDebris( void ) = 0;
virtual void CreateDecayDebris( void ) = 0;
bool hidden;
idScriptObject* scriptObject;
idStr name;
public:
// static stuff for scaling the amount of debris that can exist
enum debrisPriority_t {
PRIORITY_LOW = 0,
PRIORITY_MEDIUM,
PRIORITY_HIGH,
PRIORITY_EXTRA_HIGH
};
static bool CanAddDebris( debrisPriority_t priority, const idVec3& origin );
static void AddDebris( rvClientMoveable* debris, debrisPriority_t priority );
protected:
static const int MAX_DEBRIS = 128;
typedef idStaticList< rvClientEntityPtr< rvClientMoveable >, MAX_DEBRIS > debrisList_t;
static debrisList_t extraHighDebris;
static debrisList_t highDebris;
static debrisList_t mediumDebris;
static debrisList_t lowDebris;
};
class sdVehiclePart : public sdVehicleDriveObject {
public:
CLASS_PROTOTYPE( sdVehiclePart );
sdVehiclePart( void );
virtual ~sdVehiclePart( void );
void Init( const sdDeclVehiclePart& part );
virtual void OnKilled( void ) { }
void SetIndex( int _index ) { partIndex = _index; }
int GetIndex( void ) { return partIndex; }
void AddSurface( const char* surfaceName );
void HideSurfaces( void );
void ShowSurfaces( void );
virtual int GetBodyId( void ) { return bodyId; }
virtual void GetBounds( idBounds& bounds );
virtual void GetWorldOrigin( idVec3& vec );
virtual void GetWorldAxis( idMat3& axis );
virtual void UpdatePrePhysics( const sdVehicleInput& input ) { assert( false ); }
virtual void UpdatePostPhysics( const sdVehicleInput& input ) { }
virtual void Detach( bool createDebris, bool decay );
virtual void Reattach( void );
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision );
virtual void Decay( void );
virtual int Repair( int repair );
virtual jointHandle_t GetJoint( void ) const { return INVALID_JOINT; }
virtual bool CanDamage( void ) { return health > 0; }
virtual const partDamageInfo_t* GetDamageInfo( void ) const { return &damageInfo; }
virtual void CheckWater( const idVec3& waterBodyOrg, const idMat3& waterBodyAxis, idCollisionModel* waterBodyModel );
virtual idBounds CalcSurfaceBounds( jointHandle_t joint );
virtual bool DestroyFirst( void ) const { return flipMaster; }
// Callable by scripts
void Event_GetHealth( void );
void Event_GetOrigin( void );
void Event_GetAngles( void );
void Event_GetParent( void );
void Event_GetJoint( void );
protected:
virtual void CreateExplosionDebris( void );
virtual void CreateDecayDebris( void );
int health;
int maxHealth;
int oldcontents;
int oldclipmask;
int bodyId;
idList< int > surfaces;
int partIndex;
partDamageInfo_t damageInfo;
const idDeclEntityDef* brokenPart;
idBounds partBounds;
sdWaterEffects* waterEffects;
bool noAutoHide;
float flipPower;
bool flipMaster;
int reattachTime;
};
class sdVehiclePartSimple : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehiclePartSimple );
virtual sdTransport* GetParent( void ) const { return parent; }
virtual jointHandle_t GetJoint( void ) const { return joint; }
void Init( const sdDeclVehiclePart& part, sdTransport* _parent );
virtual void GetWorldAxis( idMat3& axis );
virtual void GetWorldOrigin( idVec3& vec );
virtual void GetWorldPhysicsOrigin( idVec3& vec );
virtual void GetWorldPhysicsAxis( idMat3& axis );
bool CanDamage( void ) { return health > 0; }
bool ShouldDisplayDebugInfo() const;
protected:
jointHandle_t joint;
sdTransport* parent;
};
class sdVehiclePartScripted : public sdVehiclePartSimple {
public:
CLASS_PROTOTYPE( sdVehiclePartScripted );
virtual void Init( const sdDeclVehiclePart& part, sdTransport* _parent );
virtual void OnKilled( void );
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision );
virtual void Decay( void ) { }
protected:
const sdProgram::sdFunction *onKilled;
const sdProgram::sdFunction *onPostDamage;
};
class sdVehicleRigidBodyPart : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyPart );
sdTransport_RB* GetRBParent( void ) { return parent; }
virtual sdTransport* GetParent( void ) const;
virtual jointHandle_t GetJoint( void ) const { return joint; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void GetWorldOrigin( idVec3& vec );
bool ShouldDisplayDebugInfo() const;
protected:
jointHandle_t joint;
sdTransport_RB* parent;
};
class sdVehicleRigidBodyPartSimple : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyPartSimple );
sdTransport_RB* GetRBParent( void ) { return parent; }
virtual sdTransport* GetParent( void ) const;
virtual jointHandle_t GetJoint( void ) const { return joint; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void GetWorldOrigin( idVec3& vec );
virtual void GetWorldPhysicsOrigin( idVec3& vec );
bool CanDamage( void ) { return health > 0; }
bool ShouldDisplayDebugInfo() const;
protected:
jointHandle_t joint;
sdTransport_RB* parent;
};
class sdVehicleRigidBodyWheel : public sdVehicleRigidBodyPartSimple {
private:
class sdSuspension : public sdVehicleSuspensionInterface {
public:
sdSuspension( void ) { }
void Init( sdVehicleRigidBodyWheel* owner ) { _owner = owner; }
virtual sdTransport* GetParent( void ) const { return _owner->GetParent(); }
virtual float GetOffset( void ) const { return _owner->wheelOffset; }
virtual jointHandle_t GetJoint( void ) const { return _owner->GetWheelJoint(); }
sdVehicleRigidBodyWheel* _owner;
};
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyWheel );
sdVehicleRigidBodyWheel( void );
virtual ~sdVehicleRigidBodyWheel( void );
void Init( const sdDeclVehiclePart& wheel, sdTransport_RB* _parent );
void TrackWheelInit( const sdDeclVehiclePart& track, int index, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
float GetLinearSpeed( void );
virtual int EvaluateContacts( contactInfo_t* list, contactInfoExt_t* listExt, int max );
void CalcForces( float& maxForce, float& velocity );
virtual bool Mask( int mask ) const { return mask & VPT_WHEEL ? true : false; }
virtual bool HasPhysics( void ) const { return true; }
bool HasDrive( void ) { return wheelFlags.hasDrive; }
bool HasSteering( void ) { return wheelFlags.hasSteering; }
bool HasInverseSteering( void ) { return wheelFlags.inverseSteering; }
bool SlowsOnLeft( void ) { return wheelFlags.slowsOnLeft; }
bool SlowsOnRight( void ) { return wheelFlags.slowsOnRight; }
bool IsLeftWheel( void ) { return wheelFlags.isLeftWheel; }
bool IsRightWheel( void ) { return !wheelFlags.isLeftWheel; }
const trace_t& GetGroundTrace( void ) const { return groundTrace; }
float GetInputSpeed( const sdVehicleInput& input );
const idVec3& GetRotationAxis( void ) const { return rotationAxis; }
jointHandle_t GetWheelJoint( void ) const { return joint; }
float GetWheelAngle( void ) const { return angle; }
bool HasVisualStateChanged( void ) const { return state.changed; }
void ResetVisualState( void ) { state.changed = false; }
const idMat3& GetFrictionAxes( void ) { return frictionAxes; }
virtual bool UpdateSuspensionIK( void );
virtual void ClearSuspensionIK( void );
idVec3 GetBaseWorldOrg( void ) const;
const idMat3& GetBaseAxes( void ) const { return baseAxes; }
void UpdateRotation( float speed );
bool IsGrounded( void ) const { return state.grounded; }
void DisableSuspension( bool disable ) { state.suspensionDisabled = disable; }
virtual void CheckWater( const idVec3& waterBodyOrg, const idMat3& waterBodyAxis, idCollisionModel* waterBodyModel );
void UpdateFriction( const sdVehicleInput& input );
void UpdateSkidding();
virtual const sdDeclSurfaceType* GetSurfaceType( void ) const { return state.grounded ? groundTrace.c.surfaceType : NULL; }
virtual bool IsNetworked() { return false; }
void UpdateSuspension( const sdVehicleInput& input );
void UpdateMotor( const sdVehicleInput& input, float motorForce );
virtual bool GoesInPartList() { return !wheelFlags.partOfTrack; }
protected:
void CommonInit( const sdDeclVehiclePart& part );
virtual void CreateDecayDebris( void );
typedef struct wheelFlags_s {
bool hasDrive : 1;
bool hasSteering : 1;
bool inverseSteering : 1;
bool slowsOnLeft : 1;
bool slowsOnRight : 1;
bool isLeftWheel : 1;
bool isFrontWheel : 1;
bool noRotation : 1;
bool noPhysics : 1;
bool hasHandBrake : 1;
bool partOfTrack : 1;
} wheelFlags_t;
typedef struct wheelState_s {
bool moving : 1;
bool steeringChanged : 1;
bool changed : 1;
bool grounded : 1;
bool rested : 1;
bool suspensionDisabled : 1;
bool spinning : 1;
bool setSteering : 1;
bool skidding : 1;
} wheelState_t;
wheelFlags_t wheelFlags;
float steerScale;
float steerAngle;
float idealSteerAngle;
float angle;
float rotationspeed;
float radius;
float velocityScale;
idVec3 currentFriction;
idVec3 normalFriction;
wheelState_t state;
idMat3 frictionAxes;
float motorForce;
float motorSpeed;
idClipModel* wheelModel;
idVec3 rotationAxis;
float brakingForce;
float handBrakeSlipScale;
float maxSlip;
idList< float > traction;
idLinkList< sdEffect > activeEffects;
float wheelSpinForceThreshold;
float wheelSkidVelocityThreshold;
sdSuspension suspensionInterface;
sdVehicleSuspension* suspension;
float wheelOffset;
typedef struct suspensionInfo_s {
float upTrace;
float downTrace;
float totalDist;
float kCompress;
float damping;
float velocityScale;
float maxRestVelocity;
float base;
float range;
bool aggressiveDampening;
float slowScale;
float slowScaleSpeed;
float hardStopScale;
bool alternateSuspensionModel;
} suspensionInfo_t;
suspensionInfo_t suspensionInfo;
idVec3 baseOrg;
idVec3 baseOrgOffset;
idMat3 baseAxes;
trace_t groundTrace;
float suspensionForce;
float suspensionVelocity;
vehicleEffectList_t dustEffects;
vehicleEffectList_t spinEffects;
vehicleEffectList_t skidEffects;
int numSurfaceTypesAtSpawn;
unsigned int treadId;
bool stroggTread;
// Stuff to allow wheel traces to be throttled instead of all run every frame
int traceIndex;
int totalWheels;
// 16 is sufficient to cover some unplayable pings - 500+
const static int MAX_WHEEL_MEMORY = 16;
idStaticList< float, MAX_WHEEL_MEMORY > wheelFractionMemory;
int currentMemoryFrame;
int currentMemoryIndex;
protected:
void UpdateRotation( const sdVehicleInput& input );
void UpdateParticles( const sdVehicleInput& input );
};
class sdVehicleTrack : public sdVehicleDriveObject {
public :
CLASS_PROTOTYPE( sdVehicleTrack );
virtual ~sdVehicleTrack( void );
void Init( const sdDeclVehiclePart& track, sdTransport_RB* _parent );
virtual int GetBodyId( void ) { return -1; }
virtual int GetSurfaceId( void ) { return -1; }
virtual void GetBounds( idBounds& bounds ) { }
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual void GetWorldOrigin( idVec3& vec ) { vec = vec3_origin; }
virtual void GetWorldAxis( idMat3& axis ) { axis = mat3_identity; }
virtual void Detach( bool createDebris, bool decay ) { }
virtual void Reattach( void ) { }
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision ) { }
virtual void Decay( void ) { };
virtual int Repair( int repair ) { return 0; }
virtual bool CanDamage( void ) { return false; }
virtual const partDamageInfo_t* GetDamageInfo( void ) const { return NULL; }
virtual void PostInit( void );
float GetInputSpeed( const sdVehicleInput& input ) const;
bool IsLeftTrack( void ) const { return leftTrack; }
virtual int EvaluateContacts( contactInfo_t* list, contactInfoExt_t* listExt, int max );
virtual void CheckWater( const idVec3& waterBodyOrg, const idMat3& waterBodyAxis, idCollisionModel* waterBodyModel );
virtual const sdDeclSurfaceType* GetSurfaceType( void ) const;
virtual sdTransport* GetParent( void ) const;
virtual bool HasPhysics( void ) const { return true; }
virtual bool UpdateSuspensionIK( void );
virtual void ClearSuspensionIK( void );
bool IsGrounded( void ) const;
protected:
const static int TRACK_MAX_WHEELS = 8;
virtual void CreateExplosionDebris( void ) { }
virtual void CreateDecayDebris( void ) { }
sdTransport_RB* parent;
jointHandle_t joint;
int shaderParmIndex;
idVec3 direction;
idStaticList< sdVehicleRigidBodyWheel*, TRACK_MAX_WHEELS > wheels;
bool leftTrack;
const sdDeclVehiclePart* spawnPart;
};
class sdVehicleThruster : public sdVehicleDriveObject {
public :
CLASS_PROTOTYPE( sdVehicleThruster );
void Init( const sdDeclVehiclePart& thruster, sdTransport_RB* _parent );
virtual bool HasPhysics( void ) const { return true; }
virtual int GetBodyId( void ) { return -1; }
virtual int GetSurfaceId( void ) { return -1; }
virtual void GetBounds( idBounds& bounds ) { }
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input ) { }
virtual void GetWorldOrigin( idVec3& vec ) { vec = vec3_origin; }
virtual void GetWorldAxis( idMat3& axis ) { axis = mat3_identity; }
virtual void Detach( bool createDebris, bool decay ) { }
virtual void Reattach( void ) { }
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision ) { }
virtual void Decay( void ) { };
virtual int Repair( int repair ) { return 0; }
virtual bool CanDamage( void ) { return false; }
virtual const partDamageInfo_t* GetDamageInfo( void ) const { return NULL; }
virtual void CheckWater( const idVec3& waterBodyOrg, const idMat3& waterBodyAxis, idCollisionModel* waterBodyModel );
virtual sdTransport* GetParent( void ) const;
void CalcPos( idVec3& pos );
bool IsInWater( void ) const { return inWater; }
float GetThrust( void ) const { return thrustScale; }
virtual void SetThrust( float thrust );
void Event_SetThrust( float thrust );
protected:
virtual void CreateExplosionDebris( void ) { }
virtual void CreateDecayDebris( void ) { }
sdTransport_RB* parent;
idVec3 direction;
idVec3 fixedDirection;
idVec3 origin;
bool needWater;
bool inWater;
float thrustScale;
float reverseScale;
};
class sdVehicleAirBrake : public sdVehicleDriveObject {
public :
CLASS_PROTOTYPE( sdVehicleAirBrake );
void Init( const sdDeclVehiclePart& airBrake, sdTransport_RB* _parent );
virtual bool HasPhysics( void ) const { return true; }
virtual int GetBodyId( void ) { return -1; }
virtual int GetSurfaceId( void ) { return -1; }
virtual void GetBounds( idBounds& bounds ) { }
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input ) { }
virtual void GetWorldOrigin( idVec3& vec ) { vec = vec3_origin; }
virtual void GetWorldAxis( idMat3& axis ) { axis = mat3_identity; }
virtual void Detach( bool createDebris, bool decay ) { }
virtual void Reattach( void ) { }
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision ) { }
virtual void Decay( void ) { }
virtual int Repair( int repair ) { return 0; }
virtual bool CanDamage( void ) { return false; }
virtual const partDamageInfo_t* GetDamageInfo( void ) const { return NULL; }
virtual sdTransport* GetParent( void ) const { return parent; }
void Enable( void ) { enabled = true; }
void Disable( void ) { enabled = false; }
protected:
virtual void CreateExplosionDebris( void ) { }
virtual void CreateDecayDebris( void ) { }
sdTransport* parent;
bool enabled;
float factor;
float maxSpeed;
};
class sdVehicleSuspensionPoint : public sdVehicleDriveObject {
class sdSuspension : public sdVehicleSuspensionInterface {
public:
sdSuspension( void ) { }
void Init( sdVehicleSuspensionPoint* owner ) { _owner = owner; }
virtual sdTransport* GetParent( void ) const { return _owner->GetParent(); }
virtual float GetOffset( void ) const { return _owner->offset; }
virtual jointHandle_t GetJoint( void ) const { return _owner->joint; }
sdVehicleSuspensionPoint* _owner;
};
public :
CLASS_PROTOTYPE( sdVehicleSuspensionPoint );
sdVehicleSuspensionPoint( void );
~sdVehicleSuspensionPoint( void );
void Init( const sdDeclVehiclePart& point, sdTransport_RB* _parent );
virtual bool HasPhysics( void ) const { return true; }
virtual int GetBodyId( void ) { return -1; }
virtual int GetSurfaceId( void ) { return -1; }
virtual void GetBounds( idBounds& bounds ) { }
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input ) { }
virtual void GetWorldOrigin( idVec3& vec ) { vec = vec3_origin; }
virtual void GetWorldAxis( idMat3& axis ) { axis = mat3_identity; }
virtual void Detach( bool createDebris, bool decay ) { }
virtual void Reattach( void ) { }
virtual void Damage( int damage, idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const trace_t* collision ) { }
virtual void Decay( void ) { }
virtual int Repair( int repair ) { return 0; }
virtual bool CanDamage( void ) { return false; }
virtual const partDamageInfo_t* GetDamageInfo( void ) const { return NULL; }
virtual int EvaluateContacts( contactInfo_t* list, contactInfoExt_t* listExt, int max );
virtual sdTransport* GetParent( void ) const;
void CalcForces( float& maxForce, float& velocity, const idVec3& traceDir );
virtual bool UpdateSuspensionIK( void );
virtual void ClearSuspensionIK( void );
protected:
virtual void CreateExplosionDebris( void ) { }
virtual void CreateDecayDebris( void ) { }
typedef struct suspensionState_s {
bool grounded : 1;
bool rested : 1;
} suspensionState_t;
typedef struct suspensionInfo_s {
float totalDist;
float kCompress;
float damping;
float velocityScale;
} suspensionInfo_t;
suspensionInfo_t suspensionInfo;
sdTransport_RB* parent;
float offset;
float radius;
jointHandle_t joint;
jointHandle_t startJoint;
idVec3 baseOrg;
idVec3 baseStartOrg;
trace_t groundTrace;
float suspensionForce;
float suspensionVelocity;
suspensionState_t state;
sdSuspension suspensionInterface;
sdVehicleSuspension* suspension;
idVec3 contactFriction;
idMat3 frictionAxes;
bool aggressiveDampening;
};
// FIXME: Split main and tail rotor into two seperate classes
class sdVehicleRigidBodyRotor : public sdVehicleRigidBodyPartSimple {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyRotor );
sdVehicleRigidBodyRotor( void );
virtual ~sdVehicleRigidBodyRotor( void );
void Init( const sdDeclVehiclePart& rotor, sdTransport_RB* _parent );
virtual bool HasPhysics( void ) const { return true; }
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
void UpdatePrePhysics_Main( const sdVehicleInput& input );
void UpdatePrePhysics_Tail( const sdVehicleInput& input );
void UpdatePostPhysics_Tail( const sdVehicleInput& input );
void UpdatePostPhysics_Main( const sdVehicleInput& input );
float GetSpeed( void ) const { return speed; }
float GetTopGoalSpeed( void ) const;
void ResetCollective( void );
float GetCollective( void ) const { return advanced.collective; }
void SetCollective( float value ) { advanced.collective = value; }
protected:
typedef struct advancedControls_s {
float cyclicBank;
float cyclicPitch;
float cyclicPitchRate;
float cyclicBankRate;
float collective;
} advancedControls_t;
typedef struct rotorJoint_s {
jointHandle_t joint;
idMat3 jointAxes;
float speedScale;
float angle;
bool isYaw;
} rotorJoint_t;
advancedControls_t advanced;
float liftCoefficient;
idList< rotorJoint_t > animJoints;
rotorType_t type;
float maxPitchDeflect;
float maxYawDeflect;
float sideScale;
float speed;
float oldPitch;
float oldYaw;
int lastYawChange;
int lastPitchChange;
float zOffset;
};
class sdVehicleRigidBodyHoverPad : public sdVehicleRigidBodyPartSimple {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyHoverPad );
sdVehicleRigidBodyHoverPad( void );
virtual ~sdVehicleRigidBodyHoverPad( void );
virtual bool HasPhysics( void ) const { return false; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual int EvaluateContacts( contactInfo_t* list, contactInfoExt_t* listExt, int max );
protected:
float maxTraceLength;
idVec3 traceDir;
// Initial positions of the joint
idVec3 baseOrg;
idMat3 baseAxes;
// Rot limits so they don't stick into the body
idAngles minAngles;
idAngles maxAngles;
// Movement info
idQuat currentAxes;
float adaptSpeed;
idVec3 lastVelocity;
// Lightning related
sdEffect engineEffect;
int nextBeamTime;
const sdDeclTargetInfo *beamTargetInfo;
int shaderParmIndex;
};
#define PSEUDO_HOVER_MAX_CASTS 8
class sdPseudoHoverBroadcastData : public sdEntityStateNetworkData {
public:
sdPseudoHoverBroadcastData( void ) { ; }
virtual void MakeDefault( void );
virtual void Write( idFile* file ) const;
virtual void Read( idFile* file );
bool parkMode;
bool foundPark;
bool lockedPark;
int startParkTime;
int endParkTime;
int lastParkUpdateTime;
idVec3 chosenParkOrigin;
idMat3 chosenParkAxis;
};
class sdPseudoHoverNetworkData : public sdEntityStateNetworkData {
public:
sdPseudoHoverNetworkData( void ) { ; }
virtual void MakeDefault( void );
virtual void Write( idFile* file ) const;
virtual void Read( idFile* file );
float lastFrictionScale;
};
class sdVehicleRigidBodyPseudoHover : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyPseudoHover );
sdVehicleRigidBodyPseudoHover( void );
virtual ~sdVehicleRigidBodyPseudoHover( void );
virtual bool HasPhysics( void ) const { return true; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual int AddCustomConstraints( constraintInfo_t* list, int max );
virtual sdTransport* GetParent( void ) const { return parent; }
virtual bool IsNetworked() { return true; }
virtual void ApplyNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& newState );
virtual void ReadNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, const idBitMsg& msg ) const;
virtual void WriteNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, idBitMsg& msg ) const;
virtual bool CheckNetworkStateChanges( networkStateMode_t mode, const sdEntityStateNetworkData& baseState ) const;
virtual sdEntityStateNetworkData* CreateNetworkStructure( networkStateMode_t mode ) const;
protected:
// hoverEvalState_t is just used to pass around to the various evaluation functions
// note that it DOES NOT store anything across frames.
typedef struct {
sdClipModelCollection clipLocale;
float timeStep;
// position
idVec3 origin;
idVec3 linVelocity;
// physical properties
float mass;
idVec3 gravity;
idMat3 inertiaTensor;
// orientation
idMat3 axis;
idVec3 angVelocity;
// game properties
sdPhysics_RigidBodyMultiple* physics;
idPlayer* driver;
// evaluation
idVec3 surfaceNormal;
idQuat surfaceQuat;
idMat3 surfaceAxis;
idVec3 hoverForce;
idVec3 drivingForce;
idVec3 frictionForce;
idQuat surfaceMatchingQuat;
idVec3 steeringAngVel;
} hoverEvalState_t;
void DoRepulsors();
void DoRepulsionForCast( const idVec3& start, const idVec3& end, float desiredFraction, const trace_t& trace, float& height, int numForces );
void CalculateSurfaceAxis();
void CalculateDrivingForce( const sdVehicleInput& input );
void CalculateFrictionForce( const sdVehicleInput& input );
void CalculateTilting( const sdVehicleInput& input );
void CalculateYaw( const sdVehicleInput& input );
void ChooseParkPosition();
void DoParkRepulsors();
// state
bool grounded;
sdTransport* parent;
idPlayer* oldDriver;
trace_t groundTrace;
float lastFrictionScale; // sync this!
hoverEvalState_t evalState;
idVec3 targetVelocity;
idQuat targetQuat;
//
// "park" mode
//
bool parkMode; // sync this!
int startParkTime; // sync this!
int endParkTime; // sync this!
int lastParkUpdateTime; // sync this!
idVec3 chosenParkOrigin; // sync this!
idMat3 chosenParkAxis; // sync this!
bool foundPark; // sync this!
bool lockedPark; // sync this!
int lastParkEffectTime;
int lastUnparkEffectTime;
// Physics tuning parameters
float hoverHeight;
float parkHeight;
float repulsionSpeedCoeff;
float repulsionSpeedHeight;
float repulsionSpeedMax;
float yawCoeff;
float fwdCoeff;
float fwdSpeedDampCoeff;
float fwdSpeedDampPower;
float fwdSpeedDampMax;
float frontCastPos;
float backCastPos;
float castOffset;
float maxSlope;
float slopeDropoff;
float parkTime;
idBounds mainBounds;
idClipModel* mainClipModel;
jointHandle_t effectJoint;
// casts
idStaticList< idVec3, PSEUDO_HOVER_MAX_CASTS > castStarts;
idStaticList< idVec3, PSEUDO_HOVER_MAX_CASTS > castDirections;
};
class sdVehicleRigidBodyVtol : public sdVehicleRigidBodyPartSimple {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyVtol );
sdVehicleRigidBodyVtol( void );
virtual ~sdVehicleRigidBodyVtol( void );
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
protected:
// Initial positions of the joints
int shoulderAxis;
int elbowAxis;
jointHandle_t elbowJoint;
jointHandle_t effectJoint;
idMat3 shoulderBaseAxes;
idMat3 elbowBaseAxes;
float oldShoulderAngle;
float oldElbowAngle;
// Parameters
float shoulderAngleScale, elbowAngleScale;
idVec2 shoulderAnglesBounds;
idVec2 elbowAnglesBounds;
sdEffect engineEffect;
// Radom movements of the hover
float noisePhase;
float noiseFreq;
float noiseAmplitude;
};
class sdVehicleRigidBodyAntiGrav : public sdVehiclePartSimple {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyAntiGrav );
sdVehicleRigidBodyAntiGrav( void );
virtual ~sdVehicleRigidBodyAntiGrav( void );
void Init( const sdDeclVehiclePart& part, sdTransport* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
void UpdateEffect();
void SetClientParent( rvClientEntity* p );
protected:
void SetupJoints( idAnimator* targetAnimator );
// Initial positions of the joints
idMat3 baseAxes;
// Parameters
idVec2 mountAnglesBounds;
sdEffect engineMainEffect;
sdEffect engineBoostEffect;
idVec3 oldVelocity;
float oldAngle;
// Axes and stuff
int rotAxis; // The engines will rotate around this axis
int tailUpAxis;
int tailSideAxis;
float fanRotation;
float targetAngle;
jointHandle_t fanJoint;
jointHandle_t tailJoint;
idStr fanJointName;
idStr tailJointName;
rvClientEntity* clientParent;
int lastGroundEffectsTime;
// fan speed stuff
float fanSpeedMultiplier;
float fanSpeedOffset;
float fanSpeedMax;
float fanSpeedRampRate;
float lastFanSpeed;
};
class sdVehicleRigidBodyDragPlane : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyDragPlane );
sdVehicleRigidBodyDragPlane( void );
virtual ~sdVehicleRigidBodyDragPlane( void );
virtual bool HasPhysics( void ) const { return true; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual sdTransport* GetParent( void ) const { return parent; }
protected:
sdTransport* parent;
idVec3 normal;
idVec3 origin; // point of application of the drag force
float coefficient;
float maxForce;
float minForce;
bool doubleSided;
bool useAngleScale;
};
class sdVehicleRigidBodyRudder : public sdVehicleRigidBodyDragPlane {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyRudder );
virtual bool HasPhysics( void ) const { return true; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
protected:
};
class sdVehicleRigidBodyHurtZone : public sdVehicleRigidBodyPart {
public:
CLASS_PROTOTYPE( sdVehicleRigidBodyHurtZone );
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
};
class sdVehicleAntiRoll : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleAntiRoll );
sdVehicleAntiRoll( void );
virtual ~sdVehicleAntiRoll( void );
virtual bool HasPhysics( void ) const { return true; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual int AddCustomConstraints( constraintInfo_t* list, int max );
virtual sdTransport* GetParent( void ) const { return parent; }
protected:
sdTransport_RB* parent;
float currentStrength;
bool active;
float startAngle;
float endAngle;
float strength;
bool needsGround;
};
class sdVehicleAntiPitch : public sdVehiclePart {
public:
CLASS_PROTOTYPE( sdVehicleAntiPitch );
sdVehicleAntiPitch( void );
virtual ~sdVehicleAntiPitch( void );
virtual bool HasPhysics( void ) const { return true; }
void Init( const sdDeclVehiclePart& part, sdTransport_RB* _parent );
virtual void UpdatePrePhysics( const sdVehicleInput& input );
virtual void UpdatePostPhysics( const sdVehicleInput& input );
virtual int AddCustomConstraints( constraintInfo_t* list, int max );
virtual sdTransport* GetParent( void ) const { return parent; }
protected:
sdTransport_RB* parent;
float currentStrength;
bool active;
float startAngle;
float endAngle;
float strength;
bool needsGround;
};
#endif // __GAME_VEHICLE_COMPONENTS_H__