CAutomobile::Render; moved some math code into .cpp

This commit is contained in:
aap 2019-07-27 11:53:51 +02:00
parent e340400875
commit 0aaaab3622
4 changed files with 379 additions and 123 deletions

View file

@ -125,6 +125,24 @@ public:
m_matrix.pos.y = 0.0f;
m_matrix.pos.z = 0.0f;
}
void Scale(float scale)
{
// GTA treats this as 4x4 floats
m_matrix.right.x *= scale;
m_matrix.right.y *= scale;
m_matrix.right.z *= scale;
m_matrix.up.x *= scale;
m_matrix.up.y *= scale;
m_matrix.up.z *= scale;
m_matrix.at.x *= scale;
m_matrix.at.y *= scale;
m_matrix.at.z *= scale;
m_matrix.pos.x *= scale;
m_matrix.pos.y *= scale;
m_matrix.pos.z *= scale;
m_matrix.flags = 0;
}
void SetRotateXOnly(float angle){
float c = Cos(angle);
@ -192,40 +210,10 @@ public:
m_matrix.pos.y = 0.0f;
m_matrix.pos.z = 0.0f;
}
void SetRotate(float xAngle, float yAngle, float zAngle) {
float cX = Cos(xAngle);
float sX = Sin(xAngle);
float cY = Cos(yAngle);
float sY = Sin(yAngle);
float cZ = Cos(zAngle);
float sZ = Sin(zAngle);
void SetRotate(float xAngle, float yAngle, float zAngle);
void Rotate(float x, float y, float z);
m_matrix.right.x = cZ * cY - (sZ * sX) * sY;
m_matrix.right.y = (cZ * sX) * sY + sZ * cY;
m_matrix.right.z = -cX * sY;
m_matrix.up.x = -sZ * cX;
m_matrix.up.y = cZ * cX;
m_matrix.up.z = sX;
m_matrix.at.x = (sZ * sX) * cY + cZ * sY;
m_matrix.at.y = sZ * sY - (cZ * sX) * cY;
m_matrix.at.z = cX * cY;
m_matrix.pos.x = 0.0f;
m_matrix.pos.y = 0.0f;
m_matrix.pos.z = 0.0f;
}
void Reorthogonalise(void){
CVector &r = GetRight();
CVector &f = GetForward();
CVector &u = GetUp();
u = CrossProduct(r, f);
u.Normalise();
r = CrossProduct(f, u);
r.Normalise();
f = CrossProduct(u, r);
}
void Reorthogonalise(void);
void CopyOnlyMatrix(CMatrix *other){
m_matrix = other->m_matrix;
}
@ -245,35 +233,13 @@ public:
}
};
inline CMatrix&
Invert(const CMatrix &src, CMatrix &dst)
{
// GTA handles this as a raw 4x4 orthonormal matrix
// and trashes the RW flags, let's not do that
// actual copy of librw code:
RwMatrix *d = &dst.m_matrix;
const RwMatrix *s = &src.m_matrix;
d->right.x = s->right.x;
d->right.y = s->up.x;
d->right.z = s->at.x;
d->up.x = s->right.y;
d->up.y = s->up.y;
d->up.z = s->at.y;
d->at.x = s->right.z;
d->at.y = s->up.z;
d->at.z = s->at.z;
d->pos.x = -(s->pos.x*s->right.x +
s->pos.y*s->right.y +
s->pos.z*s->right.z);
d->pos.y = -(s->pos.x*s->up.x +
s->pos.y*s->up.y +
s->pos.z*s->up.z);
d->pos.z = -(s->pos.x*s->at.x +
s->pos.y*s->at.y +
s->pos.z*s->at.z);
d->flags = rwMATRIXTYPEORTHONORMAL;
return dst;
}
CMatrix &Invert(const CMatrix &src, CMatrix &dst);
CVector operator*(const CMatrix &mat, const CVector &vec);
CMatrix operator*(const CMatrix &m1, const CMatrix &m2);
CVector MultiplyInverse(const CMatrix &mat, const CVector &vec);
CVector Multiply3x3(const CMatrix &mat, const CVector &vec);
CVector Multiply3x3(const CVector &vec, const CMatrix &mat);
inline CMatrix
Invert(const CMatrix &matrix)
@ -282,64 +248,6 @@ Invert(const CMatrix &matrix)
return Invert(matrix, inv);
}
inline CVector
operator*(const CMatrix &mat, const CVector &vec)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y,
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z + mat.m_matrix.pos.z);
}
inline CMatrix
operator*(const CMatrix &m1, const CMatrix &m2)
{
CMatrix out;
RwMatrix *dst = &out.m_matrix;
const RwMatrix *src1 = &m1.m_matrix;
const RwMatrix *src2 = &m2.m_matrix;
dst->right.x = src1->right.x*src2->right.x + src1->up.x*src2->right.y + src1->at.x*src2->right.z;
dst->right.y = src1->right.y*src2->right.x + src1->up.y*src2->right.y + src1->at.y*src2->right.z;
dst->right.z = src1->right.z*src2->right.x + src1->up.z*src2->right.y + src1->at.z*src2->right.z;
dst->up.x = src1->right.x*src2->up.x + src1->up.x*src2->up.y + src1->at.x*src2->up.z;
dst->up.y = src1->right.y*src2->up.x + src1->up.y*src2->up.y + src1->at.y*src2->up.z;
dst->up.z = src1->right.z*src2->up.x + src1->up.z*src2->up.y + src1->at.z*src2->up.z;
dst->at.x = src1->right.x*src2->at.x + src1->up.x*src2->at.y + src1->at.x*src2->at.z;
dst->at.y = src1->right.y*src2->at.x + src1->up.y*src2->at.y + src1->at.y*src2->at.z;
dst->at.z = src1->right.z*src2->at.x + src1->up.z*src2->at.y + src1->at.z*src2->at.z;
dst->pos.x = src1->right.x*src2->pos.x + src1->up.x*src2->pos.y + src1->at.x*src2->pos.z + src1->pos.x;
dst->pos.y = src1->right.y*src2->pos.x + src1->up.y*src2->pos.y + src1->at.y*src2->pos.z + src1->pos.y;
dst->pos.z = src1->right.z*src2->pos.x + src1->up.z*src2->pos.y + src1->at.z*src2->pos.z + src1->pos.z;
return out;
}
inline CVector
MultiplyInverse(const CMatrix &mat, const CVector &vec)
{
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
return CVector(
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
}
inline CVector
Multiply3x3(const CMatrix &mat, const CVector &vec)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z,
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z);
}
inline CVector
Multiply3x3(const CVector &vec, const CMatrix &mat)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z,
mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z,
mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z);
}
class CCompressedMatrixNotAligned
{

View file

@ -4,6 +4,145 @@
// TODO: move more stuff into here
void
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
{
float cX = Cos(xAngle);
float sX = Sin(xAngle);
float cY = Cos(yAngle);
float sY = Sin(yAngle);
float cZ = Cos(zAngle);
float sZ = Sin(zAngle);
m_matrix.right.x = cZ * cY - (sZ * sX) * sY;
m_matrix.right.y = (cZ * sX) * sY + sZ * cY;
m_matrix.right.z = -cX * sY;
m_matrix.up.x = -sZ * cX;
m_matrix.up.y = cZ * cX;
m_matrix.up.z = sX;
m_matrix.at.x = (sZ * sX) * cY + cZ * sY;
m_matrix.at.y = sZ * sY - (cZ * sX) * cY;
m_matrix.at.z = cX * cY;
m_matrix.pos.x = 0.0f;
m_matrix.pos.y = 0.0f;
m_matrix.pos.z = 0.0f;
}
void
CMatrix::Rotate(float x, float y, float z)
{
// TODO? do this directly without creating another matrix
CMatrix rot;
rot.SetRotate(x, y, z);
*this = rot * *this;
}
void
CMatrix::Reorthogonalise(void)
{
CVector &r = GetRight();
CVector &f = GetForward();
CVector &u = GetUp();
u = CrossProduct(r, f);
u.Normalise();
r = CrossProduct(f, u);
r.Normalise();
f = CrossProduct(u, r);
}
CMatrix&
Invert(const CMatrix &src, CMatrix &dst)
{
// GTA handles this as a raw 4x4 orthonormal matrix
// and trashes the RW flags, let's not do that
// actual copy of librw code:
RwMatrix *d = &dst.m_matrix;
const RwMatrix *s = &src.m_matrix;
d->right.x = s->right.x;
d->right.y = s->up.x;
d->right.z = s->at.x;
d->up.x = s->right.y;
d->up.y = s->up.y;
d->up.z = s->at.y;
d->at.x = s->right.z;
d->at.y = s->up.z;
d->at.z = s->at.z;
d->pos.x = -(s->pos.x*s->right.x +
s->pos.y*s->right.y +
s->pos.z*s->right.z);
d->pos.y = -(s->pos.x*s->up.x +
s->pos.y*s->up.y +
s->pos.z*s->up.z);
d->pos.z = -(s->pos.x*s->at.x +
s->pos.y*s->at.y +
s->pos.z*s->at.z);
d->flags = rwMATRIXTYPEORTHONORMAL;
return dst;
}
CVector
operator*(const CMatrix &mat, const CVector &vec)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y,
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z + mat.m_matrix.pos.z);
}
CMatrix
operator*(const CMatrix &m1, const CMatrix &m2)
{
CMatrix out;
RwMatrix *dst = &out.m_matrix;
const RwMatrix *src1 = &m1.m_matrix;
const RwMatrix *src2 = &m2.m_matrix;
dst->right.x = src1->right.x*src2->right.x + src1->up.x*src2->right.y + src1->at.x*src2->right.z;
dst->right.y = src1->right.y*src2->right.x + src1->up.y*src2->right.y + src1->at.y*src2->right.z;
dst->right.z = src1->right.z*src2->right.x + src1->up.z*src2->right.y + src1->at.z*src2->right.z;
dst->up.x = src1->right.x*src2->up.x + src1->up.x*src2->up.y + src1->at.x*src2->up.z;
dst->up.y = src1->right.y*src2->up.x + src1->up.y*src2->up.y + src1->at.y*src2->up.z;
dst->up.z = src1->right.z*src2->up.x + src1->up.z*src2->up.y + src1->at.z*src2->up.z;
dst->at.x = src1->right.x*src2->at.x + src1->up.x*src2->at.y + src1->at.x*src2->at.z;
dst->at.y = src1->right.y*src2->at.x + src1->up.y*src2->at.y + src1->at.y*src2->at.z;
dst->at.z = src1->right.z*src2->at.x + src1->up.z*src2->at.y + src1->at.z*src2->at.z;
dst->pos.x = src1->right.x*src2->pos.x + src1->up.x*src2->pos.y + src1->at.x*src2->pos.z + src1->pos.x;
dst->pos.y = src1->right.y*src2->pos.x + src1->up.y*src2->pos.y + src1->at.y*src2->pos.z + src1->pos.y;
dst->pos.z = src1->right.z*src2->pos.x + src1->up.z*src2->pos.y + src1->at.z*src2->pos.z + src1->pos.z;
return out;
}
CVector
MultiplyInverse(const CMatrix &mat, const CVector &vec)
{
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
return CVector(
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
}
CVector
Multiply3x3(const CMatrix &mat, const CVector &vec)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z,
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z);
}
CVector
Multiply3x3(const CVector &vec, const CMatrix &mat)
{
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z,
mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z,
mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z);
}
void
CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, float invSin, float t)
{

View file

@ -168,7 +168,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fCarGunLR = 0.0f;
m_fCarGunUD = 0.05f;
m_fWindScreenRotation = 0.0f;
m_fPropellerRotation = 0.0f;
m_weaponDoorTimerLeft = 0.0f;
m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
@ -1203,8 +1203,216 @@ CAutomobile::Teleport(CVector pos)
}
WRAPPER void CAutomobile::PreRender(void) { EAXJMP(0x535B40); }
WRAPPER void CAutomobile::Render(void) { EAXJMP(0x539EA0); }
void
CAutomobile::Render(void)
{
int i;
CMatrix mat;
CVector pos;
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
// Rhino has no bonnet...what are we doing here?
CMatrix m;
CVector p;
m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
p = m.GetPosition();
m.SetRotateZ(m_fCarGunLR);
m.Translate(p);
m.UpdateRW();
}
CVector contactPoints[4]; // relative to model
CVector contactSpeeds[4]; // speed at contact points
CVector frontWheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f));
CVector rearWheelFwd = GetForward();
for(i = 0; i < 4; i++){
contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
contactSpeeds[i] = GetSpeed(contactPoints[i]);
if(i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)
m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], frontWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
else
m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], rearWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
m_aWheelRotation[i] += m_aWheelSpeed[i];
}
// Rear right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RB]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_REAR_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_REAR_RIGHT], 0.0f, 0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_RIGHT]));
else
mat.SetRotateX(m_aWheelRotation[CARWHEEL_REAR_RIGHT]);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]));
// Rear left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LB]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_REAR_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(-m_aWheelRotation[CARWHEEL_REAR_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]));
// Mid right wheel
if(m_aCarNodes[CAR_WHEEL_RM]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RM]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_REAR_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_REAR_RIGHT], 0.0f, 0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_RIGHT]));
else
mat.SetRotateX(m_aWheelRotation[CARWHEEL_REAR_RIGHT]);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RM]));
}
// Mid left wheel
if(m_aCarNodes[CAR_WHEEL_LM]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LM]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_REAR_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(-m_aWheelRotation[CARWHEEL_REAR_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LM]));
}
if(GetModelIndex() == MI_DODO){
// Front wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle+0.3f*Sin(m_aWheelRotation[CARWHEEL_FRONT_RIGHT]));
else
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Rotate propeller
if(m_aCarNodes[CAR_WINDSCREEN]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN]));
pos = mat.GetPosition();
mat.SetRotateY(m_fPropellerRotation);
mat.Translate(pos);
mat.UpdateRW();
m_fPropellerRotation += m_fGasPedal != 0.0f ? TWOPI/13.0f : TWOPI/26.0f;
if(m_fPropellerRotation > TWOPI)
m_fPropellerRotation -= TWOPI;
}
// Rudder
if(Damage.GetDoorStatus(DOOR_BOOT) != DOOR_STATUS_MISSING && m_aCarNodes[CAR_BOOT]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BOOT]));
pos = mat.GetPosition();
mat.SetRotate(0.0f, 0.0f, -m_fSteerAngle);
mat.Rotate(0.0f, Sin(m_fSteerAngle)*DEGTORAD(22.0f), 0.0f);
mat.Translate(pos);
mat.UpdateRW();
}
ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
}else if(GetModelIndex() == MI_RHINO){
// Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
// no damaged wheels or steering
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, 0.0f);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Front left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_FRONT_LEFT];
// no damaged wheels or steering
mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]));
}else{
// Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle+0.3f*Sin(m_aWheelRotation[CARWHEEL_FRONT_RIGHT]));
else
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Front left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
pos.x = mat.GetPosition().x;
pos.y = mat.GetPosition().y;
pos.z = m_aWheelPosition[CARWHEEL_FRONT_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI+m_fSteerAngle+0.3f*Sin(-m_aWheelRotation[CARWHEEL_FRONT_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI+m_fSteerAngle);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
if(CVehicle::bWheelsOnlyCheat)
RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]));
ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
ProcessSwingingDoor(CAR_DOOR_LR, DOOR_REAR_LEFT);
ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
mi->SetVehicleColour(m_currentColour1, m_currentColour2);
}
if(!CVehicle::bWheelsOnlyCheat)
CEntity::Render();
}
int32
CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
@ -3600,6 +3808,7 @@ STARTPATCHES
InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP);
InjectHook(0x531470, &CAutomobile_::ProcessControl_, PATCH_JUMP);
InjectHook(0x535180, &CAutomobile_::Teleport_, PATCH_JUMP);
InjectHook(0x539EA0, &CAutomobile_::Render_, PATCH_JUMP);
InjectHook(0x53B270, &CAutomobile_::ProcessEntityCollision_, PATCH_JUMP);
InjectHook(0x53B660, &CAutomobile_::ProcessControlInputs_, PATCH_JUMP);
InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP);

View file

@ -71,7 +71,7 @@ public:
float m_weaponDoorTimerRight;
float m_fCarGunLR;
float m_fCarGunUD;
float m_fWindScreenRotation;
float m_fPropellerRotation;
uint8 stuff4[4];
uint8 m_nWheelsOnGround;
uint8 m_nDriveWheelsOnGround;