diff options
| author | ariel- <ariel.silva305@gmail.com> | 2016-07-30 11:34:02 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-07-30 11:36:18 +0200 |
| commit | 2967bf59b4a47837b85c995b732a6761c9c35f7e (patch) | |
| tree | 58a617b694033317d816106186036cdfb564886d /src/server/game/Entities/GameObject | |
| parent | c271e196c8bb02705d8a3e4a7432bbc2959f0b1a (diff) | |
Core/GameObjects: Gameobject rotation (from cmangos/mangos-wotlk@2bcbc0f) (#14146)
cmangos/mangos-wotlk@0fe88f35dfb: [11531] Normalize gameobject's quaternion, thanks to zergtmn for pointing
cmangos/mangos-wotlk@060dfb791b: [11667] Implement transport path rotation
cmangos/mangos-wotlk@565f52c6c1: [11806] A bit gameobject code refactoring
cmangos/mangos-wotlk@6874951: [11807] Add gameobject_addon table
Closes #14146
Diffstat (limited to 'src/server/game/Entities/GameObject')
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 92 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 23 |
2 files changed, 58 insertions, 57 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 2ff398fcba4..a403c07cbcc 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -51,9 +51,9 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_cooldownTime = 0; m_goInfo = nullptr; m_goData = nullptr; + m_packedRotation = 0.f; m_spawnId = 0; - m_rotation = 0; m_lootRecipientGroup = 0; m_groupLootTimer = 0; @@ -173,7 +173,7 @@ void GameObject::RemoveFromWorld() } } -bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit) +bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit) { ASSERT(map); SetMap(map); @@ -222,10 +222,15 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u return false; } - SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0); - SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1); + SetWorldRotation(rotation); + GameObjectAddon const* gameObjectAddon = sObjectMgr->GetGameObjectAddon(GetSpawnId()); - UpdateRotationFields(rotation2, rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3 + // For most of gameobjects is (0, 0, 0, 1) quaternion, there are only some transports with not standard rotation + G3D::Quat parentRotation; + if (gameObjectAddon) + parentRotation = gameObjectAddon->ParentRotation; + + SetParentRotation(parentRotation); SetObjectScale(goinfo->size); @@ -285,13 +290,10 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u break; } - if (GameObjectAddon const* addon = sObjectMgr->GetGameObjectAddon(GetSpawnId())) + if (gameObjectAddon && gameObjectAddon->InvisibilityValue) { - if (addon->InvisibilityValue) - { - m_invisibility.AddFlag(addon->invisibilityType); - m_invisibility.AddValue(addon->invisibilityType, addon->InvisibilityValue); - } + m_invisibility.AddFlag(gameObjectAddon->invisibilityType); + m_invisibility.AddValue(gameObjectAddon->invisibilityType, gameObjectAddon->InvisibilityValue); } LastUsedScriptID = GetGOInfo()->ScriptId; @@ -780,10 +782,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) data.posY = GetPositionY(); data.posZ = GetPositionZ(); data.orientation = GetOrientation(); - data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0); - data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1); - data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2); - data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3); + data.rotation = m_worldRotation; data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime; data.animprogress = GetGoAnimProgress(); data.go_state = GetGoState(); @@ -809,10 +808,10 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) stmt->setFloat(index++, GetPositionY()); stmt->setFloat(index++, GetPositionZ()); stmt->setFloat(index++, GetOrientation()); - stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION)); - stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+1)); - stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+2)); - stmt->setFloat(index++, GetFloatValue(GAMEOBJECT_PARENTROTATION+3)); + stmt->setFloat(index++, m_worldRotation.x); + stmt->setFloat(index++, m_worldRotation.y); + stmt->setFloat(index++, m_worldRotation.z); + stmt->setFloat(index++, m_worldRotation.w); stmt->setInt32(index++, int32(m_respawnDelayTime)); stmt->setUInt8(index++, GetGoAnimProgress()); stmt->setUInt8(index++, uint8(GetGoState())); @@ -839,17 +838,12 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo float z = data->posZ; float ang = data->orientation; - float rotation0 = data->rotation0; - float rotation1 = data->rotation1; - float rotation2 = data->rotation2; - float rotation3 = data->rotation3; - uint32 animprogress = data->animprogress; GOState go_state = data->go_state; uint32 artKit = data->artKit; m_spawnId = spawnId; - if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) + if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit)) return false; if (data->spawntimesecs >= 0) @@ -1899,34 +1893,38 @@ std::string const & GameObject::GetNameForLocaleIdx(LocaleConstant loc_idx) cons return GetName(); } -void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/) +void GameObject::UpdatePackedRotation() { - static double const atan_pow = atan(pow(2.0f, -20.0f)); + static const int32 PACK_YZ = 1 << 20; + static const int32 PACK_X = PACK_YZ << 1; - double f_rot1 = std::sin(GetOrientation() / 2.0f); - double f_rot2 = std::cos(GetOrientation() / 2.0f); + static const int32 PACK_YZ_MASK = (PACK_YZ << 1) - 1; + static const int32 PACK_X_MASK = (PACK_X << 1) - 1; - 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 = std::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 = std::sin(0.0f / 2.0f); - //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f)); - //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000; + int8 w_sign = (m_worldRotation.w >= 0.f ? 1 : -1); + int64 x = int32(m_worldRotation.x * PACK_X) * w_sign & PACK_X_MASK; + int64 y = int32(m_worldRotation.y * PACK_YZ) * w_sign & PACK_YZ_MASK; + int64 z = int32(m_worldRotation.z * PACK_YZ) * w_sign & PACK_YZ_MASK; + m_packedRotation = z | (y << 21) | (x << 42); +} - m_rotation = rotation; +void GameObject::SetWorldRotation(G3D::Quat const& rot) +{ + m_worldRotation = rot.toUnit(); + UpdatePackedRotation(); +} - if (rotation2 == 0.0f && rotation3 == 0.0f) - { - rotation2 = (float)f_rot1; - rotation3 = (float)f_rot2; - } +void GameObject::SetParentRotation(G3D::Quat const& rotation) +{ + SetFloatValue(GAMEOBJECT_PARENTROTATION + 0, rotation.x); + SetFloatValue(GAMEOBJECT_PARENTROTATION + 1, rotation.y); + SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, rotation.z); + SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, rotation.w); +} - SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2); - SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3); +void GameObject::SetWorldRotationAngles(float z_rot, float y_rot, float x_rot) +{ + SetWorldRotation(G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot))); } void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index eb263ddf299..af354f2aff6 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -25,6 +25,7 @@ #include "Object.h" #include "LootMgr.h" #include "DatabaseEnv.h" +#include <G3D/Quat.h> class GameObjectAI; class Group; @@ -603,6 +604,7 @@ struct GameObjectLocale // `gameobject_addon` table struct GameObjectAddon { + G3D::Quat ParentRotation; InvisibilityType invisibilityType; uint32 InvisibilityValue; }; @@ -622,8 +624,7 @@ enum GOState // from `gameobject` struct GameObjectData { - explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), - rotation0(0.0f), rotation1(0.0f), rotation2(0.0f), rotation3(0.0f), spawntimesecs(0), + explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), dbData(true) { } uint32 id; // entry in gamobject_template uint16 mapid; @@ -632,10 +633,7 @@ struct GameObjectData float posY; float posZ; float orientation; - float rotation0; - float rotation1; - float rotation2; - float rotation3; + G3D::Quat rotation; int32 spawntimesecs; uint32 animprogress; GOState go_state; @@ -677,7 +675,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void RemoveFromWorld() override; void CleanupsBeforeDelete(bool finalCleanup = true) override; - bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit = 0); + bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0); void Update(uint32 p_time) override; GameObjectTemplate const* GetGOInfo() const { return m_goInfo; } GameObjectData const* GetGOData() const { return m_goData; } @@ -689,7 +687,11 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> ObjectGuid::LowType GetSpawnId() const { return m_spawnId; } - void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f); + // z_rot, y_rot, x_rot - rotation angles around z, y and x axes + void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot); + void SetWorldRotation(G3D::Quat const& rot); + void SetParentRotation(G3D::Quat const& rotation); // transforms(rotates) transport's path + int64 GetPackedWorldRotation() const { return m_packedRotation; } // overwrite WorldObject function for proper name localization std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; @@ -847,7 +849,6 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void EventInform(uint32 eventId, WorldObject* invoker = NULL); - uint64 GetRotation() const { return m_rotation; } virtual uint32 GetScriptId() const { return GetGOInfo()->ScriptId; } GameObjectAI* AI() const { return m_AI; } @@ -902,7 +903,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> GameObjectData const* m_goData; GameObjectValue m_goValue; - uint64 m_rotation; + int64 m_packedRotation; + G3D::Quat m_worldRotation; Position m_stationaryPosition; ObjectGuid m_lootRecipient; @@ -911,6 +913,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> private: void RemoveFromOwner(); void SwitchDoorOrButton(bool activate, bool alternative = false); + void UpdatePackedRotation(); //! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size. bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const override |
