aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorariel- <ariel.silva305@gmail.com>2016-07-30 11:34:02 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-30 11:36:18 +0200
commit2967bf59b4a47837b85c995b732a6761c9c35f7e (patch)
tree58a617b694033317d816106186036cdfb564886d /src/server/game/Entities/GameObject
parentc271e196c8bb02705d8a3e4a7432bbc2959f0b1a (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.cpp92
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h23
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