diff options
| author | Shauren <shauren.trinity@gmail.com> | 2018-03-28 22:01:22 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2020-06-27 20:23:30 +0200 |
| commit | 0468c70dfe91794ad272594323dd7feb611d0a93 (patch) | |
| tree | bb623c775fe215e4c0867fb2efa4bda0b360f7ec /src/common/Collision/Models | |
| parent | 54c701cf0db81c0062e8c5020e07db18984d0ffa (diff) | |
Core/Maps: Implemented getting area id from gameobject spawns
Yes, you can now spawn LK platform anywhere and it will treat you as inside Icecrown Citadel
(cherry picked from commit 42f9deb21ec68e169f7ed1c8cf14092f144b22da)
Diffstat (limited to 'src/common/Collision/Models')
| -rw-r--r-- | src/common/Collision/Models/GameObjectModel.cpp | 64 | ||||
| -rw-r--r-- | src/common/Collision/Models/GameObjectModel.h | 12 |
2 files changed, 74 insertions, 2 deletions
diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 54b48714c90..2c95187fbb2 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -146,6 +146,7 @@ bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> model #endif owner = std::move(modelOwner); + isWmo = it->second.isWmo; return true; } @@ -183,6 +184,69 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto return hit; } +void GameObjectModel::intersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const +{ + if (!(phasemask & ph_mask) || !owner->IsSpawned() || !isMapObject()) + return; + + if (!iBound.contains(point)) + return; + + // child bounds are defined in object space: + Vector3 pModel = iInvRot * (point - iPos) * iInvScale; + Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); + float zDist; + if (iModel->IntersectPoint(pModel, zDirModel, zDist, info)) + { + Vector3 modelGround = pModel + zDist * zDirModel; + float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; + if (info.ground_Z < world_Z) + info.ground_Z = world_Z; + } +} + +bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const +{ + if (!(phasemask & ph_mask) || !owner->IsSpawned() || !isMapObject()) + return false; + + if (!iBound.contains(point)) + return false; + + // child bounds are defined in object space: + Vector3 pModel = iInvRot * (point - iPos) * iInvScale; + Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); + float zDist; + if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info)) + { + Vector3 modelGround = pModel + zDist * zDirModel; + float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; + if (info.ground_Z < world_Z) + { + info.ground_Z = world_Z; + return true; + } + } + + return false; +} + +bool GameObjectModel::GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const +{ + // child bounds are defined in object space: + Vector3 pModel = iInvRot * (point - iPos) * iInvScale; + //Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); + float zDist; + if (info.hitModel->GetLiquidLevel(pModel, zDist)) + { + // calculate world height (zDist in model coords): + // assume WMO not tilted (wouldn't make much sense anyway) + liqHeight = zDist * iScale + iPos.z; + return true; + } + return false; +} + bool GameObjectModel::UpdatePosition() { if (!iModel) diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 99ffef0ee98..78f17b75391 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -29,6 +29,8 @@ namespace VMAP { class WorldModel; + struct AreaInfo; + struct LocationInfo; enum class ModelIgnoreFlags : uint32; } @@ -38,6 +40,8 @@ struct GameObjectDisplayInfoEntry; class TC_COMMON_API GameObjectModelOwnerBase { public: + virtual ~GameObjectModelOwnerBase() = default; + virtual bool IsSpawned() const = 0; virtual uint32 GetDisplayId() const = 0; virtual uint32 GetPhaseMask() const = 0; @@ -45,12 +49,11 @@ public: virtual float GetOrientation() const = 0; virtual float GetScale() const = 0; virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const = 0; - virtual ~GameObjectModelOwnerBase() { } }; class TC_COMMON_API GameObjectModel /*, public Intersectable*/ { - GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr) { } + GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr), isWmo(false) { } public: std::string name; @@ -65,8 +68,12 @@ public: void enable(uint32 ph_mask) { phasemask = ph_mask;} bool isEnabled() const {return phasemask != 0;} + bool isMapObject() const { return isWmo; } bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask, VMAP::ModelIgnoreFlags ignoreFlags) const; + void intersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const; + bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const; + bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const; static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath); @@ -83,6 +90,7 @@ private: float iScale; VMAP::WorldModel* iModel; std::unique_ptr<GameObjectModelOwnerBase> owner; + bool isWmo; }; TC_COMMON_API void LoadGameObjectModelList(std::string const& dataPath); |
