diff options
Diffstat (limited to 'src/common/Collision')
29 files changed, 307 insertions, 432 deletions
diff --git a/src/common/Collision/BoundingIntervalHierarchy.cpp b/src/common/Collision/BoundingIntervalHierarchy.cpp index 7e44771e82..9f15618425 100644 --- a/src/common/Collision/BoundingIntervalHierarchy.cpp +++ b/src/common/Collision/BoundingIntervalHierarchy.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/BoundingIntervalHierarchy.h b/src/common/Collision/BoundingIntervalHierarchy.h index d626bc86fc..84aa011394 100644 --- a/src/common/Collision/BoundingIntervalHierarchy.h +++ b/src/common/Collision/BoundingIntervalHierarchy.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -70,6 +70,7 @@ private: { tree.clear(); objects.clear(); + bounds = G3D::AABox::empty(); // create space for the first node tree.push_back(3u << 30u); // dummy leaf tree.insert(tree.end(), 2, 0); @@ -116,6 +117,7 @@ public: delete[] dat.indices; } [[nodiscard]] uint32 primCount() const { return objects.size(); } + G3D::AABox const& bound() const { return bounds; } template<typename RayCallback> void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const diff --git a/src/common/Collision/BoundingIntervalHierarchyWrapper.h b/src/common/Collision/BoundingIntervalHierarchyWrapper.h index 81c5f433a9..69aee48022 100644 --- a/src/common/Collision/BoundingIntervalHierarchyWrapper.h +++ b/src/common/Collision/BoundingIntervalHierarchyWrapper.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index 4fcfc55b49..0025bf9984 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -170,25 +170,6 @@ private: VMAP::ModelIgnoreFlags _ignoreFlags; }; -struct DynamicTreeAreaInfoCallback -{ - DynamicTreeAreaInfoCallback(uint32 phaseMask) : _phaseMask(phaseMask) { } - - void operator()(G3D::Vector3 const& p, GameObjectModel const& obj) - { - obj.IntersectPoint(p, _areaInfo, _phaseMask); - } - - VMAP::AreaInfo const& GetAreaInfo() const - { - return _areaInfo; - } - -private: - uint32 _phaseMask; - VMAP::AreaInfo _areaInfo; -}; - struct DynamicTreeLocationInfoCallback { DynamicTreeLocationInfoCallback(uint32 phaseMask) @@ -308,24 +289,7 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, } } -bool DynamicMapTree::GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const -{ - G3D::Vector3 v(x, y, z + 0.5f); - DynamicTreeAreaInfoCallback intersectionCallBack(phasemask); - impl->intersectPoint(v, intersectionCallBack); - if (intersectionCallBack.GetAreaInfo().result) - { - flags = intersectionCallBack.GetAreaInfo().flags; - adtId = intersectionCallBack.GetAreaInfo().adtId; - rootId = intersectionCallBack.GetAreaInfo().rootId; - groupId = intersectionCallBack.GetAreaInfo().groupId; - z = intersectionCallBack.GetAreaInfo().ground_Z; - return true; - } - return false; -} - -void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const +bool DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) const { G3D::Vector3 v(x, y, z + 0.5f); DynamicTreeLocationInfoCallback intersectionCallBack(phasemask); @@ -335,13 +299,16 @@ void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phas data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z; uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType(); float liquidLevel; - if (!reqLiquidType || (dynamic_cast<VMAP::VMapMgr2*>(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & reqLiquidType)) + if (!reqLiquidType || (dynamic_cast<VMAP::VMapMgr2*>(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & *reqLiquidType)) if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel)) data.liquidInfo.emplace(liquidType, liquidLevel); - data.areaInfo.emplace(0, + data.areaInfo.emplace(intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(), + 0, intersectionCallBack.GetLocationInfo().rootId, - intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(), - intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags()); + intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags(), + 0); + return true; } + return false; } diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h index c9dd5281bb..e2ddca550b 100644 --- a/src/common/Collision/DynamicTree.h +++ b/src/common/Collision/DynamicTree.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -19,6 +19,7 @@ #define _DYNTREE_H #include "Define.h" +#include "Optional.h" namespace G3D { @@ -47,8 +48,7 @@ public: bool GetIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const G3D::Vector3& endPos, float& maxDist) const; - bool GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; - void GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const; + bool GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) const; bool GetObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1, const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos, diff --git a/src/common/Collision/Management/IMMAPMgr.h b/src/common/Collision/Management/IMMAPMgr.h index e68f0ff488..49452c4a7b 100644 --- a/src/common/Collision/Management/IMMAPMgr.h +++ b/src/common/Collision/Management/IMMAPMgr.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Management/IVMapMgr.h b/src/common/Collision/Management/IVMapMgr.h index 260188e7b6..410743f768 100644 --- a/src/common/Collision/Management/IVMapMgr.h +++ b/src/common/Collision/Management/IVMapMgr.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -52,20 +52,23 @@ namespace VMAP { struct AreaInfo { - AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags) - : adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { } - int32 const adtId; - int32 const rootId; - int32 const groupId; - uint32 const mogpFlags; + AreaInfo() = default; + AreaInfo(int32 _groupId, int32 _adtId, int32 _rootId, uint32 _mogpFlags, uint32 _uniqueId) + : groupId(_groupId), adtId(_adtId), rootId(_rootId), mogpFlags(_mogpFlags), uniqueId(_uniqueId) { } + int32 groupId = 0; + int32 adtId = 0; + int32 rootId = 0; + uint32 mogpFlags = 0; + uint32 uniqueId = 0; }; struct LiquidInfo { + LiquidInfo() = default; LiquidInfo(uint32 _type, float _level) : type(_type), level(_level) {} - uint32 const type; - float const level; + uint32 type = 0; + float level = 0.0f; }; float floorZ = VMAP_INVALID_HEIGHT; @@ -120,14 +123,12 @@ namespace VMAP [[nodiscard]] bool isMapLoadingEnabled() const { return (iEnableLineOfSightCalc || iEnableHeightCalc ); } [[nodiscard]] virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0; + /** Query world model area info. \param z gets adjusted to the ground height for which this are info is valid */ - virtual bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0; - virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const = 0; - // get both area + liquid data in a single vmap lookup - virtual void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const = 0; + virtual bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) const = 0; }; } diff --git a/src/common/Collision/Management/MMapFactory.cpp b/src/common/Collision/Management/MMapFactory.cpp index 70a57726dd..4409bcc77e 100644 --- a/src/common/Collision/Management/MMapFactory.cpp +++ b/src/common/Collision/Management/MMapFactory.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Management/MMapFactory.h b/src/common/Collision/Management/MMapFactory.h index 08136b6fc9..923954ab40 100644 --- a/src/common/Collision/Management/MMapFactory.h +++ b/src/common/Collision/Management/MMapFactory.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Management/MMapMgr.cpp b/src/common/Collision/Management/MMapMgr.cpp index e08ecba790..d3c450097c 100644 --- a/src/common/Collision/Management/MMapMgr.cpp +++ b/src/common/Collision/Management/MMapMgr.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -23,9 +23,6 @@ namespace MMAP { - static char const* const MAP_FILE_NAME_FORMAT = "{}/mmaps/{:03}.mmap"; - static char const* const TILE_FILE_NAME_FORMAT = "{}/mmaps/{:03}{:02}{:02}.mmtile"; - // ######################## MMapMgr ######################## MMapMgr::~MMapMgr() { diff --git a/src/common/Collision/Management/MMapMgr.h b/src/common/Collision/Management/MMapMgr.h index 013f34292a..823142cde6 100644 --- a/src/common/Collision/Management/MMapMgr.h +++ b/src/common/Collision/Management/MMapMgr.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -39,6 +39,9 @@ inline void dtCustomFree(void* ptr) // move map related classes namespace MMAP { + static char const* const MAP_FILE_NAME_FORMAT = "{}/mmaps/{:03}.mmap"; + static char const* const TILE_FILE_NAME_FORMAT = "{}/mmaps/{:03}{:02}{:02}.mmtile"; + typedef std::unordered_map<uint32, dtTileRef> MMapTileSet; typedef std::unordered_map<uint32, dtNavMeshQuery*> NavMeshQuerySet; diff --git a/src/common/Collision/Management/VMapFactory.cpp b/src/common/Collision/Management/VMapFactory.cpp index 3303910966..034fdf1bed 100644 --- a/src/common/Collision/Management/VMapFactory.cpp +++ b/src/common/Collision/Management/VMapFactory.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Management/VMapFactory.h b/src/common/Collision/Management/VMapFactory.h index aa6ebd4ee8..1efae9643c 100644 --- a/src/common/Collision/Management/VMapFactory.h +++ b/src/common/Collision/Management/VMapFactory.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Management/VMapMgr2.cpp b/src/common/Collision/Management/VMapMgr2.cpp index 46df0b3301..7639c9c6bc 100644 --- a/src/common/Collision/Management/VMapMgr2.cpp +++ b/src/common/Collision/Management/VMapMgr2.cpp @@ -253,70 +253,8 @@ namespace VMAP return VMAP_INVALID_HEIGHT_VALUE; } - bool VMapMgr2::GetAreaInfo(uint32 mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const + bool VMapMgr2::GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) const { -#if defined(ENABLE_VMAP_CHECKS) - if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) -#endif - { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); - if (instanceTree != iInstanceMapTrees.end()) - { - Vector3 pos = convertPositionToInternalRep(x, y, z); - bool result = instanceTree->second->GetAreaInfo(pos, flags, adtId, rootId, groupId); - // z is not touched by convertPositionToInternalRep(), so just copy - z = pos.z; - return result; - } - } - - return false; - } - - bool VMapMgr2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const - { -#if defined(ENABLE_VMAP_CHECKS) - if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) -#endif - { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); - if (instanceTree != iInstanceMapTrees.end()) - { - LocationInfo info; - Vector3 pos = convertPositionToInternalRep(x, y, z); - if (instanceTree->second->GetLocationInfo(pos, info)) - { - floor = info.ground_Z; - ASSERT(floor < std::numeric_limits<float>::max()); - type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc - mogpFlags = info.hitModel->GetMogpFlags(); - if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType)) - { - return false; - } - if (info.hitInstance->GetLiquidLevel(pos, info, level)) - { - return true; - } - } - } - } - - return false; - } - - void VMapMgr2::GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const - { - if (IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) - { - data.floorZ = z; - int32 adtId, rootId, groupId; - uint32 flags; - if (GetAreaInfo(mapId, x, y, data.floorZ, flags, adtId, rootId, groupId)) - data.areaInfo.emplace(adtId, rootId, groupId, flags); - return; - } - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { @@ -325,16 +263,22 @@ namespace VMAP if (instanceTree->second->GetLocationInfo(pos, info)) { data.floorZ = info.ground_Z; - uint32 liquidType = info.hitModel->GetLiquidType(); - float liquidLevel; - if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & reqLiquidType)) - if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel)) - data.liquidInfo.emplace(liquidType, liquidLevel); + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) + { + uint32 liquidType = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc + float liquidLevel; + if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & *reqLiquidType)) + if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel)) + data.liquidInfo.emplace(liquidType, liquidLevel); + } if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) - data.areaInfo.emplace(info.hitInstance->adtId, info.rootId, info.hitModel->GetWmoID(), info.hitModel->GetMogpFlags()); + data.areaInfo.emplace(info.hitModel->GetWmoID(), info.hitInstance->adtId, info.rootId, info.hitModel->GetMogpFlags(), info.hitInstance->ID); + return true; } } + + return false; } WorldModel* VMapMgr2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */) diff --git a/src/common/Collision/Management/VMapMgr2.h b/src/common/Collision/Management/VMapMgr2.h index f025c8086c..5fc4106d21 100644 --- a/src/common/Collision/Management/VMapMgr2.h +++ b/src/common/Collision/Management/VMapMgr2.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -115,9 +115,7 @@ namespace VMAP bool processCommand(char* /*command*/) override { return false; } // for debug and extensions - bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override; - bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const override; - void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const override; + bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) const override; WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags); void releaseModelInstance(const std::string& filename); diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h index 7f28fc8b2a..d928c51721 100644 --- a/src/common/Collision/Maps/MapDefines.h +++ b/src/common/Collision/Maps/MapDefines.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -26,7 +26,40 @@ #define SIZE_OF_GRIDS 533.3333f #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 16 +#define MMAP_VERSION 18 + +struct MmapTileRecastConfig +{ + float walkableSlopeAngle; + + uint8 walkableRadius; // 1 + uint8 walkableHeight; // 1 + uint8 walkableClimb; // 1 + uint8 padding0{0}; // 1 → align next to 4 + + uint32 vertexPerMapEdge; + uint32 vertexPerTileEdge; + uint32 tilesPerMapEdge; + float baseUnitDim; + float cellSizeHorizontal; + float cellSizeVertical; + float maxSimplificationError; + + bool operator==(const MmapTileRecastConfig& b) const { + return walkableSlopeAngle == b.walkableSlopeAngle && + walkableRadius == b.walkableRadius && + walkableHeight == b.walkableHeight && + walkableClimb == b.walkableClimb && + vertexPerMapEdge == b.vertexPerMapEdge && + vertexPerTileEdge == b.vertexPerTileEdge && + tilesPerMapEdge == b.tilesPerMapEdge && + baseUnitDim == b.baseUnitDim && + cellSizeHorizontal == b.cellSizeHorizontal && + cellSizeVertical == b.cellSizeVertical && + maxSimplificationError == b.maxSimplificationError; + } +}; +static_assert(sizeof(MmapTileRecastConfig) == 36, "Unexpected size of MmapTileRecastConfig"); struct MmapTileHeader { @@ -37,17 +70,20 @@ struct MmapTileHeader char usesLiquids{true}; char padding[3] {}; + MmapTileRecastConfig recastConfig; + MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) { } }; // All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files -static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size"); +static_assert(sizeof(MmapTileHeader) == 56, "MmapTileHeader size is not correct, adjust the padding field size"); static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) + sizeof(MmapTileHeader::dtVersion) + sizeof(MmapTileHeader::mmapVersion) + sizeof(MmapTileHeader::size) + sizeof(MmapTileHeader::usesLiquids) + - sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); + sizeof(MmapTileHeader::padding)+ + sizeof(MmapTileRecastConfig)), "MmapTileHeader has uninitialized padding fields"); enum NavTerrain { diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp index 27c4c1ded1..bb9577d4ec 100644 --- a/src/common/Collision/Maps/MapTree.cpp +++ b/src/common/Collision/Maps/MapTree.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -51,22 +51,6 @@ namespace VMAP bool hit; }; - class AreaInfoCallback - { - public: - AreaInfoCallback(ModelInstance* val): prims(val) {} - void operator()(const Vector3& point, uint32 entry) - { -#if defined(VMAP_DEBUG) - LOG_DEBUG("maps", "AreaInfoCallback: trying to intersect '{}'", prims[entry].name); -#endif - prims[entry].intersectPoint(point, aInfo); - } - - ModelInstance* prims; - AreaInfo aInfo; - }; - class LocationInfoCallback { public: @@ -99,22 +83,6 @@ namespace VMAP return tilefilename.str(); } - bool StaticMapTree::GetAreaInfo(Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const - { - AreaInfoCallback intersectionCallBack(iTreeValues); - iTree.intersectPoint(pos, intersectionCallBack); - if (intersectionCallBack.aInfo.result) - { - flags = intersectionCallBack.aInfo.flags; - adtId = intersectionCallBack.aInfo.adtId; - rootId = intersectionCallBack.aInfo.rootId; - groupId = intersectionCallBack.aInfo.groupId; - pos.z = intersectionCallBack.aInfo.ground_Z; - return true; - } - return false; - } - bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const { LocationInfoCallback intersectionCallBack(iTreeValues, info); diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h index c7d6e59392..09e426e3f1 100644 --- a/src/common/Collision/Maps/MapTree.h +++ b/src/common/Collision/Maps/MapTree.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -30,6 +30,12 @@ namespace VMAP enum class ModelIgnoreFlags : uint32; enum class LoadResult : uint8; + struct GroupLocationInfo + { + const GroupModel* hitModel = nullptr; + int32 rootId = -1; + }; + struct LocationInfo { LocationInfo(): ground_Z(-G3D::inf()) { } @@ -73,7 +79,6 @@ namespace VMAP [[nodiscard]] bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2, ModelIgnoreFlags ignoreFlags) const; bool GetObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const; [[nodiscard]] float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const; - bool GetAreaInfo(G3D::Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; bool GetLocationInfo(const G3D::Vector3& pos, LocationInfo& info) const; bool InitMap(const std::string& fname, VMapMgr2* vm); diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index 50cf2eaca0..368d7e6d77 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h index efd6dda49e..b51f98307f 100644 --- a/src/common/Collision/Maps/TileAssembler.h +++ b/src/common/Collision/Maps/TileAssembler.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 683dd0c1a9..eebc7e62d2 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -203,27 +203,6 @@ 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()) @@ -236,7 +215,9 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI 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)) + + VMAP::GroupLocationInfo groupInfo; + if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo)) { Vector3 modelGround = pModel + zDist * zDirModel; float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index d0f8e35f4a..5938a5c1d0 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -70,7 +70,6 @@ public: [[nodiscard]] 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; diff --git a/src/common/Collision/Models/ModelIgnoreFlags.h b/src/common/Collision/Models/ModelIgnoreFlags.h index f54da68ef5..2a7ccfe737 100644 --- a/src/common/Collision/Models/ModelIgnoreFlags.h +++ b/src/common/Collision/Models/ModelIgnoreFlags.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/Models/ModelInstance.cpp b/src/common/Collision/Models/ModelInstance.cpp index a18d5d4f9f..c5b6fbfdb0 100644 --- a/src/common/Collision/Models/ModelInstance.cpp +++ b/src/common/Collision/Models/ModelInstance.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -63,44 +63,6 @@ namespace VMAP return hit; } - void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const - { - if (!iModel) - { -#ifdef VMAP_DEBUG - std::cout << "<object not loaded>\n"; -#endif - return; - } - - // M2 files don't contain area info, only WMO files - if (flags & MOD_M2) - { - return; - } - if (!iBound.contains(p)) - { - return; - } - // child bounds are defined in object space: - Vector3 pModel = iInvRot * (p - 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; - // Transform back to world space. Note that: - // Mat * vec == vec * Mat.transpose() - // and for rotation matrices: Mat.inverse() == Mat.transpose() - float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; - if (info.ground_Z < world_Z) - { - info.ground_Z = world_Z; - info.adtId = adtId; - } - } - } - bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const { if (!iModel) @@ -124,7 +86,9 @@ namespace VMAP Vector3 pModel = iInvRot * (p - iPos) * iInvScale; Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); float zDist; - if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info)) + + GroupLocationInfo groupInfo; + if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo)) { Vector3 modelGround = pModel + zDist * zDirModel; // Transform back to world space. Note that: @@ -133,6 +97,8 @@ namespace VMAP float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection? { + info.rootId = groupInfo.rootId; + info.hitModel = groupInfo.hitModel; info.ground_Z = world_Z; info.hitInstance = this; return true; diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h index 25987f3fd6..3476a514d5 100644 --- a/src/common/Collision/Models/ModelInstance.h +++ b/src/common/Collision/Models/ModelInstance.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -66,7 +66,6 @@ namespace VMAP ModelInstance(const ModelSpawn& spawn, WorldModel* model); void setUnloaded() { iModel = nullptr; } bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const; - void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const; bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const; bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const; WorldModel* getWorldModel() { return iModel; } diff --git a/src/common/Collision/Models/WorldModel.cpp b/src/common/Collision/Models/WorldModel.cpp index 99375e294a..53bd55a2d2 100644 --- a/src/common/Collision/Models/WorldModel.cpp +++ b/src/common/Collision/Models/WorldModel.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -20,9 +20,9 @@ #include "ModelIgnoreFlags.h" #include "ModelInstance.h" #include "VMapDefinitions.h" +#include <array> using G3D::Vector3; -using G3D::Ray; template<> struct BoundsTrait<VMAP::GroupModel> { @@ -451,21 +451,46 @@ namespace VMAP return callback.hit; } - bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const + inline bool IsInsideOrAboveBound(G3D::AABox const& bounds, const G3D::Point3& point) { - if (triangles.empty() || !iBound.contains(pos)) + return point.x >= bounds.low().x + && point.y >= bounds.low().y + && point.z >= bounds.low().z + && point.x <= bounds.high().x + && point.y <= bounds.high().y; + } + + GroupModel::InsideResult GroupModel::IsInsideObject(G3D::Ray const& ray, float& z_dist) const + { + if (triangles.empty() || !IsInsideOrAboveBound(iBound, ray.origin())) + return OUT_OF_BOUNDS; + + if (meshTree.bound().high().z >= ray.origin().z) { - return false; + float dist = G3D::finf(); + if (IntersectRay(ray, dist, false)) + { + z_dist = dist - 0.1f; + return INSIDE; + } + if (meshTree.bound().contains(ray.origin())) + return MAYBE_INSIDE; } - Vector3 rPos = pos - 0.1f * down; - float dist = G3D::inf(); - G3D::Ray ray(rPos, down); - bool hit = IntersectRay(ray, dist, false); - if (hit) + else { - z_dist = dist - 0.1f; + // some group models don't have any floor to intersect with + // so we should attempt to intersect with a model part below this group + // then find back where we originated from (in WorldModel::GetLocationInfo) + float dist = G3D::finf(); + float delta = ray.origin().z - meshTree.bound().high().z; + if (IntersectRay(ray.bumpedRay(delta), dist, false)) + { + z_dist = dist - 0.1f + delta; + return ABOVE; + } } - return hit; + + return OUT_OF_BOUNDS; } bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const @@ -541,76 +566,58 @@ namespace VMAP class WModelAreaCallback { public: - WModelAreaCallback(const std::vector<GroupModel>& vals, const Vector3& down): - prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { } - std::vector<GroupModel>::const_iterator prims; - std::vector<GroupModel>::const_iterator hit; - float minVol; - float zDist; - Vector3 zVec; - void operator()(const Vector3& point, uint32 entry) + WModelAreaCallback(std::vector<GroupModel> const& vals) : + prims(vals), hit() { } + std::vector<GroupModel> const& prims; + std::array<GroupModel const*, 3> hit; + bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool /*stopAtFirstHit*/) { float group_Z; - //float pVol = prims[entry].GetBound().volume(); - //if (pVol < minVol) - //{ - /* if (prims[entry].iBound.contains(point)) */ - if (prims[entry].IsInsideObject(point, zVec, group_Z)) + if (GroupModel::InsideResult result = prims[entry].IsInsideObject(ray, group_Z); result != GroupModel::OUT_OF_BOUNDS) { - //minVol = pVol; - //hit = prims + entry; - if (group_Z < zDist) + if (result != GroupModel::MAYBE_INSIDE) { - zDist = group_Z; - hit = prims + entry; + if (group_Z < distance) + { + distance = group_Z; + hit[result] = &prims[entry]; + return true; + } } -#ifdef VMAP_DEBUG - const GroupModel& gm = prims[entry]; - printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(), - gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z, - gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z); -#endif + else + hit[result] = &prims[entry]; } - //} - //std::cout << "trying to intersect '" << prims[entry].name << "'\n"; + return false; } }; - bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const + bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const { if (groupModels.empty()) { return false; } - WModelAreaCallback callback(groupModels, down); - groupTree.intersectPoint(p, callback); - if (callback.hit != groupModels.end()) + WModelAreaCallback callback(groupModels); + G3D::Ray r(p - down * 0.1f, down); + float zDist = groupTree.bound().extent().length(); + groupTree.intersectRay(r, callback, zDist, false); + if (callback.hit[GroupModel::INSIDE]) { info.rootId = RootWMOID; - info.groupId = callback.hit->GetWmoID(); - info.flags = callback.hit->GetMogpFlags(); - info.result = true; - dist = callback.zDist; + info.hitModel = callback.hit[GroupModel::INSIDE]; + dist = zDist; return true; } - return false; - } - - bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const - { - if (groupModels.empty()) - { - return false; - } - WModelAreaCallback callback(groupModels, down); - groupTree.intersectPoint(p, callback); - if (callback.hit != groupModels.end()) + // some group models don't have any floor to intersect with + // so we should attempt to intersect with a model part below the group `p` is in (stored in GroupModel::ABOVE) + // then find back where we originated from (GroupModel::MAYBE_INSIDE) + if (callback.hit[GroupModel::MAYBE_INSIDE] && callback.hit[GroupModel::ABOVE]) { info.rootId = RootWMOID; - info.hitModel = &(*callback.hit); - dist = callback.zDist; + info.hitModel = callback.hit[GroupModel::MAYBE_INSIDE]; + dist = zDist; return true; } return false; diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h index df1bd47512..2d5d8126b1 100644 --- a/src/common/Collision/Models/WorldModel.h +++ b/src/common/Collision/Models/WorldModel.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -29,6 +29,7 @@ namespace VMAP class TreeNode; struct AreaInfo; struct LocationInfo; + struct GroupLocationInfo; enum class ModelIgnoreFlags : uint32; class MeshTriangle @@ -81,12 +82,14 @@ namespace VMAP void setMeshData(std::vector<G3D::Vector3>& vert, std::vector<MeshTriangle>& tri); void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = nullptr; } bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const; - bool IsInsideObject(const G3D::Vector3& pos, const G3D::Vector3& down, float& z_dist) const; + enum InsideResult { INSIDE = 0, MAYBE_INSIDE = 1, ABOVE = 2, OUT_OF_BOUNDS = -1 }; + InsideResult IsInsideObject(G3D::Ray const& ray, float& z_dist) const; bool GetLiquidLevel(const G3D::Vector3& pos, float& liqHeight) const; [[nodiscard]] uint32 GetLiquidType() const; bool writeToFile(FILE* wf); bool readFromFile(FILE* rf); - [[nodiscard]] const G3D::AABox& GetBound() const { return iBound; } + [[nodiscard]] G3D::AABox const& GetBound() const { return iBound; } + [[nodiscard]] G3D::AABox const& GetMeshTreeBound() const { return meshTree.bound(); } [[nodiscard]] uint32 GetMogpFlags() const { return iMogpFlags; } [[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; } void GetMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid); @@ -109,8 +112,7 @@ namespace VMAP void setGroupModels(std::vector<GroupModel>& models); void setRootWmoID(uint32 id) { RootWMOID = id; } bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const; - bool IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const; - bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const; + bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const; bool writeFile(const std::string& filename); bool readFile(const std::string& filename); void GetGroupModels(std::vector<GroupModel>& outGroupModels); diff --git a/src/common/Collision/VMapDefinitions.h b/src/common/Collision/VMapDefinitions.h index eee744fe45..623dea5020 100644 --- a/src/common/Collision/VMapDefinitions.h +++ b/src/common/Collision/VMapDefinitions.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along diff --git a/src/common/Collision/VMapTools.h b/src/common/Collision/VMapTools.h index f200e3647b..ba47cdf62d 100644 --- a/src/common/Collision/VMapTools.h +++ b/src/common/Collision/VMapTools.h @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along |
