From fcd58c134dc532a99dbc19a884b9f3aa9ec70b69 Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Mon, 7 Jun 2010 13:57:34 +0200 Subject: * Move VMap3 code to a separate static 'collision' library. --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 450 ++++++++++++++++++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 src/server/collision/Maps/MapTree.cpp (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp new file mode 100644 index 00000000000..8c77ee109f3 --- /dev/null +++ b/src/server/collision/Maps/MapTree.cpp @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MapTree.h" +#include "ModelInstance.h" +#include "VMapManager2.h" +#include "VMapDefinitions.h" + +#include +#include +#include + +using G3D::Vector3; + +namespace VMAP +{ + + class MapRayCallback + { + public: + MapRayCallback(ModelInstance *val): prims(val) {} + ModelInstance *prims; + bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true) + { + return prims[entry].intersectRay(ray, distance, pStopAtFirstHit); + //std::cout << "trying to intersect '" << entity->name << "'\n"; + } + }; + + class AreaInfoCallback + { + public: + AreaInfoCallback(ModelInstance *val): prims(val) {} + void operator()(const Vector3& point, uint32 entry) + { +#ifdef VMAP_DEBUG + std::cout << "trying to intersect '" << prims[entry].name << "'\n"; +#endif + prims[entry].intersectPoint(point, aInfo); + } + + ModelInstance *prims; + AreaInfo aInfo; + }; + + class LocationInfoCallback + { + public: + LocationInfoCallback(ModelInstance *val, LocationInfo &info): prims(val), locInfo(info), result(false) {} + void operator()(const Vector3& point, uint32 entry) + { +#ifdef VMAP_DEBUG + std::cout << "trying to intersect '" << prims[entry].name << "'\n"; +#endif + if (prims[entry].GetLocationInfo(point, locInfo)) + result = true; + } + + ModelInstance *prims; + LocationInfo &locInfo; + bool result; + }; + + + //========================================================= + + std::string StaticMapTree::getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY) + { + std::stringstream tilefilename; + tilefilename.fill('0'); + tilefilename << std::setw(3) << mapID << "_"; + //tilefilename << std::setw(2) << tileX << "_" << std::setw(2) << tileY << ".vmtile"; + tilefilename << std::setw(2) << tileY << "_" << std::setw(2) << tileX << ".vmtile"; + 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); + iTree.intersectPoint(pos, intersectionCallBack); + return intersectionCallBack.result; + } + + StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath): + iMapID(mapID), /* iTree(0), */ iTreeValues(0), iBasePath(basePath) + { + if (iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\')) + { + iBasePath.append("/"); + } + } + + //========================================================= + //! Make sure to call unloadMap() to unregister acquired model references before destroying + StaticMapTree::~StaticMapTree() + { + delete[] iTreeValues; + } + + //========================================================= + /** + return dist to hit or inf() if no hit + */ + + float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const + { + float distance = pMaxDist; + MapRayCallback intersectionCallBack(iTreeValues); + iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit); + return distance; + } + //========================================================= + + bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const + { + bool result = true; + float maxDist = (pos2 - pos1).magnitude(); + // prevent NaN values which can cause BIH intersection to enter infinite loop + if (maxDist < 1e-10f) + return true; + // direction with length of 1 + G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); + float resultDist = getIntersectionTime(ray, maxDist, true); + if (resultDist < maxDist) + { + result = false; + } + return result; + } + //========================================================= + /** + When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one + Return the hit pos or the original dest pos + */ + + bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const + { + bool result=false; + float maxDist = (pPos2 - pPos1).magnitude(); + // prevent NaN values which can cause BIH intersection to enter infinite loop + if (maxDist < 1e-10f) + { + pResultHitPos = pPos2; + return false; + } + Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1 + G3D::Ray ray(pPos1, dir); + float dist = getIntersectionTime(ray, maxDist, false); + if (dist < maxDist) + { + pResultHitPos = pPos1 + dir * dist; + if (pModifyDist < 0) + { + if ((pResultHitPos - pPos1).magnitude() > -pModifyDist) + { + pResultHitPos = pResultHitPos + dir*pModifyDist; + } + else + { + pResultHitPos = pPos1; + } + } + else + { + pResultHitPos = pResultHitPos + dir*pModifyDist; + } + result = true; + } + else + { + pResultHitPos = pPos2; + result = false; + } + return result; + } + + //========================================================= + + float StaticMapTree::getHeight(const Vector3& pPos) const + { + float height = G3D::inf(); + Vector3 dir = Vector3(0,0,-1); + G3D::Ray ray(pPos, dir); // direction with length of 1 + float maxDist = VMapDefinitions::getMaxCanFallDistance(); + float dist = getIntersectionTime(ray, maxDist, false); + if (dist < maxDist) + { + height = pPos.z - dist; + } + return(height); + } + + //========================================================= + + bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY) + { + std::string basePath = vmapPath; + if (basePath.length() > 0 && (basePath[basePath.length()-1] != '/' || basePath[basePath.length()-1] != '\\')) + basePath.append("/"); + std::string fullname = basePath + VMapManager2::getMapFileName(mapID); + bool success = true; + FILE *rf = fopen(fullname.c_str(), "rb"); + if (!rf) + return false; + // TODO: check magic number when implemented... + char tiled; + char chunk[8]; + if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1) + { + fclose(rf); + return false; + } + if (tiled) + { + std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY); + FILE* tf = fopen(tilefile.c_str(), "rb"); + if (!tf) + success = false; + else + fclose(tf); + } + fclose(rf); + return success; + } + + //========================================================= + + bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm) + { + std::cout << "Initializing StaticMapTree '" << fname << "'\n"; + bool success = true; + std::string fullname = iBasePath + fname; + FILE *rf = fopen(fullname.c_str(), "rb"); + if (!rf) + return false; + else + { + char chunk[8]; + //general info + if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false; + char tiled; + if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false; + iIsTiled = bool(tiled); + // Nodes + if (success && !readChunk(rf, chunk, "NODE", 4)) success = false; + if (success) success = iTree.readFromFile(rf); + if (success) + { + iNTreeValues = iTree.primCount(); + iTreeValues = new ModelInstance[iNTreeValues]; + } + + if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false; + // global model spawns + // only non-tiled maps have them, and if so exactly one (so far at least...) + ModelSpawn spawn; +#ifdef VMAP_DEBUG + std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl; +#endif + if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) + { + WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); + std::cout << "StaticMapTree::InitMap(): loading " << spawn.name << std::endl; + if (model) + { + // assume that global model always is the first and only tree value (could be improved...) + iTreeValues[0] = ModelInstance(spawn, model); + iLoadedSpawns[0] = 1; + } + else + { + success = false; + std::cout << "error: could not acquire WorldModel pointer!\n"; + } + } + + fclose(rf); + } + return success; + } + + //========================================================= + + void StaticMapTree::UnloadMap(VMapManager2 *vm) + { + for (loadedSpawnMap::iterator i = iLoadedSpawns.begin(); i != iLoadedSpawns.end(); ++i) + { + iTreeValues[i->first].setUnloaded(); + for (uint32 refCount = 0; refCount < i->second; ++refCount) + vm->releaseModelInstance(iTreeValues[i->first].name); + } + iLoadedSpawns.clear(); + iLoadedTiles.clear(); + } + + //========================================================= + + bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm) + { + if (!iIsTiled) + { + // currently, core creates grids for all maps, whether it has terrain tiles or not + // so we need "fake" tile loads to know when we can unload map geometry + iLoadedTiles[packTileID(tileX, tileY)] = false; + return true; + } + if (!iTreeValues) + { + std::cout << "Tree has not been initialized!\n"; + return false; + } + bool result = true; + + std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); + FILE* tf = fopen(tilefile.c_str(), "rb"); + if (tf) + { + uint32 numSpawns; + if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1) + result = false; + for (uint32 i=0; iacquireModelInstance(iBasePath, spawn.name); + if (!model) std::cout << "error: could not acquire WorldModel pointer!\n"; + + // update tree + uint32 referencedVal; + + fread(&referencedVal, sizeof(uint32), 1, tf); + if (!iLoadedSpawns.count(referencedVal)) + { +#ifdef VMAP_DEBUG + if (referencedVal > iNTreeValues) + { + std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n"; + continue; + } +#endif + iTreeValues[referencedVal] = ModelInstance(spawn, model); + iLoadedSpawns[referencedVal] = 1; + } + else + { + ++iLoadedSpawns[referencedVal]; +#ifdef VMAP_DEBUG + if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n"; + else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n"; +#endif + } + } + } + iLoadedTiles[packTileID(tileX, tileY)] = true; + fclose(tf); + } + else + iLoadedTiles[packTileID(tileX, tileY)] = false; + return result; + } + + //========================================================= + + void StaticMapTree::UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm) + { + uint32 tileID = packTileID(tileX, tileY); + loadedTileMap::iterator tile = iLoadedTiles.find(tileID); + if (tile == iLoadedTiles.end()) + { + std::cout << "WARNING: trying to unload non-loaded tile. Map:" << iMapID << " X:" << tileX << " Y:" << tileY << std::endl; + return; + } + if (tile->second) // file associated with tile + { + std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); + FILE* tf = fopen(tilefile.c_str(), "rb"); + if (tf) + { + bool result=true; + uint32 numSpawns; + if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1) + result = false; + for (uint32 i=0; ireleaseModelInstance(spawn.name); + + // update tree + uint32 referencedNode; + + fread(&referencedNode, sizeof(uint32), 1, tf); + if (!iLoadedSpawns.count(referencedNode)) + { + std::cout << "error! trying to unload non-referenced model '" << spawn.name << "' (ID:" << spawn.ID << ")\n"; + } + else if (--iLoadedSpawns[referencedNode] == 0) + { + //std::cout << "MapTree: removing '" << spawn.name << "' from tree\n"; + iTreeValues[referencedNode].setUnloaded(); + iLoadedSpawns.erase(referencedNode); + } + } + } + fclose(tf); + } + } + iLoadedTiles.erase(tile); + } + +} -- cgit v1.2.3 From ebb07858170c7552439ce0afd9395d93b79e2eb8 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 15 Jun 2010 17:08:04 +0200 Subject: Commit from Lynx3d: Add assert to values that can cause nasty freeze, but should never occur with valid input. --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 6 ++++++ src/tools/vmap3_assembler/CMakeLists.txt | 1 + src/tools/vmap3_assembler/VC90/vmap_assembler.vcproj | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 8c77ee109f3..af4073fcc8c 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "Errors.h" #include "MapTree.h" #include "ModelInstance.h" #include "VMapManager2.h" @@ -24,6 +25,7 @@ #include #include #include +#include using G3D::Vector3; @@ -146,6 +148,8 @@ namespace VMAP { bool result = true; float maxDist = (pos2 - pos1).magnitude(); + // valid map coords should *never ever* produce float overflow, but this would produce NaNs too + ASSERT(maxDist < std::numeric_limits::max()); // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) return true; @@ -168,6 +172,8 @@ namespace VMAP { bool result=false; float maxDist = (pPos2 - pPos1).magnitude(); + // valid map coords should *never ever* produce float overflow, but this would produce NaNs too + ASSERT(maxDist < std::numeric_limits::max()); // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) { diff --git a/src/tools/vmap3_assembler/CMakeLists.txt b/src/tools/vmap3_assembler/CMakeLists.txt index b3b16d540c7..62eaca7e13f 100644 --- a/src/tools/vmap3_assembler/CMakeLists.txt +++ b/src/tools/vmap3_assembler/CMakeLists.txt @@ -14,6 +14,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/collision/Maps ${CMAKE_SOURCE_DIR}/src/server/collision/Models ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging ${ACE_INCLUDE_DIR} ) diff --git a/src/tools/vmap3_assembler/VC90/vmap_assembler.vcproj b/src/tools/vmap3_assembler/VC90/vmap_assembler.vcproj index e3b1b7766a5..b7c0e7719b3 100644 --- a/src/tools/vmap3_assembler/VC90/vmap_assembler.vcproj +++ b/src/tools/vmap3_assembler/VC90/vmap_assembler.vcproj @@ -42,7 +42,7 @@ Date: Thu, 17 Jun 2010 20:38:46 +0200 Subject: Add plane/finitecheck tests for OOB intersection-vectors (this should fix vmap-related freezes) - patch by Gyullo --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index af4073fcc8c..4879cc963db 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -146,19 +146,32 @@ namespace VMAP bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const { - bool result = true; + bool result = false; float maxDist = (pos2 - pos1).magnitude(); // valid map coords should *never ever* produce float overflow, but this would produce NaNs too - ASSERT(maxDist < std::numeric_limits::max()); + + //ASSERT(maxDist < std::numeric_limits::max()); + // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) return true; // direction with length of 1 + G3D::Plane checkPlane = G3D::Plane(pos1, pos2, (pos2 - pos1)); G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); - float resultDist = getIntersectionTime(ray, maxDist, true); - if (resultDist < maxDist) + + Vector3 checkFinite = ray.intersection(checkPlane); + if (!checkFinite.isFinite()) { - result = false; + ray = G3D::Ray::fromOriginAndDirection(pos1, -((pos2 - pos1)/maxDist)); + checkFinite = ray.intersection(checkPlane); + } + if (checkFinite.isFinite()) + { + float resultDist = getIntersectionTime(ray, maxDist, true); + if (resultDist >= maxDist) + { + result = true; + } } return result; } -- cgit v1.2.3 From 7fe641c99e2eb17a2f4c10d1eb61debc7dfe72ef Mon Sep 17 00:00:00 2001 From: click Date: Thu, 17 Jun 2010 22:28:16 +0200 Subject: Fix a small "typo" regarding the calculation of LoS from the r9b1c565510 vmap-fix - fix by Gyullo, after being busy slapping himself for the mistake --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 4879cc963db..c733ed37454 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -156,7 +156,7 @@ namespace VMAP if (maxDist < 1e-10f) return true; // direction with length of 1 - G3D::Plane checkPlane = G3D::Plane(pos1, pos2, (pos2 - pos1)); + G3D::Plane checkPlane = G3D::Plane((pos2 - pos1)/maxDist,pos1, pos2); G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); Vector3 checkFinite = ray.intersection(checkPlane); -- cgit v1.2.3 From 8c8986b2bc7a5dee3c12252486ad68a40a482ee0 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sat, 19 Jun 2010 17:26:12 +0200 Subject: Fix usage of uninitialized waypoint array variables in ConfusedMovementGenerator::Initialize and revert 9b1c565510+ad8ce5245e that covered up this problem without fixing it and introduced a faulty LOS calculation. With thanks to Lynx3d and click, and Aokromes and ritchy for testing. --HG-- branch : trunk --- src/server/collision/Management/VMapManager2.cpp | 10 +++++----- src/server/collision/Maps/MapTree.cpp | 23 +++++----------------- src/server/collision/Maps/MapTree.h | 1 + .../ConfusedMovementGenerator.cpp | 14 ++++++------- 4 files changed, 17 insertions(+), 31 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 1e8a84aee52..032793b1c09 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -109,7 +109,7 @@ namespace VMAP ss2 >> map_num; if (map_num >= 0) { - std::cout << "ingoring Map " << map_num << " for VMaps\n"; + sLog.outDebug("Ignoring Map %i for VMaps", map_num); iIgnoreMapIds[map_num] = true; // unload map in case it is loaded unloadMap(map_num); @@ -299,11 +299,11 @@ namespace VMAP WorldModel *worldmodel = new WorldModel(); if (!worldmodel->readFile(basepath + filename + ".vmo")) { - std::cout << "VMapManager2: could not load '" << basepath << filename << ".vmo'!\n"; + sLog.outError("VMapManager2: could not load '%s%s.vmo'!", basepath, filename); delete worldmodel; return NULL; } - std::cout << "VMapManager2: loading file '" << basepath << filename << "'.\n"; + sLog.outDebug("VMapManager2: loading file '%s%s'.", basepath, filename); model = iLoadedModelFiles.insert(std::pair(filename, ManagedModel())).first; model->second.setModel(worldmodel); } @@ -316,12 +316,12 @@ namespace VMAP ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { - std::cout << "VMapManager2: trying to unload non-loaded file '" << filename << "'!\n"; + sLog.outError("VMapManager2: trying to unload non-loaded file '%s'!", filename); return; } if( model->second.decRefCount() == 0) { - std::cout << "VMapManager2: unloading file '" << filename << "'.\n"; + sLog.outDebug("VMapManager2: unloading file '%s'", filename); delete model->second.getModel(); iLoadedModelFiles.erase(model); } diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index c733ed37454..af4073fcc8c 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -146,32 +146,19 @@ namespace VMAP bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const { - bool result = false; + bool result = true; float maxDist = (pos2 - pos1).magnitude(); // valid map coords should *never ever* produce float overflow, but this would produce NaNs too - - //ASSERT(maxDist < std::numeric_limits::max()); - + ASSERT(maxDist < std::numeric_limits::max()); // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) return true; // direction with length of 1 - G3D::Plane checkPlane = G3D::Plane((pos2 - pos1)/maxDist,pos1, pos2); G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); - - Vector3 checkFinite = ray.intersection(checkPlane); - if (!checkFinite.isFinite()) + float resultDist = getIntersectionTime(ray, maxDist, true); + if (resultDist < maxDist) { - ray = G3D::Ray::fromOriginAndDirection(pos1, -((pos2 - pos1)/maxDist)); - checkFinite = ray.intersection(checkPlane); - } - if (checkFinite.isFinite()) - { - float resultDist = getIntersectionTime(ray, maxDist, true); - if (resultDist >= maxDist) - { - result = true; - } + result = false; } return result; } diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 7a7af43e949..f9c51d47b95 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -22,6 +22,7 @@ #include "Define.h" #include "Dynamic/UnorderedMap.h" #include "BoundingIntervalHierarchy.h" +#include "Log.h" namespace VMAP { diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 43c6052d2d3..c9e39866bf5 100644 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -51,15 +51,13 @@ ConfusedMovementGenerator::Initialize(T &unit) for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx) { + const float wanderX = wander_distance*rand_norm() - wander_distance/2; + const float wanderY = wander_distance*rand_norm() - wander_distance/2; + i_waypoints[idx][0] = x + wanderX; + i_waypoints[idx][1] = y + wanderY; + const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f); - if (isInLoS) - { - const float wanderX = wander_distance*rand_norm() - wander_distance/2; - const float wanderY = wander_distance*rand_norm() - wander_distance/2; - i_waypoints[idx][0] = x + wanderX; - i_waypoints[idx][1] = y + wanderY; - } - else + if (!isInLoS) { i_waypoints[idx][0] = x; i_waypoints[idx][1] = y; -- cgit v1.2.3 From 29d9e40f7482ff5b5b0944a339fcf7b89464bf2d Mon Sep 17 00:00:00 2001 From: click Date: Sat, 19 Jun 2010 21:35:32 +0200 Subject: Some smaller fixes to the vmapextractor courtesy of Lynx3d (not using corefunctions + update errormessages to use the new fileextensions) --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 7 ++++++- src/server/game/World/World.cpp | 2 +- src/tools/vmap3_assembler/CMakeLists.txt | 1 + src/tools/vmap3_extractor/wmo.cpp | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index af4073fcc8c..9f55920bcf9 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Errors.h" #include "MapTree.h" #include "ModelInstance.h" #include "VMapManager2.h" @@ -27,6 +26,12 @@ #include #include +#ifndef NO_CORE_FUNCS + #include "Errors.h" +#else + #define ASSERT(x) +#endif + using G3D::Vector3; namespace VMAP diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0041bbaecc8..8a98da41cc1 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1274,7 +1274,7 @@ void World::SetInitialWorldSettings() ||m_configs[CONFIG_EXPANSION] && ( !MapManager::ExistMapAndVMap(530,10349.6f,-6357.29f) || !MapManager::ExistMapAndVMap(530,-3961.64f,-13931.2f))) { - sLog.outError("Correct *.map files not found in path '%smaps' or *.vmap/*vmdir files in '%svmaps'. Please place *.map/*.vmap/*.vmdir files in appropriate directories or correct the DataDir value in the Trinityd.conf file.",m_dataPath.c_str(),m_dataPath.c_str()); + sLog.outError("Correct *.map files not found in path '%smaps' or *.vmtree/*.vmtile files in '%svmaps'. Please place *.map/*.vmtree/*.vmtile files in appropriate directories or correct the DataDir value in the Trinityd.conf file.",m_dataPath.c_str(),m_dataPath.c_str()); exit(1); } diff --git a/src/tools/vmap3_assembler/CMakeLists.txt b/src/tools/vmap3_assembler/CMakeLists.txt index 7d3c02eb58b..8c79fff6804 100644 --- a/src/tools/vmap3_assembler/CMakeLists.txt +++ b/src/tools/vmap3_assembler/CMakeLists.txt @@ -19,6 +19,7 @@ include_directories( ${ACE_INCLUDE_DIR} ) +add_definitions(-DNO_CORE_FUNCS) add_executable(vmap3assembler VMapAssembler.cpp) target_link_libraries(vmap3assembler collision g3dlib) diff --git a/src/tools/vmap3_extractor/wmo.cpp b/src/tools/vmap3_extractor/wmo.cpp index 650d2279f28..216a2248953 100644 --- a/src/tools/vmap3_extractor/wmo.cpp +++ b/src/tools/vmap3_extractor/wmo.cpp @@ -386,7 +386,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPrecis if (rootWMO->liquidType & 4) liquidEntry = liquidType; else if (liquidType == 15) - liquidEntry = 0; + liquidEntry = 1; // first entry, generic "Water" else liquidEntry = liquidType + 1; // overwrite material type in header... -- cgit v1.2.3 From f43727e18cbc9523be81d3b347ae6cf07616322c Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sat, 19 Jun 2010 22:08:03 +0200 Subject: Change some map/vmap-related runtime output to sLog format. --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 9f55920bcf9..af92ec37ae7 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -20,6 +20,7 @@ #include "ModelInstance.h" #include "VMapManager2.h" #include "VMapDefinitions.h" +#include "Log.h" #include #include @@ -56,7 +57,7 @@ namespace VMAP void operator()(const Vector3& point, uint32 entry) { #ifdef VMAP_DEBUG - std::cout << "trying to intersect '" << prims[entry].name << "'\n"; + sLog.outDebug("trying to intersect '%s'", prims[entry].name.c_str()); #endif prims[entry].intersectPoint(point, aInfo); } @@ -72,7 +73,7 @@ namespace VMAP void operator()(const Vector3& point, uint32 entry) { #ifdef VMAP_DEBUG - std::cout << "trying to intersect '" << prims[entry].name << "'\n"; + sLog.outDebug("trying to intersect '%s'", prims[entry].name.c_str()); #endif if (prims[entry].GetLocationInfo(point, locInfo)) result = true; @@ -269,7 +270,7 @@ namespace VMAP bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm) { - std::cout << "Initializing StaticMapTree '" << fname << "'\n"; + sLog.outDebug("Initializing StaticMapTree '%s'", fname.c_str()); bool success = true; std::string fullname = iBasePath + fname; FILE *rf = fopen(fullname.c_str(), "rb"); @@ -297,12 +298,12 @@ namespace VMAP // only non-tiled maps have them, and if so exactly one (so far at least...) ModelSpawn spawn; #ifdef VMAP_DEBUG - std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl; + sLog.outDebug("Map isTiled: %u", static_cast(iIsTiled)); #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); - std::cout << "StaticMapTree::InitMap(): loading " << spawn.name << std::endl; + sLog.outDebug("StaticMapTree::InitMap(): loading %s", spawn.name.c_str()); if (model) { // assume that global model always is the first and only tree value (could be improved...) @@ -312,7 +313,7 @@ namespace VMAP else { success = false; - std::cout << "error: could not acquire WorldModel pointer!\n"; + sLog.outError("Could not acquire WorldModel pointer!"); } } @@ -348,7 +349,7 @@ namespace VMAP } if (!iTreeValues) { - std::cout << "Tree has not been initialized!\n"; + sLog.outError("Tree has not been initialized! [%u,%u]", tileX, tileY); return false; } bool result = true; @@ -369,7 +370,8 @@ namespace VMAP { // acquire model instance WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); - if (!model) std::cout << "error: could not acquire WorldModel pointer!\n"; + if (!model) + sLog.outError("error: could not acquire WorldModel pointer! [%u,%u]", tileX, tileY); // update tree uint32 referencedVal; @@ -380,7 +382,7 @@ namespace VMAP #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { - std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n"; + sLog.outDebug("invalid tree element! (%u/%u)", referencedVal, iNTreeValues); continue; } #endif @@ -391,8 +393,10 @@ namespace VMAP { ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG - if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n"; - else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n"; + if (iTreeValues[referencedVal].ID != spawn.ID) + sLog.outDebug("error: trying to load wrong spawn in node!"); + else if (iTreeValues[referencedVal].name != spawn.name) + sLog.outDebug("error: name collision on GUID=%u", spawn.ID); #endif } } @@ -413,7 +417,7 @@ namespace VMAP loadedTileMap::iterator tile = iLoadedTiles.find(tileID); if (tile == iLoadedTiles.end()) { - std::cout << "WARNING: trying to unload non-loaded tile. Map:" << iMapID << " X:" << tileX << " Y:" << tileY << std::endl; + sLog.outError("WARNING: trying to unload non-loaded tile. Map:%u X:%u Y:%u", iMapID, tileX, tileY); return; } if (tile->second) // file associated with tile @@ -442,7 +446,7 @@ namespace VMAP fread(&referencedNode, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(referencedNode)) { - std::cout << "error! trying to unload non-referenced model '" << spawn.name << "' (ID:" << spawn.ID << ")\n"; + sLog.outError("Trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); } else if (--iLoadedSpawns[referencedNode] == 0) { -- cgit v1.2.3 From 45e2a65fad6549ff93005ff166fba309c20259e0 Mon Sep 17 00:00:00 2001 From: click Date: Fri, 9 Jul 2010 18:02:46 +0200 Subject: Update VMap3 to "final" release (REEXTRACTION OF MAPS/VMAPS IS REQUIRED!) - thanks to Lynx3d (again) - add magic-header to .vmtile files - calculate waterlevels for non-flat surfaces in a more correct way - make MSVC shut up about float-issues - change logging around a bit (output function that the respective logentry comes from) - remove remaining Stormlib leftovers - set indoor/outdoor check to enabled by default (more blizzlike) --HG-- branch : trunk --- src/server/collision/Management/VMapManager2.cpp | 32 ++++++------ src/server/collision/Maps/MapTree.cpp | 64 ++++++++++++++---------- src/server/collision/Maps/MapTree.h | 1 + src/server/collision/Maps/TileAssembler.cpp | 28 ++++++----- src/server/collision/Models/ModelInstance.cpp | 23 +++++---- src/server/collision/Models/WorldModel.cpp | 63 +++++++++++++++++------ src/server/collision/VMapDefinitions.h | 22 ++++---- src/server/worldserver/worldserver.conf.dist | 6 +-- src/tools/vmap3_assembler/VMapAssembler.cpp | 4 +- src/tools/vmap3_extractor/dbcfile.h | 22 ++++++-- src/tools/vmap3_extractor/vmapexport.cpp | 2 +- 11 files changed, 165 insertions(+), 102 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 1936ba6ebba..61b202c9342 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #include @@ -57,7 +57,7 @@ namespace VMAP Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const { Vector3 pos; - const float mid = 0.5 * 64.0 * 533.33333333f; + const float mid = 0.5f * 64.0f * 533.33333333f; pos.x = mid - x; pos.y = mid - y; pos.z = z; @@ -70,7 +70,7 @@ namespace VMAP Vector3 VMapManager2::convertPositionToMangosRep(float x, float y, float z) const { Vector3 pos; - const float mid = 0.5 * 64.0 * 533.33333333f; + const float mid = 0.5f * 64.0f * 533.33333333f; pos.x = mid - x; pos.y = mid - y; pos.z = z; @@ -301,11 +301,11 @@ namespace VMAP WorldModel *worldmodel = new WorldModel(); if (!worldmodel->readFile(basepath + filename + ".vmo")) { - sLog.outError("VMapManager2: could not load '%s%s.vmo'!", basepath.c_str(), filename.c_str()); + sLog.outError("VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str()); delete worldmodel; return NULL; } - sLog.outDebug("VMapManager2: loading file '%s%s'.", basepath.c_str(), filename.c_str()); + sLog.outDebug("VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); model = iLoadedModelFiles.insert(std::pair(filename, ManagedModel())).first; model->second.setModel(worldmodel); } @@ -318,7 +318,7 @@ namespace VMAP ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { - sLog.outError("VMapManager2: trying to unload non-loaded file '%s'!", filename.c_str()); + sLog.outError("VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); return; } if( model->second.decRefCount() == 0) diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index af92ec37ae7..e758581e2f8 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #include "MapTree.h" @@ -57,7 +57,7 @@ namespace VMAP void operator()(const Vector3& point, uint32 entry) { #ifdef VMAP_DEBUG - sLog.outDebug("trying to intersect '%s'", prims[entry].name.c_str()); + sLog.outDebug("AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str()); #endif prims[entry].intersectPoint(point, aInfo); } @@ -73,7 +73,7 @@ namespace VMAP void operator()(const Vector3& point, uint32 entry) { #ifdef VMAP_DEBUG - sLog.outDebug("trying to intersect '%s'", prims[entry].name.c_str()); + sLog.outDebug("LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str()); #endif if (prims[entry].GetLocationInfo(point, locInfo)) result = true; @@ -121,7 +121,7 @@ namespace VMAP } StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath): - iMapID(mapID), /* iTree(0), */ iTreeValues(0), iBasePath(basePath) + iMapID(mapID), iTreeValues(0), iBasePath(basePath) { if (iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\')) { @@ -260,7 +260,11 @@ namespace VMAP if (!tf) success = false; else + { + if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) + success = false; fclose(tf); + } } fclose(rf); return success; @@ -270,7 +274,7 @@ namespace VMAP bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm) { - sLog.outDebug("Initializing StaticMapTree '%s'", fname.c_str()); + sLog.outDebug("StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str()); bool success = true; std::string fullname = iBasePath + fname; FILE *rf = fopen(fullname.c_str(), "rb"); @@ -298,12 +302,12 @@ namespace VMAP // only non-tiled maps have them, and if so exactly one (so far at least...) ModelSpawn spawn; #ifdef VMAP_DEBUG - sLog.outDebug("Map isTiled: %u", static_cast(iIsTiled)); + sLog.outDebug("StaticMapTree::InitMap() : map isTiled: %u", static_cast(iIsTiled)); #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); - sLog.outDebug("StaticMapTree::InitMap(): loading %s", spawn.name.c_str()); + sLog.outDebug("StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); if (model) { // assume that global model always is the first and only tree value (could be improved...) @@ -313,7 +317,7 @@ namespace VMAP else { success = false; - sLog.outError("Could not acquire WorldModel pointer!"); + sLog.outError("StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); } } @@ -349,7 +353,7 @@ namespace VMAP } if (!iTreeValues) { - sLog.outError("Tree has not been initialized! [%u,%u]", tileX, tileY); + sLog.outError("StaticMapTree::LoadMapTile() : tree has not been initialized [%u,%u]", tileX, tileY); return false; } bool result = true; @@ -358,8 +362,12 @@ namespace VMAP FILE* tf = fopen(tilefile.c_str(), "rb"); if (tf) { + char chunk[8]; + + if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) + result = false; uint32 numSpawns; - if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1) + if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1) result = false; for (uint32 i=0; iacquireModelInstance(iBasePath, spawn.name); if (!model) - sLog.outError("error: could not acquire WorldModel pointer! [%u,%u]", tileX, tileY); + sLog.outError("StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u,%u]", tileX, tileY); // update tree uint32 referencedVal; @@ -382,7 +390,7 @@ namespace VMAP #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { - sLog.outDebug("invalid tree element! (%u/%u)", referencedVal, iNTreeValues); + sLog.outDebug("StaticMapTree::LoadMapTile() : invalid tree element (%u/%u)", referencedVal, iNTreeValues); continue; } #endif @@ -394,9 +402,9 @@ namespace VMAP ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].ID != spawn.ID) - sLog.outDebug("error: trying to load wrong spawn in node!"); + sLog.outDebug("StaticMapTree::LoadMapTile() : trying to load wrong spawn in node"); else if (iTreeValues[referencedVal].name != spawn.name) - sLog.outDebug("error: name collision on GUID=%u", spawn.ID); + sLog.outDebug("StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID); #endif } } @@ -417,7 +425,7 @@ namespace VMAP loadedTileMap::iterator tile = iLoadedTiles.find(tileID); if (tile == iLoadedTiles.end()) { - sLog.outError("WARNING: trying to unload non-loaded tile. Map:%u X:%u Y:%u", iMapID, tileX, tileY); + sLog.outError("StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY); return; } if (tile->second) // file associated with tile @@ -427,6 +435,9 @@ namespace VMAP if (tf) { bool result=true; + char chunk[8]; + if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) + result = false; uint32 numSpawns; if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1) result = false; @@ -446,11 +457,10 @@ namespace VMAP fread(&referencedNode, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(referencedNode)) { - sLog.outError("Trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); + sLog.outError("StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); } else if (--iLoadedSpawns[referencedNode] == 0) { - //std::cout << "MapTree: removing '" << spawn.name << "' from tree\n"; iTreeValues[referencedNode].setUnloaded(); iLoadedSpawns.erase(referencedNode); } diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 7a7af43e949..f9c51d47b95 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -22,6 +22,7 @@ #include "Define.h" #include "Dynamic/UnorderedMap.h" #include "BoundingIntervalHierarchy.h" +#include "Log.h" namespace VMAP { diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp index 0b9780130ed..c6798e70cc4 100644 --- a/src/server/collision/Maps/TileAssembler.cpp +++ b/src/server/collision/Maps/TileAssembler.cpp @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #include "WorldModel.h" @@ -82,6 +82,7 @@ namespace VMAP // build global map tree std::vector mapSpawns; UniqueEntryMap::iterator entry; + printf("Calculating model bounds for map %u...\n", map_iter->first); for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry) { // M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail @@ -100,6 +101,7 @@ namespace VMAP spawnedModelFiles.insert(entry->second.name); } + printf("Creating map tree...\n", map_iter->first); BIH pTree; pTree.build(mapSpawns, BoundsTrait::getBounds); @@ -107,8 +109,6 @@ namespace VMAP std::map modelNodeIdx; for (uint32 i=0; i(mapSpawns[i]->ID, i)); - if (!modelNodeIdx.empty()) - printf("min GUID: %u, max GUID: %u\n", modelNodeIdx.begin()->first, modelNodeIdx.rbegin()->first); // write map tree file std::stringstream mapfilename; @@ -158,6 +158,8 @@ namespace VMAP StaticMapTree::unpackTileID(tile->first, x, y); tilefilename << std::setw(2) << x << "_" << std::setw(2) << y << ".vmtile"; FILE *tilefile = fopen(tilefilename.str().c_str(), "wb"); + // file header + if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false; // write number of tile spawns if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false; // write tile spawns diff --git a/src/server/collision/Models/ModelInstance.cpp b/src/server/collision/Models/ModelInstance.cpp index 677a08e147a..af32d4026e7 100644 --- a/src/server/collision/Models/ModelInstance.cpp +++ b/src/server/collision/Models/ModelInstance.cpp @@ -1,24 +1,25 @@ /* + * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #include "ModelInstance.h" #include "WorldModel.h" #include "MapTree.h" +#include "VMapDefinitions.h" using G3D::Vector3; using G3D::Ray; diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp index 690c77577ae..0bd156fedc2 100644 --- a/src/server/collision/Models/WorldModel.cpp +++ b/src/server/collision/Models/WorldModel.cpp @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #include "WorldModel.h" @@ -148,15 +148,48 @@ namespace VMAP bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const { - uint32 tx = (pos.x - iCorner.x)/LIQUID_TILE_SIZE; + float tx_f = (pos.x - iCorner.x)/LIQUID_TILE_SIZE; + uint32 tx = uint32(tx_f); if (tx<0 || tx >= iTilesX) return false; - uint32 ty = (pos.y - iCorner.y)/LIQUID_TILE_SIZE; + float ty_f = (pos.y - iCorner.y)/LIQUID_TILE_SIZE; + uint32 ty = uint32(ty_f); if (ty<0 || ty >= iTilesY) return false; + + // check if tile shall be used for liquid level // checking for 0x08 *might* be enough, but disabled tiles always are 0x?F: if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F) return false; - //placeholder...use only lower left corner vertex - liqHeight = /* iCorner.z + */ iHeight[tx + ty*(iTilesX+1)]; + + // (dx, dy) coordinates inside tile, in [0,1]^2 + float dx = tx_f - (float)tx; + float dy = ty_f - (float)ty; + + /* Tesselate tile to two triangles (not sure if client does it exactly like this) + + ^ dy + | + 1 x---------x (1,1) + | (b) / | + | / | + | / | + | / (a) | + x---------x---> dx + 0 1 + */ + + const uint32 rowOffset = iTilesX + 1; + if (dx > dy) // case (a) + { + float sx = iHeight[tx+1 + ty * rowOffset] - iHeight[tx + ty * rowOffset]; + float sy = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx+1 + ty * rowOffset]; + liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy; + } + else // case (b) + { + float sx = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx + (ty+1) * rowOffset]; + float sy = iHeight[tx + (ty+1) * rowOffset] - iHeight[tx + ty * rowOffset]; + liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy; + } return true; } diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index e4a34cc1397..5f4a976ed2a 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-YYYY TrinityCore * Copyright (C) 2005-2010 MaNGOS * - * 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 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 General Public License for more details. + * 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 General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . */ #ifndef _VMAPDEFINITIONS_H diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 3b6d20e093d..b78d8b363cd 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -177,7 +177,7 @@ EAIErrorLevel = 2 # # vmap.enableIndoorCheck # Enable/Disable VMap based indoor check to remove outdoor-only auras (mounts etc.) -# Default: 0 (disabled) +# Default: 1 (enabled) # # DetectPosCollision # Check final move position, summon position, etc for visible collision @@ -244,10 +244,10 @@ PlayerSave.Stats.MinLevel = 0 PlayerSave.Stats.SaveOnlyOnLogout = 1 vmap.enableLOS = 0 vmap.enableHeight = 0 -vmap.ignoreMapIds = "369" +vmap.ignoreMapIds = "" vmap.ignoreSpellIds = "7720" vmap.petLOS = 0 -vmap.enableIndoorCheck = 0 +vmap.enableIndoorCheck = 1 DetectPosCollision = 1 TargetPosRecalculateRange = 1.5 UpdateUptimeInterval = 10 diff --git a/src/tools/vmap3_assembler/VMapAssembler.cpp b/src/tools/vmap3_assembler/VMapAssembler.cpp index 6666b54356c..d714db5ae45 100644 --- a/src/tools/vmap3_assembler/VMapAssembler.cpp +++ b/src/tools/vmap3_assembler/VMapAssembler.cpp @@ -76,11 +76,13 @@ A '#' at the beginning of a line defines a comment return(result); } */ //======================================================= + int main(int argc, char* argv[]) { if(argc != 3 && argc != 4) { - printf("\nusage: %s [config file name]\n", argv[0]); + //printf("\nusage: %s [config file name]\n", argv[0]); + printf("\nusage: %s \n", argv[0]); return 1; } diff --git a/src/tools/vmap3_extractor/dbcfile.h b/src/tools/vmap3_extractor/dbcfile.h index 7381ab9f668..d405d6ffd60 100644 --- a/src/tools/vmap3_extractor/dbcfile.h +++ b/src/tools/vmap3_extractor/dbcfile.h @@ -1,13 +1,27 @@ +/* + * Copyright (C) 2008-2010 TrinityCore + * Copyright (C) 2005-2010 MaNGOS + * + * 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #ifndef DBCFILE_H #define DBCFILE_H -#define __STORMLIB_SELF__ #include #include -//#include "StormLib.h" -#undef min -#undef max class DBCFile { public: diff --git a/src/tools/vmap3_extractor/vmapexport.cpp b/src/tools/vmap3_extractor/vmapexport.cpp index 82e9bd7cc7b..b82f9249f07 100644 --- a/src/tools/vmap3_extractor/vmapexport.cpp +++ b/src/tools/vmap3_extractor/vmapexport.cpp @@ -435,7 +435,7 @@ bool processArgv(int argc, char ** argv, const char *versionString) int main(int argc, char ** argv) { bool success=true; - const char *versionString = "V2.90 2010_05"; + const char *versionString = "V3.00 2010_07"; // Use command line arguments, when some if(!processArgv(argc, argv, versionString)) -- cgit v1.2.3 From 478946284d6949922267a24dae45e4ac4532ff56 Mon Sep 17 00:00:00 2001 From: click Date: Sat, 10 Jul 2010 05:14:05 +0200 Subject: Fix incorrect blocked LOS-calculation on certain locations (by Lynx3d) --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 42 +++++++++++++++------------ src/server/collision/Maps/MapTree.h | 2 +- src/server/collision/Models/ModelInstance.cpp | 7 +++-- 3 files changed, 29 insertions(+), 22 deletions(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index e758581e2f8..fe35e389363 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -41,13 +41,18 @@ namespace VMAP class MapRayCallback { public: - MapRayCallback(ModelInstance *val): prims(val) {} - ModelInstance *prims; + MapRayCallback(ModelInstance *val): prims(val), hit(false) {} bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true) { - return prims[entry].intersectRay(ray, distance, pStopAtFirstHit); - //std::cout << "trying to intersect '" << entity->name << "'\n"; + bool result = prims[entry].intersectRay(ray, distance, pStopAtFirstHit); + if (result) + hit = true; + return result; } + bool didHit() { return hit; } + protected: + ModelInstances *prims; + bool hit; }; class AreaInfoCallback @@ -138,21 +143,23 @@ namespace VMAP //========================================================= /** - return dist to hit or inf() if no hit + If intersection is found within pMaxDist, sets pMaxDist to intersection distance and returns true. + Else, pMaxDist is not modified and returns false; */ - float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const + bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit) const { float distance = pMaxDist; MapRayCallback intersectionCallBack(iTreeValues); iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit); - return distance; + if (intersectionCallBack.didHit()) + pMaxDist = distance; + return intersectionCallBack.didHit(); } //========================================================= bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const { - bool result = true; float maxDist = (pos2 - pos1).magnitude(); // valid map coords should *never ever* produce float overflow, but this would produce NaNs too ASSERT(maxDist < std::numeric_limits::max()); @@ -161,12 +168,10 @@ namespace VMAP return true; // direction with length of 1 G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); - float resultDist = getIntersectionTime(ray, maxDist, true); - if (resultDist < maxDist) - { - result = false; - } - return result; + if (getIntersectionTime(ray, maxDist, true)) + return false; + + return true; } //========================================================= /** @@ -188,8 +193,8 @@ namespace VMAP } Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1 G3D::Ray ray(pPos1, dir); - float dist = getIntersectionTime(ray, maxDist, false); - if (dist < maxDist) + float dist = maxDist; + if (getIntersectionTime(ray, dist, false)) { pResultHitPos = pPos1 + dir * dist; if (pModifyDist < 0) @@ -225,10 +230,9 @@ namespace VMAP Vector3 dir = Vector3(0,0,-1); G3D::Ray ray(pPos, dir); // direction with length of 1 float maxDist = VMapDefinitions::getMaxCanFallDistance(); - float dist = getIntersectionTime(ray, maxDist, false); - if (dist < maxDist) + if (getIntersectionTime(ray, maxDist, false)) { - height = pPos.z - dist; + height = pPos.z - maxDist; } return(height); } diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 7a7af43e949..8f2242da5a6 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -57,7 +57,7 @@ namespace VMAP std::string iBasePath; private: - float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const; + bool getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit) const; //bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); } public: static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY); diff --git a/src/server/collision/Models/ModelInstance.cpp b/src/server/collision/Models/ModelInstance.cpp index af32d4026e7..1ab6b363b22 100644 --- a/src/server/collision/Models/ModelInstance.cpp +++ b/src/server/collision/Models/ModelInstance.cpp @@ -57,8 +57,11 @@ namespace VMAP Ray modRay(p, iInvRot * pRay.direction()); float distance = pMaxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit); - distance *= iScale; - pMaxDist = distance; + if(hit) + { + distance *= iScale; + pMaxDist = distance; + } return hit; } -- cgit v1.2.3 From 63179eb772b39792b087207c0b1b6fdc8bc0e063 Mon Sep 17 00:00:00 2001 From: click Date: Sat, 10 Jul 2010 05:46:21 +0200 Subject: Fix typo in previous commit *sighs* --HG-- branch : trunk --- src/server/collision/Maps/MapTree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/collision/Maps/MapTree.cpp') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index fe35e389363..b47e34b2b72 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -51,7 +51,7 @@ namespace VMAP } bool didHit() { return hit; } protected: - ModelInstances *prims; + ModelInstance *prims; bool hit; }; -- cgit v1.2.3