mirror of
https://github.com/GTAmodding/re3.git
synced 2024-12-25 06:06:06 +00:00
CAutomobile::Render; moved some math code into .cpp
This commit is contained in:
parent
e340400875
commit
0aaaab3622
4 changed files with 379 additions and 123 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue