CVehicle::ProcessWheel

This commit is contained in:
aap 2019-07-10 11:05:49 +02:00
parent 702cd00765
commit 1aeb34f547
3 changed files with 158 additions and 48 deletions

View File

@ -119,7 +119,9 @@ VALIDATE_SIZE(tHandlingData, 0xD8);
class cHandlingDataMgr class cHandlingDataMgr
{ {
float field_0; // unused it seems float field_0; // unused it seems
public:
float field_4; // wheel related float field_4; // wheel related
private:
float field_8; // float field_8; //
float field_C; // unused it seems float field_C; // unused it seems
float field_10; // float field_10; //

View File

@ -130,6 +130,47 @@ CVehicle::~CVehicle()
} }
} }
void
CVehicle::SetModelIndex(uint32 id)
{
CEntity::SetModelIndex(id);
m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0];
m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1];
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id);
}
bool
CVehicle::SetupLighting(void)
{
ActivateDirectional();
SetAmbientColoursForPedsCarsAndObjects();
if(bRenderScorched){
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
}else{
CVector coors = GetPosition();
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
if(!bHasBlip && lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}
}
return false;
}
void
CVehicle::RemoveLighting(bool reset)
{
CRenderer::RemoveVehiclePedLights(this, reset);
}
float
CVehicle::GetHeightAboveRoad(void)
{
return -1.0f * GetColModel()->boundingBox.min.z;
}
void void
CVehicle::FlyingControl(eFlightModel flightModel) CVehicle::FlyingControl(eFlightModel flightModel)
{ {
@ -192,47 +233,127 @@ CVehicle::FlyingControl(eFlightModel flightModel)
} }
void void
CVehicle::SetModelIndex(uint32 id) CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus)
{ {
CEntity::SetModelIndex(id); // BUG: using statics here is probably a bad idea
m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0]; static bool bAlreadySkidding = false; // this is never reset
m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1]; static bool bBraking;
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id); static bool bDriving;
}
bool // how much force we want to apply in these axes
CVehicle::SetupLighting(void) float fwd = 0.0f;
{ float right = 0.0f;
ActivateDirectional();
SetAmbientColoursForPedsCarsAndObjects();
if(bRenderScorched){ bBraking = brake != 0.0f;
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); if(bBraking)
thrust = 0.0f;
bDriving = thrust != 0.0f;
float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd);
float contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight);
if(*wheelState != WHEEL_STATE_0)
bAlreadySkidding = true;
*wheelState = WHEEL_STATE_0;
adhesion *= CTimer::GetTimeStep();
if(bAlreadySkidding)
adhesion *= m_handling->fTractionLoss;
// moving sideways
if(contactSpeedRight != 0.0f){
// exert opposing force
right = -contactSpeedRight/wheelsOnGround;
if(wheelStatus == WHEEL_STATUS_BURST){
float fwdspeed = min(contactSpeedFwd, 0.3f);
right += fwdspeed * CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
}
}
if(bDriving){
fwd = thrust;
// limit sideways force (why?)
if(right > 0.0f){
if(right > adhesion)
right = adhesion;
}else{ }else{
CVector coors = GetPosition(); if(right < -adhesion)
float lighting = CPointLights::GenerateLightsAffectingObject(&coors); right = -adhesion;
if(!bHasBlip && lighting != 1.0f){ }
SetAmbientAndDirectionalColours(lighting); }else if(contactSpeedFwd != 0.0f){
return true; fwd = -contactSpeedFwd/wheelsOnGround;
if(!bBraking){
if(m_fGasPedal < 0.01f){
if(GetModelIndex() == MI_RCBANDIT)
brake = 0.2f * mod_HandlingManager.field_4 / m_fMass;
else
brake = mod_HandlingManager.field_4 / m_fMass;
} }
} }
return false; if(brake > adhesion){
} if(fabs(contactSpeedFwd) > 0.005f)
*wheelState = WHEEL_STATE_STATIC;
}else {
if(fwd > 0.0f){
if(fwd > brake)
fwd = brake;
}else{
if(fwd < -brake)
fwd = -brake;
}
}
}
void if(sq(adhesion) < sq(right) + sq(fwd)){
CVehicle::RemoveLighting(bool reset) if(*wheelState != WHEEL_STATE_STATIC){
{ if(bDriving && contactSpeedFwd < 0.2f)
CRenderer::RemoveVehiclePedLights(this, reset); *wheelState = WHEEL_STATE_1;
else
*wheelState = WHEEL_STATE_2;
}
float l = sqrt(sq(right) + sq(fwd));
float tractionLoss = bAlreadySkidding ? 1.0f : m_handling->fTractionLoss;
right *= adhesion * tractionLoss / l;
fwd *= adhesion * tractionLoss / l;
}
if(fwd != 0.0f || right != 0.0f){
CVector direction = fwd*wheelFwd + right*wheelRight;
float speed = direction.Magnitude();
direction.Normalise();
float impulse = speed*m_fMass;
float turnImpulse = speed*GetMass(wheelContactPoint, direction);
ApplyMoveForce(impulse * direction);
ApplyTurnForce(turnImpulse * direction, wheelContactPoint);
}
} }
float float
CVehicle::GetHeightAboveRoad(void) CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius)
{ {
return -1.0f * GetColModel()->boundingBox.min.z; float angularVelocity;
switch(state){
case WHEEL_STATE_1:
angularVelocity = -1.1f; // constant speed forward
break;
case WHEEL_STATE_STATIC:
angularVelocity = 0.0f; // not moving
break;
default:
angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed
break;
}
return angularVelocity * CTimer::GetTimeStep();
} }
void void
CVehicle::ExtinguishCarFire(void) CVehicle::ExtinguishCarFire(void)
{ {
@ -269,24 +390,6 @@ CVehicle::ProcessDelayedExplosion(void)
} }
} }
float
CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius)
{
float angularVelocity;
switch(state){
case WHEEL_STATE_1:
angularVelocity = -1.1f; // constant speed forward
break;
case WHEEL_STATE_3:
angularVelocity = 0.0f; // not moving
break;
default:
angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed
break;
}
return angularVelocity * CTimer::GetTimeStep();
}
bool bool
CVehicle::IsLawEnforcementVehicle(void) CVehicle::IsLawEnforcementVehicle(void)
{ {
@ -669,9 +772,10 @@ STARTPATCHES
InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP);
InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP); InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP);
InjectHook(0x5512E0, &CVehicle::ProcessWheel, PATCH_JUMP);
InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP);
InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP); InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP);
InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP); InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP);
InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP);
InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP); InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP);
InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP); InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP);
InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP); InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP);

View File

@ -106,8 +106,10 @@ enum
enum tWheelState enum tWheelState
{ {
WHEEL_STATE_0 = 0,
WHEEL_STATE_1 = 1, // constant velocity WHEEL_STATE_1 = 1, // constant velocity
WHEEL_STATE_3 = 3, // not moving WHEEL_STATE_2 = 2, // normal
WHEEL_STATE_STATIC = 3, // not moving
}; };
enum eFlightModel enum eFlightModel
@ -249,6 +251,8 @@ public:
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; } bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
void FlyingControl(eFlightModel flightModel); void FlyingControl(eFlightModel flightModel);
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus);
void ExtinguishCarFire(void); void ExtinguishCarFire(void);
void ProcessDelayedExplosion(void); void ProcessDelayedExplosion(void);
float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius); float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius);