- 11
- 3
Всем привет!
Пытался повернуть персонажа на определенные игровые координаты через кватернион, но в результате получается полная вакханалия.
Большое спасибо @SR_team за открытые исходники
Пытался повернуть персонажа на определенные игровые координаты через кватернион, но в результате получается полная вакханалия.
Большое спасибо @SR_team за открытые исходники
Сам кватернион:
struct Quaternion {
float fW, fX, fY, fZ;
};
void SetQuaternion()( const Quaternion &quater ) {
float SquarredQuaterW = 0.0f, SquarredQuaterX = 0.0f, SquarredQuaterY = 0.0f, SquarredQuaterZ = 0.0f;
SquarredQuaterW = quater.fW * quater.fW;
SquarredQuaterX = quater.fX * quater.fX;
SquarredQuaterY = quater.fY * quater.fY;
SquarredQuaterZ = quater.fZ * quater.fZ;
right.fX = SquarredQuaterX - SquarredQuaterY - SquarredQuaterZ + SquarredQuaterW;
up.fY = SquarredQuaterY - SquarredQuaterX - SquarredQuaterZ + SquarredQuaterW;
at.fZ = SquarredQuaterZ - ( SquarredQuaterY + SquarredQuaterX ) + SquarredQuaterW;
float multXY = quater.fX * quater.fY;
float multWZ = quater.fW * quater.fZ;
up.fX = multWZ + multXY + multWZ + multXY;
right.fY = multXY - multWZ + multXY - multWZ;
float multXZ = quater.fX * quater.fZ;
float multWY = quater.fW * quater.fY;
at.fX = multXZ - multWY + multXZ - multWY;
right.fZ = multWY + multXZ + multWY + multXZ;
float multYZ = quater.fY * quater.fZ;
float multWX = quater.fW * quater.fX;
at.fY = multWX + multYZ + multWX + multYZ;
up.fZ = multYZ - multWX + multYZ - multWX;
}
Quaternion GetQuaternion() {
long double v13; // st7@1
long double v14; // st7@3
long double v15; // st5@5
float v16; // st6@5
float v17; // st7@5
long double v18; // st6@7
Quaternion result;
float v23; // [sp+10h] [bp-20h]@7
float v24; // [sp+18h] [bp-18h]@9
v13 = right.fX + up.fY + at.fZ + 1.0f;
if ( v13 < 0.0f ) v13 = 0.0f;
result.fW = (float)sqrt( v13 ) * 0.5f;
v14 = right.fX + 1.0 - up.fY - at.fZ;
if ( v14 < 0.0f ) v14 = 0.0f;
v17 = (float)sqrt( v14 ) * 0.5f;
v16 = 1.0f - right.fX;
v15 = up.fY + v16 - at.fZ;
if ( v15 < 0.0f ) v15 = 0.0f;
v23 = (float)sqrt( v15 ) * 0.5f;
v18 = v16 - up.fY + at.fZ;
if ( v18 < 0.0f ) v18 = 0.0f;
v24 = (float)sqrt( v18 ) * 0.5f;
if ( result.fW < 0.0f ) result.fW = 0.0f;
if ( v17 < 0.0f ) v17 = 0.0f;
if ( v23 < 0.0f ) v23 = 0.0f;
if ( v24 < 0.0f ) v24 = 0.0f;
result.fX = (float)copysign( v17, at.fY - up.fZ );
result.fY = (float)copysign( v23, right.fZ - at.fX );
result.fZ = (float)copysign( v24, up.fX - right.fY );
return result;
}
Функция поворота:
float GetAngleBetweenObjectsRad(float& x1, float& y1, float& x2, float& y2)
{
float kx, ky;
float t, a;
kx = x2 - x1;
ky = y2 - y1;
if (kx == 0) kx = 0.00001f;
t = kx / ky;
if (t < 0) t = -t;
a = (float)(180 * atan((float)t) / 3.1415);
if ((kx <= 0) && (ky <= 0)) a = 180 - a;
else if ((kx >= 0) && (ky >= 0)) a = 359.99999f - a;
else if ((kx >= 0) && (ky <= 0)) a = -(180 - a);
a = (a * 3.1415) / 180.0f;
return a;
}
void RotateTo(CVector& vec)
{
auto me = LOCAL_PLAYER->getPosition();
float angle = -GetAngleBetweenObjectsRad(me.fX, me.fY, vec.fX, vec.fY);
auto quat = GetQuaternion();
quat.fX = cosf(angle / 2);
quat.fW = sinf(angle / 2);
SetQuaternion(quat);
}