2019-05-15 10:52:37 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "Lists.h"
|
2019-05-19 15:28:10 -04:00
|
|
|
#include "Timer.h"
|
2019-05-15 10:52:37 -04:00
|
|
|
#include "Entity.h"
|
|
|
|
|
|
|
|
enum {
|
|
|
|
PHYSICAL_MAX_COLLISIONRECORDS = 6
|
|
|
|
};
|
|
|
|
|
2019-07-08 15:37:47 -04:00
|
|
|
#define GRAVITY (0.008f)
|
|
|
|
|
2019-07-08 02:46:42 -04:00
|
|
|
class CTreadable;
|
|
|
|
|
2019-05-15 10:52:37 -04:00
|
|
|
class CPhysical : public CEntity
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// The not properly indented fields haven't been checked properly yet
|
|
|
|
|
2019-06-29 05:09:33 -04:00
|
|
|
int32 m_audioEntityId;
|
2019-05-15 10:52:37 -04:00
|
|
|
float unk1;
|
2019-08-09 13:42:18 -04:00
|
|
|
CTreadable *m_treadable[2]; // car and ped
|
2019-05-15 10:52:37 -04:00
|
|
|
uint32 m_nLastTimeCollided;
|
|
|
|
CVector m_vecMoveSpeed; // velocity
|
|
|
|
CVector m_vecTurnSpeed; // angular velocity
|
|
|
|
CVector m_vecMoveFriction;
|
|
|
|
CVector m_vecTurnFriction;
|
|
|
|
CVector m_vecMoveSpeedAvg;
|
|
|
|
CVector m_vecTurnSpeedAvg;
|
|
|
|
float m_fMass;
|
|
|
|
float m_fTurnMass; // moment of inertia
|
2020-04-12 18:02:11 -04:00
|
|
|
float m_fForceMultiplier;
|
2019-05-15 10:52:37 -04:00
|
|
|
float m_fAirResistance;
|
|
|
|
float m_fElasticity;
|
2019-06-19 12:35:51 -04:00
|
|
|
float m_fBuoyancy;
|
2019-05-15 10:52:37 -04:00
|
|
|
CVector m_vecCentreOfMass;
|
|
|
|
CEntryInfoList m_entryInfoList;
|
|
|
|
CPtrNode *m_movingListNode;
|
|
|
|
|
|
|
|
char field_EC;
|
|
|
|
uint8 m_nStaticFrames;
|
|
|
|
uint8 m_nCollisionRecords;
|
2020-04-19 00:14:13 -04:00
|
|
|
bool m_bIsVehicleBeingShifted;
|
2019-05-15 10:52:37 -04:00
|
|
|
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
|
|
|
|
|
|
|
|
float m_fDistanceTravelled;
|
|
|
|
|
|
|
|
// damaged piece
|
2019-05-19 15:28:10 -04:00
|
|
|
float m_fDamageImpulse;
|
|
|
|
CEntity *m_pDamageEntity;
|
|
|
|
CVector m_vecDamageNormal;
|
|
|
|
int16 m_nDamagePieceType;
|
2019-05-15 10:52:37 -04:00
|
|
|
|
2019-06-02 13:33:41 -04:00
|
|
|
uint8 bIsHeavy : 1;
|
2019-05-15 10:52:37 -04:00
|
|
|
uint8 bAffectedByGravity : 1;
|
|
|
|
uint8 bInfiniteMass : 1;
|
2019-06-02 13:33:41 -04:00
|
|
|
uint8 bIsInWater : 1;
|
2020-04-19 00:14:13 -04:00
|
|
|
uint8 m_phy_flagA10 : 1; // unused
|
|
|
|
uint8 m_phy_flagA20 : 1; // unused
|
2019-07-29 13:18:03 -04:00
|
|
|
uint8 bHitByTrain : 1;
|
2020-04-30 11:58:15 -04:00
|
|
|
uint8 bSkipLineCol : 1;
|
2019-05-15 10:52:37 -04:00
|
|
|
|
2019-07-09 03:57:44 -04:00
|
|
|
uint8 m_nSurfaceTouched;
|
2019-10-02 21:02:02 -04:00
|
|
|
int8 m_nZoneLevel;
|
2019-05-15 10:52:37 -04:00
|
|
|
|
2019-06-12 14:07:37 -04:00
|
|
|
CPhysical(void);
|
|
|
|
~CPhysical(void);
|
2019-05-15 10:52:37 -04:00
|
|
|
|
|
|
|
// from CEntity
|
2019-07-08 02:46:42 -04:00
|
|
|
void Add(void);
|
|
|
|
void Remove(void);
|
|
|
|
CRect GetBoundRect(void);
|
|
|
|
void ProcessControl(void);
|
|
|
|
void ProcessShift(void);
|
|
|
|
void ProcessCollision(void);
|
|
|
|
|
2019-07-09 03:57:44 -04:00
|
|
|
virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *colpoints);
|
2019-05-17 08:08:18 -04:00
|
|
|
|
2019-05-15 10:52:37 -04:00
|
|
|
void RemoveAndAdd(void);
|
|
|
|
void AddToMovingList(void);
|
|
|
|
void RemoveFromMovingList(void);
|
2019-05-18 06:39:39 -04:00
|
|
|
void SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, CVector dir);
|
|
|
|
void AddCollisionRecord(CEntity *ent);
|
|
|
|
void AddCollisionRecord_Treadable(CEntity *ent);
|
|
|
|
bool GetHasCollidedWith(CEntity *ent);
|
|
|
|
void RemoveRefsToEntity(CEntity *ent);
|
2019-07-07 05:13:12 -04:00
|
|
|
static void PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phys, CVector localPos);
|
2019-05-15 10:52:37 -04:00
|
|
|
|
2019-05-19 15:28:10 -04:00
|
|
|
float GetDistanceSq(void) { return m_vecMoveSpeed.MagnitudeSqr() * sq(CTimer::GetTimeStep()); }
|
2019-05-15 10:52:37 -04:00
|
|
|
// get speed of point p relative to entity center
|
|
|
|
CVector GetSpeed(const CVector &r);
|
|
|
|
CVector GetSpeed(void) { return GetSpeed(CVector(0.0f, 0.0f, 0.0f)); }
|
|
|
|
float GetMass(const CVector &pos, const CVector &dir) {
|
|
|
|
return 1.0f / (CrossProduct(pos, dir).MagnitudeSqr()/m_fTurnMass +
|
|
|
|
1.0f/m_fMass);
|
|
|
|
}
|
|
|
|
float GetMassTime(const CVector &pos, const CVector &dir, float t) {
|
|
|
|
return 1.0f / (CrossProduct(pos, dir).MagnitudeSqr()/(m_fTurnMass*t) +
|
|
|
|
1.0f/(m_fMass*t));
|
|
|
|
}
|
|
|
|
void UnsetIsInSafePosition(void) {
|
|
|
|
m_vecMoveSpeed *= -1.0f;
|
|
|
|
m_vecTurnSpeed *= -1.0f;
|
|
|
|
ApplyTurnSpeed();
|
|
|
|
ApplyMoveSpeed();
|
|
|
|
m_vecMoveSpeed *= -1.0f;
|
|
|
|
m_vecTurnSpeed *= -1.0f;
|
|
|
|
bIsInSafePosition = false;
|
|
|
|
}
|
|
|
|
|
2019-07-07 05:13:12 -04:00
|
|
|
const CVector &GetMoveSpeed() { return m_vecMoveSpeed; }
|
2019-07-08 15:37:47 -04:00
|
|
|
void SetMoveSpeed(float x, float y, float z) {
|
|
|
|
m_vecMoveSpeed.x = x;
|
|
|
|
m_vecMoveSpeed.y = y;
|
|
|
|
m_vecMoveSpeed.z = z;
|
|
|
|
}
|
2019-08-06 17:32:19 -04:00
|
|
|
void SetMoveSpeed(const CVector& speed) {
|
|
|
|
m_vecMoveSpeed = speed;
|
|
|
|
}
|
2019-07-07 05:13:12 -04:00
|
|
|
const CVector &GetTurnSpeed() { return m_vecTurnSpeed; }
|
2019-07-08 15:37:47 -04:00
|
|
|
void SetTurnSpeed(float x, float y, float z) {
|
|
|
|
m_vecTurnSpeed.x = x;
|
|
|
|
m_vecTurnSpeed.y = y;
|
|
|
|
m_vecTurnSpeed.z = z;
|
|
|
|
}
|
|
|
|
const CVector &GetCenterOfMass() { return m_vecCentreOfMass; }
|
|
|
|
void SetCenterOfMass(float x, float y, float z) {
|
|
|
|
m_vecCentreOfMass.x = x;
|
|
|
|
m_vecCentreOfMass.y = y;
|
|
|
|
m_vecCentreOfMass.z = z;
|
|
|
|
}
|
2019-07-06 11:06:08 -04:00
|
|
|
|
2019-05-15 10:52:37 -04:00
|
|
|
void ApplyMoveSpeed(void);
|
|
|
|
void ApplyTurnSpeed(void);
|
|
|
|
// Force actually means Impulse here
|
|
|
|
void ApplyMoveForce(float jx, float jy, float jz);
|
|
|
|
void ApplyMoveForce(const CVector &j) { ApplyMoveForce(j.x, j.y, j.z); }
|
2019-07-05 08:23:39 -04:00
|
|
|
// j(x,y,z) is direction of force, p(x,y,z) is point relative to model center where force is applied
|
|
|
|
void ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz);
|
|
|
|
// j is direction of force, p is point relative to model center where force is applied
|
2019-05-15 10:52:37 -04:00
|
|
|
void ApplyTurnForce(const CVector &j, const CVector &p) { ApplyTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); }
|
|
|
|
void ApplyFrictionMoveForce(float jx, float jy, float jz);
|
|
|
|
void ApplyFrictionMoveForce(const CVector &j) { ApplyFrictionMoveForce(j.x, j.y, j.z); }
|
|
|
|
void ApplyFrictionTurnForce(float jx, float jy, float jz, float rx, float ry, float rz);
|
|
|
|
void ApplyFrictionTurnForce(const CVector &j, const CVector &p) { ApplyFrictionTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); }
|
2019-07-07 05:13:12 -04:00
|
|
|
// springRatio: 1.0 fully extended, 0.0 fully compressed
|
|
|
|
bool ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias);
|
|
|
|
bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed);
|
2019-05-15 10:52:37 -04:00
|
|
|
void ApplyGravity(void);
|
|
|
|
void ApplyFriction(void);
|
|
|
|
void ApplyAirResistance(void);
|
|
|
|
bool ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB);
|
|
|
|
bool ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CVector &moveSpeed, CVector &turnSpeed);
|
|
|
|
bool ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint);
|
|
|
|
bool ApplyFriction(float adhesiveLimit, CColPoint &colpoint);
|
|
|
|
|
2019-05-17 08:08:18 -04:00
|
|
|
bool ProcessShiftSectorList(CPtrList *ptrlists);
|
2019-05-18 06:39:39 -04:00
|
|
|
bool ProcessCollisionSectorList_SimpleCar(CPtrList *lists);
|
2019-05-19 15:28:10 -04:00
|
|
|
bool ProcessCollisionSectorList(CPtrList *lists);
|
|
|
|
bool CheckCollision(void);
|
|
|
|
bool CheckCollision_SimpleCar(void);
|
2019-05-15 10:52:37 -04:00
|
|
|
};
|
|
|
|
static_assert(sizeof(CPhysical) == 0x128, "CPhysical: error");
|