mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
[11529] Pack and send to client all gameobject's quaternion components which allows place gameobjects cornerwise.
Update '.gobject turn' command, now you have to specify 3 rotations to turn gameobject: rotation angles around z, y and x axes. Note to DB devs: use QuaternionCompressed::Unpack to extract rotations from the data that came with UPDATEFLAG_ROTATION.
This commit is contained in:
parent
ab50a7d3e9
commit
7c86d3f477
8 changed files with 70 additions and 48 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#include "BattleGroundAV.h"
|
||||
#include "Util.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include <G3D/Quat.h>
|
||||
|
||||
GameObject::GameObject() : WorldObject(),
|
||||
m_goInfo(NULL),
|
||||
|
|
@ -128,10 +129,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
|
|||
|
||||
SetObjectScale(goinfo->size);
|
||||
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
|
||||
|
||||
UpdateRotationFields(rotation2,rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3
|
||||
SetRotationQuat(rotation0,rotation1,rotation2,rotation3);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
|
@ -1632,34 +1630,60 @@ const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
|
|||
return GetName();
|
||||
}
|
||||
|
||||
void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/)
|
||||
using G3D::Quat;
|
||||
struct QuaternionCompressed
|
||||
{
|
||||
static double const atan_pow = atan(pow(2.0f, -20.0f));
|
||||
QuaternionCompressed() : m_raw(0) {}
|
||||
QuaternionCompressed(int64 val) : m_raw(val) {}
|
||||
QuaternionCompressed(const Quat& quat) { Set(quat); }
|
||||
|
||||
double f_rot1 = sin(GetOrientation() / 2.0f);
|
||||
double f_rot2 = cos(GetOrientation() / 2.0f);
|
||||
enum{
|
||||
PACK_COEFF_YZ = 1 << 20,
|
||||
PACK_COEFF_X = 1 << 21,
|
||||
};
|
||||
|
||||
int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f));
|
||||
int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
|
||||
|
||||
//float f_rot2 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
|
||||
//rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;
|
||||
|
||||
//float f_rot3 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
|
||||
//rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;
|
||||
|
||||
m_rotation = rotation;
|
||||
|
||||
if(rotation2==0.0f && rotation3==0.0f)
|
||||
void Set(const Quat& quat)
|
||||
{
|
||||
rotation2 = (float)f_rot1;
|
||||
rotation3 = (float)f_rot2;
|
||||
int8 w_sign = (quat.w >= 0 ? 1 : -1);
|
||||
int64 X = int32(quat.x * PACK_COEFF_X) * w_sign & ((1 << 22) - 1);
|
||||
int64 Y = int32(quat.y * PACK_COEFF_YZ) * w_sign & ((1 << 21) - 1);
|
||||
int64 Z = int32(quat.z * PACK_COEFF_YZ) * w_sign & ((1 << 21) - 1);
|
||||
m_raw = Z | (Y << 21) | (X << 42);
|
||||
}
|
||||
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
|
||||
Quat Unpack() const
|
||||
{
|
||||
double x = (double)(m_raw >> 42) / (double)PACK_COEFF_X;
|
||||
double y = (double)(m_raw << 22 >> 43) / (double)PACK_COEFF_YZ;
|
||||
double z = (double)(m_raw << 43 >> 43) / (double)PACK_COEFF_YZ;
|
||||
double w = 1 - (x * x + y * y + z * z);
|
||||
MANGOS_ASSERT(w >= 0);
|
||||
w = sqrt(w);
|
||||
|
||||
return Quat(x,y,z,w);
|
||||
}
|
||||
|
||||
int64 m_raw;
|
||||
};
|
||||
|
||||
void GameObject::SetRotationQuat(float qx, float qy, float qz, float qw)
|
||||
{
|
||||
Quat quat(qx, qy, qz, qw);
|
||||
// Temporary solution for gameobjects that has no rotation data in DB:
|
||||
if (qz == 0 && qw == 0)
|
||||
quat = Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), GetOrientation());
|
||||
|
||||
m_rotation = QuaternionCompressed(quat).m_raw;
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, quat.x);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, quat.y);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, quat.z);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, quat.w);
|
||||
}
|
||||
|
||||
void GameObject::SetRotationAngles(float z_rot, float y_rot, float x_rot)
|
||||
{
|
||||
Quat quat( G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot) );
|
||||
SetRotationQuat(quat.x, quat.y, quat.z, quat.w);
|
||||
}
|
||||
|
||||
bool GameObject::IsHostileTo(Unit const* unit) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue