From e62f64b5912fb1b249680d0bd026b8e4c7d7a022 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Fri, 4 Oct 2013 10:25:44 -0500 Subject: Tools/MeshExtractor: Fixed loading of locale patch MPQs (This fixes DBC extraction) --- src/tools/mesh_extractor/MPQManager.cpp | 75 ++++++++++++++++++++++++++---- src/tools/mesh_extractor/MPQManager.h | 5 +- src/tools/mesh_extractor/MeshExtractor.cpp | 13 ++++-- 3 files changed, 79 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 4d3ab808a2e..950e284f92e 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -14,6 +14,12 @@ char const* MPQManager::Files[] = { "patch-3.MPQ" }; +char const* MPQManager::LocalePatchFiles[] = { + "Data/%s/patch-%s.MPQ", + "Data/%s/patch-%s-2.MPQ", + "Data/%s/patch-%s-3.MPQ" +}; + char const* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; void MPQManager::Initialize() @@ -31,7 +37,6 @@ void MPQManager::Initialize() void MPQManager::InitializeDBC() { BaseLocale = -1; - std::string fileName; uint32 size = sizeof(Languages) / sizeof(char*); MPQArchive* _baseLocale = NULL; for (uint32 i = 0; i < size; ++i) @@ -41,20 +46,34 @@ void MPQManager::InitializeDBC() if (file) { if (BaseLocale == -1) - { BaseLocale = i; - _baseLocale = new MPQArchive(_fileName.c_str()); - fileName = _fileName; - LocaleFiles[i] = _baseLocale; + + // Load the base locale file + MPQArchive* arch = new MPQArchive(_fileName.c_str()); + LocaleFiles[i].push_front(arch); + + Archives.push_front(arch); // For lookup in GetFile + + // Load the locale patches + for (uint32 j = 0; j < sizeof(LocalePatchFiles) / sizeof(char*); ++j) + { + char patchName[100]; + sprintf(patchName, LocalePatchFiles[j], Languages[i], Languages[i]); + FILE* patch = fopen(patchName, "rb"); + if (file) + { + MPQArchive* archP = new MPQArchive(patchName); + LocaleFiles[i].push_front(archP); + Archives.push_front(archP); // For lookup in GetFile + fclose(patch); + } } - else - LocaleFiles[i] = new MPQArchive(_fileName.c_str()); AvailableLocales.insert(i); printf("Detected locale: %s\n", Languages[i]); } } - Archives.push_front(_baseLocale); + if (BaseLocale == -1) { printf("No locale data detected. Please make sure that the executable is in the same folder as your WoW installation.\n"); @@ -79,6 +98,46 @@ DBC* MPQManager::GetDBC(const std::string& name ) return new DBC(GetFile(path)); } +FILE* MPQManager::GetFileFromLocale( const std::string& path, uint32 locale ) +{ + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); + std::deque files = LocaleFiles[locale]; + FILE* ret = NULL; + for (std::deque::iterator itr = files.begin(); itr != files.end(); ++itr) + { + mpq_archive* mpq_a = (*itr)->mpq_a; + + uint32_t filenum; + if(libmpq__file_number(mpq_a, path.c_str(), &filenum)) + continue; + libmpq__off_t transferred; + libmpq__off_t size = 0; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size <= 1) + continue; + + char* buffer = new char[size]; + + //libmpq_file_getdata + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + + // Pack the return into a FILE stream + ret = tmpfile(); + if (!ret) + { + printf("Could not create temporary file. Please run as Administrator or root\n"); + exit(1); + } + fwrite(buffer, sizeof(uint8), size, ret); + fseek(ret, 0, SEEK_SET); + delete[] buffer; + break; + } + return ret; +} + FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 7f9d675c4d4..3514674b9bf 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -16,15 +16,18 @@ public: void Initialize(); FILE* GetFile(const std::string& path); FILE* GetFileFrom(const std::string& path, MPQArchive* file); + FILE* GetFileFromLocale(const std::string& path, uint32 locale); + DBC* GetDBC(const std::string& name); std::vector GetAllFiles(std::string extension); std::deque Archives; int32 BaseLocale; std::set AvailableLocales; - std::map LocaleFiles; + std::map > LocaleFiles; static char const* Files[]; + static char const* LocalePatchFiles[]; static char const* Languages[]; protected: void InitializeDBC(); diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0d9160a610b..9cc7eea5509 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -58,9 +58,12 @@ void ExtractDBCs() // Populate list of DBC files // We get the DBC names by going over the (guaranteed to exist) default locale files // Then we look in other locale files in case that they are available. - for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) - if (itr->rfind(".dbc") == itr->length() - extLen) // Check if the extension is ".dbc" - DBCFiles.insert(*itr); + for (std::map >::iterator itr = MPQHandler->LocaleFiles.begin(); itr != MPQHandler->LocaleFiles.end(); ++itr) + for (std::deque::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) + for (std::vector::iterator itr3 = (*itr2)->Files.begin(); itr3 != (*itr2)->Files.end(); ++itr3) + if (itr3->rfind(".dbc") == itr3->length() - extLen) // Check if the extension is ".dbc" + if (DBCFiles.find(*itr3) == DBCFiles.end()) + DBCFiles.insert(*itr3); const size_t folderLen = strlen("DBFilesClient\\"); // Iterate over all available locales @@ -76,10 +79,10 @@ void ExtractDBCs() std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; // Extract the component file - Utils::SaveToDisk(MPQHandler->GetFileFrom(component, MPQHandler->LocaleFiles[*itr]), path + component); + Utils::SaveToDisk(MPQHandler->GetFileFromLocale(component, *itr), path + component); // Extract the DBC files for the given locale for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) - Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + folderLen)); + Utils::SaveToDisk(MPQHandler->GetFileFromLocale(*itr2, *itr), path + (itr2->c_str() + folderLen)); } printf("DBC extraction finished!\n"); } -- cgit v1.2.3 From a27237dedd1b770ab4e66570e7a236a44d2c9e00 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Fri, 4 Oct 2013 22:23:17 -0500 Subject: Core/MMaps: MMaps are now correctly loaded into TC P.S: They do behave better in some places, but are still a bit weird in some others, will have to look into that. P.P.S: I'll have to re-implement all the previous PathGenerator code --- src/server/game/Maps/Map.cpp | 6 +- src/server/game/Miscellaneous/SharedDefines.h | 2 +- .../ConfusedMovementGenerator.cpp | 1 - .../FleeingMovementGenerator.cpp | 1 - src/server/game/Movement/PathGenerator.cpp | 755 ++------------------- src/server/game/Movement/PathGenerator.h | 52 -- src/server/game/Spells/Spell.cpp | 1 - src/server/scripts/Commands/cs_mmaps.cpp | 68 +- src/tools/mesh_extractor/MeshExtractor.cpp | 8 +- src/tools/mesh_extractor/TileBuilder.cpp | 4 +- 10 files changed, 125 insertions(+), 773 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 3156a071854..aaeb06462ef 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -121,7 +121,11 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { - bool mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), gx, gy); + bool mmapLoadResult = false; + if (GetEntry()->Instanceable()) + mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), 0, 0); // Ignore the tile entry for instances, as they only have 1 tile. + else + mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), gx, gy); if (mmapLoadResult) TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP loaded name: %s, id: %d, x: %d, y: %d", GetMapName(), GetId(), gx, gy); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e561d37ed36..6ed0982e631 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3541,7 +3541,7 @@ enum PartyResult }; const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' -#define MMAP_VERSION 4 +#define MMAP_VERSION 3 struct MmapTileHeader { diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index ef24b112253..63b1cf283a4 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -86,7 +86,6 @@ bool ConfusedMovementGenerator::DoUpdate(T* unit, uint32 diff) unit->MovePositionToFirstCollision(pos, dest, 0.0f); PathGenerator path(unit); - path.SetPathLengthLimit(30.0f); bool result = path.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ); if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index f78411fc547..1c65499fe50 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -44,7 +44,6 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) _getPoint(owner, x, y, z); PathGenerator path(owner); - path.SetPathLengthLimit(30.0f); bool result = path.CalculatePath(x, y, z); if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 3216cb8103e..c5922156939 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -29,12 +29,10 @@ ////////////////// PathGenerator ////////////////// PathGenerator::PathGenerator(const Unit* owner) : - _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false), - _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), - _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(NULL), - _navMeshQuery(NULL) + _type(PATHFIND_BLANK), _endPosition(G3D::Vector3::zero()), + _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL) { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); uint32 mapId = _sourceUnit->GetMapId(); if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) @@ -49,7 +47,7 @@ PathGenerator::PathGenerator(const Unit* owner) : PathGenerator::~PathGenerator() { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow()); } bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) @@ -66,463 +64,88 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo G3D::Vector3 start(x, y, z); SetStartPosition(start); - _forceDestination = forceDest; - - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow()); // make sure navMesh works - we can run on map w/o mmap // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) - if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || - !HaveTile(start) || !HaveTile(dest)) + if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING)) { - BuildShortcut(); _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); return true; } UpdateFilter(); - BuildPolyPath(start, dest); - return true; -} - -dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* point, float* distance) const -{ - if (!polyPath || !polyPathSize) - return INVALID_POLYREF; - - dtPolyRef nearestPoly = INVALID_POLYREF; - float minDist2d = FLT_MAX; - float minDist3d = 0.0f; + float startPos[3]; + startPos[0] = -y; + startPos[1] = z; + startPos[2] = -x; - for (uint32 i = 0; i < polyPathSize; ++i) - { - float closestPoint[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint))) - continue; - - float d = dtVdist2DSqr(point, closestPoint); - if (d < minDist2d) - { - minDist2d = d; - nearestPoly = polyPath[i]; - minDist3d = dtVdistSqr(point, closestPoint); - } + float endPos[3]; + endPos[0] = -destY; + endPos[1] = destZ; + endPos[2] = -destX; - if (minDist2d < 1.0f) // shortcut out - close enough for us - break; - } + float polyPickExt[3]; + polyPickExt[0] = 2.5f; + polyPickExt[1] = 2.5f; + polyPickExt[2] = 2.5f; - if (distance) - *distance = dtSqrt(minDist3d); + // + dtPolyRef startRef; + dtPolyRef endRef; - return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF; -} + float nearestPt[3]; -dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance) const -{ - // first we check the current path - // if the current path doesn't contain the current poly, - // we need to use the expensive navMesh.findNearestPoly - dtPolyRef polyRef = GetPathPolyByPosition(_pathPolyRefs, _polyLength, point, distance); - if (polyRef != INVALID_POLYREF) - return polyRef; + _navMeshQuery->findNearestPoly(startPos, polyPickExt, &_filter, &startRef, nearestPt); + _navMeshQuery->findNearestPoly(endPos, polyPickExt, &_filter, &endRef, nearestPt); - // we don't have it in our old path - // try to get it by findNearestPoly() - // first try with low search box - float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area - float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f}; - if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF) + if (!startRef || !endRef) { - *distance = dtVdist(closestPoint, point); - return polyRef; - } - - // still nothing .. - // try with bigger search box - // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly) - extents[1] = 50.0f; - - if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF) - { - *distance = dtVdist(closestPoint, point); - return polyRef; - } - - return INVALID_POLYREF; -} - -void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos) -{ - // *** getting start/end poly logic *** - - float distToStartPoly, distToEndPoly; - float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x}; - float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x}; - - dtPolyRef startPoly = GetPolyByLocation(startPoint, &distToStartPoly); - dtPolyRef endPoly = GetPolyByLocation(endPoint, &distToEndPoly); - - // we have a hole in our mesh - // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) - // its up to caller how he will use this info - if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); - BuildShortcut(); - bool path = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanFly(); - - bool waterPath = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanSwim(); - if (waterPath) - { - // Check both start and end points, if they're both in water, then we can *safely* let the creature move - for (uint32 i = 0; i < _pathPoints.size(); ++i) - { - ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); - // One of the points is not in the water, cancel movement. - if (status == LIQUID_MAP_NO_WATER) - { - waterPath = false; - break; - } - } - } - - _type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; - return; - } - - // we may need a better number here - bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); - if (farFromPoly) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly); - - bool buildShotrcut = false; - if (_sourceUnit->GetTypeId() == TYPEID_UNIT) - { - Creature* owner = (Creature*)_sourceUnit; - - G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos; - if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n"); - if (owner->CanSwim()) - buildShotrcut = true; - } - else - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n"); - if (owner->CanFly()) - buildShotrcut = true; - } - } - - if (buildShotrcut) - { - BuildShortcut(); - _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); - return; - } - else - { - float closestPoint[VERTEX_SIZE]; - // we may want to use closestPointOnPolyBoundary instead - if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))) - { - dtVcopy(endPoint, closestPoint); - SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1])); - } - - _type = PATHFIND_INCOMPLETE; - } - } - - // *** poly path generating logic *** - - // start and end are on same polygon - // just need to move in straight line - if (startPoly == endPoly) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == endPoly)\n"); - - BuildShortcut(); - - _pathPolyRefs[0] = startPoly; - _polyLength = 1; - - _type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", _type); - return; - } - - // look for startPoly/endPoly in current path - /// @todo we can merge it with getPathPolyByPosition() loop - bool startPolyFound = false; - bool endPolyFound = false; - uint32 pathStartIndex = 0; - uint32 pathEndIndex = 0; - - if (_polyLength) - { - for (; pathStartIndex < _polyLength; ++pathStartIndex) - { - // here to carch few bugs - ASSERT(_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); - - if (_pathPolyRefs[pathStartIndex] == startPoly) - { - startPolyFound = true; - break; - } - } - - for (pathEndIndex = _polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) - if (_pathPolyRefs[pathEndIndex] == endPoly) - { - endPolyFound = true; - break; - } - } - - if (startPolyFound && endPolyFound) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n"); - - // we moved along the path and the target did not move out of our old poly-path - // our path is a simple subpath case, we have all the data we need - // just "cut" it out - - _polyLength = pathEndIndex - pathStartIndex + 1; - memmove(_pathPolyRefs, _pathPolyRefs + pathStartIndex, _polyLength * sizeof(dtPolyRef)); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no polygons found for start and end locations\n", _sourceUnit->GetGUIDLow()); + _type = PATHFIND_NOPATH; + return false; } - else if (startPolyFound && !endPolyFound) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n"); - - // we are moving on the old path but target moved out - // so we have atleast part of poly-path ready - - _polyLength -= pathStartIndex; - // try to adjust the suffix of the path instead of recalculating entire length - // at given interval the target cannot get too far from its last location - // thus we have less poly to cover - // sub-path of optimal path is optimal - - // take ~80% of the original length - /// @todo play with the values here - uint32 prefixPolyLength = uint32(_polyLength * 0.8f + 0.5f); - memmove(_pathPolyRefs, _pathPolyRefs+pathStartIndex, prefixPolyLength * sizeof(dtPolyRef)); - - dtPolyRef suffixStartPoly = _pathPolyRefs[prefixPolyLength-1]; - - // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data - float suffixEndPoint[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))) - { - // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that - // try to recover by using prev polyref - --prefixPolyLength; - suffixStartPoly = _pathPolyRefs[prefixPolyLength-1]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))) - { - // suffixStartPoly is still invalid, error state - BuildShortcut(); - _type = PATHFIND_NOPATH; - return; - } - } - - // generate suffix - uint32 suffixPolyLength = 0; - dtStatus dtResult = _navMeshQuery->findPath( - suffixStartPoly, // start polygon - endPoly, // end polygon - suffixEndPoint, // start position - endPoint, // end position - &_filter, // polygon search filter - _pathPolyRefs + prefixPolyLength - 1, // [out] path - (int*)&suffixPolyLength, - MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path - - if (!suffixPolyLength || dtStatusFailed(dtResult)) - { - // this is probably an error state, but we'll leave it - // and hopefully recover on the next Update - // we still need to copy our preffix - TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); - } - - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n", _polyLength, prefixPolyLength, suffixPolyLength); - - // new path = prefix + suffix - overlap - _polyLength = prefixPolyLength + suffixPolyLength - 1; - } - else + int hops; + dtPolyRef* hopBuffer = new dtPolyRef[8192]; + dtStatus status = _navMeshQuery->findPath(startRef, endRef, startPos, endPos, &_filter, hopBuffer, &hops, 8192); + + if (!dtStatusSucceed(status)) { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n"); - - // either we have no path at all -> first run - // or something went really wrong -> we aren't moving along the path to the target - // just generate new path - - // free and invalidate old path data - Clear(); - - dtStatus dtResult = _navMeshQuery->findPath( - startPoly, // start polygon - endPoly, // end polygon - startPoint, // start position - endPoint, // end position - &_filter, // polygon search filter - _pathPolyRefs, // [out] path - (int*)&_polyLength, - MAX_PATH_LENGTH); // max number of polygons in output path - - if (!_polyLength || dtStatusFailed(dtResult)) - { - // only happens if we passed bad data to findPath(), or navmesh is messed up - TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); - BuildShortcut(); - _type = PATHFIND_NOPATH; - return; - } + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no path found for start and end locations\n", _sourceUnit->GetGUIDLow()); + _type = PATHFIND_NOPATH; + return false; } - // by now we know what type of path we can get - if (_pathPolyRefs[_polyLength - 1] == endPoly && !(_type & PATHFIND_INCOMPLETE)) - _type = PATHFIND_NORMAL; - else - _type = PATHFIND_INCOMPLETE; - - // generate the point-path out of our up-to-date poly-path - BuildPointPath(startPoint, endPoint); -} - -void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoint) -{ - float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE]; - uint32 pointCount = 0; - dtStatus dtResult = DT_FAILURE; - if (_useStraightPath) - { - dtResult = _navMeshQuery->findStraightPath( - startPoint, // start position - endPoint, // end position - _pathPolyRefs, // current path - _polyLength, // lenth of current path - pathPoints, // [out] path corner points - NULL, // [out] flags - NULL, // [out] shortened path - (int*)&pointCount, - _pointPathLimit); // maximum number of points/polygons to use - } - else - { - dtResult = FindSmoothPath( - startPoint, // start position - endPoint, // end position - _pathPolyRefs, // current path - _polyLength, // length of current path - pathPoints, // [out] path corner points - (int*)&pointCount, - _pointPathLimit); // maximum number of points - } + int resultHopCount; + float* straightPath = new float[2048 * 3]; + unsigned char* pathFlags = new unsigned char[2048]; + dtPolyRef* pathRefs = new dtPolyRef[2048]; - if (pointCount < 2 || dtStatusFailed(dtResult)) + status = _navMeshQuery->findStraightPath(startPos, endPos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); + if (!dtStatusSucceed(status)) { - // only happens if pass bad data to findStraightPath or navmesh is broken - // single point paths can be generated here - /// @todo check the exact cases - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount); - BuildShortcut(); + TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no straight path found for start and end locations\n", _sourceUnit->GetGUIDLow()); _type = PATHFIND_NOPATH; - return; - } - else if (pointCount == _pointPathLimit) - { - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, _pointPathLimit); - BuildShortcut(); - _type = PATHFIND_SHORT; - return; + return false; } - _pathPoints.resize(pointCount); - for (uint32 i = 0; i < pointCount; ++i) - _pathPoints[i] = G3D::Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); + for (uint32 i = 0; i < resultHopCount; ++i) + _pathPoints.push_back(G3D::Vector3(-straightPath[i * 3 + 2], -straightPath[i * 3 + 0], straightPath[i * 3 + 1])); - NormalizePath(); - - // first point is always our current location - we need the next one - SetActualEndPosition(_pathPoints[pointCount-1]); - - // force the given destination, if needed - if (_forceDestination && - (!(_type & PATHFIND_NORMAL) || !InRange(GetEndPosition(), GetActualEndPosition(), 1.0f, 1.0f))) - { - // we may want to keep partial subpath - if (Dist3DSqr(GetActualEndPosition(), GetEndPosition()) < 0.3f * Dist3DSqr(GetStartPosition(), GetEndPosition())) - { - SetActualEndPosition(GetEndPosition()); - _pathPoints[_pathPoints.size()-1] = GetEndPosition(); - } - else - { - SetActualEndPosition(GetEndPosition()); - BuildShortcut(); - } - - _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); - } - - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", _type, pointCount, _polyLength); -} - -void PathGenerator::NormalizePath() -{ - for (uint32 i = 0; i < _pathPoints.size(); ++i) - _sourceUnit->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z); -} - -void PathGenerator::BuildShortcut() -{ - TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); - - Clear(); - - // make two point path, our curr pos is the start, and dest is the end - _pathPoints.resize(2); - - // set start and a default next position - _pathPoints[0] = GetStartPosition(); - _pathPoints[1] = GetActualEndPosition(); - - NormalizePath(); - - _type = PATHFIND_SHORTCUT; + return true; } void PathGenerator::CreateFilter() { - uint16 includeFlags = 0; + uint16 includeFlags = 1 | 2; uint16 excludeFlags = 0; - - if (_sourceUnit->GetTypeId() == TYPEID_UNIT) - { - Creature* creature = (Creature*)_sourceUnit; - if (creature->CanWalk()) - includeFlags |= NAV_GROUND; // walk - - // creatures don't take environmental damage - if (creature->CanSwim()) - includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim - } - else // assume Player + + if (_sourceUnit->GetTypeId() == TYPEID_UNIT && !_sourceUnit->ToCreature()->CanSwim()) { - // perfect support not possible, just stay 'safe' - includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME); + includeFlags = 1; + excludeFlags = 2; } _filter.setIncludeFlags(includeFlags); @@ -533,275 +156,5 @@ void PathGenerator::CreateFilter() void PathGenerator::UpdateFilter() { - // allow creatures to cheat and use different movement types if they are moved - // forcefully into terrain they can't normally move in - if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater()) - { - uint16 includedFlags = _filter.getIncludeFlags(); - includedFlags |= GetNavTerrain(_sourceUnit->GetPositionX(), - _sourceUnit->GetPositionY(), - _sourceUnit->GetPositionZ()); - - _filter.setIncludeFlags(includedFlags); - } -} - -NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) -{ - LiquidData data; - ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); - if (liquidStatus == LIQUID_MAP_NO_WATER) - return NAV_GROUND; - - switch (data.type_flags) - { - case MAP_LIQUID_TYPE_WATER: - case MAP_LIQUID_TYPE_OCEAN: - return NAV_WATER; - case MAP_LIQUID_TYPE_MAGMA: - return NAV_MAGMA; - case MAP_LIQUID_TYPE_SLIME: - return NAV_SLIME; - default: - return NAV_GROUND; - } -} - -bool PathGenerator::HaveTile(const G3D::Vector3& p) const -{ - int tx = -1, ty = -1; - float point[VERTEX_SIZE] = {p.y, p.z, p.x}; - - _navMesh->calcTileLoc(point, &tx, &ty); - - /// Workaround - /// For some reason, often the tx and ty variables wont get a valid value - /// Use this check to prevent getting negative tile coords and crashing on getTileAt - if (tx < 0 || ty < 0) - return false; - - return (_navMesh->getTileAt(tx, ty, 0) != NULL); -} - -uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) -{ - int32 furthestPath = -1; - int32 furthestVisited = -1; - - // Find furthest common polygon. - for (int32 i = npath-1; i >= 0; --i) - { - bool found = false; - for (int32 j = nvisited-1; j >= 0; --j) - { - if (path[i] == visited[j]) - { - furthestPath = i; - furthestVisited = j; - found = true; - } - } - if (found) - break; - } - - // If no intersection found just return current path. - if (furthestPath == -1 || furthestVisited == -1) - return npath; - - // Concatenate paths. - - // Adjust beginning of the buffer to include the visited. - uint32 req = nvisited - furthestVisited; - uint32 orig = uint32(furthestPath + 1) < npath ? furthestPath + 1 : npath; - uint32 size = npath > orig ? npath - orig : 0; - if (req + size > maxPath) - size = maxPath-req; - - if (size) - memmove(path + req, path + orig, size * sizeof(dtPolyRef)); - - // Store visited - for (uint32 i = 0; i < req; ++i) - path[i] = visited[(nvisited - 1) - i]; - - return req+size; -} - -bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos, - float minTargetDist, dtPolyRef const* path, uint32 pathSize, - float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef) -{ - // Find steer target. - static const uint32 MAX_STEER_POINTS = 3; - float steerPath[MAX_STEER_POINTS*VERTEX_SIZE]; - unsigned char steerPathFlags[MAX_STEER_POINTS]; - dtPolyRef steerPathPolys[MAX_STEER_POINTS]; - uint32 nsteerPath = 0; - dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, - steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS); - if (!nsteerPath || dtStatusFailed(dtResult)) - return false; - - // Find vertex far enough to steer to. - uint32 ns = 0; - while (ns < nsteerPath) - { - // Stop at Off-Mesh link or when point is further than slop away. - if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || - !InRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) - break; - ns++; - } - // Failed to find good point to steer to. - if (ns >= nsteerPath) - return false; - - dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]); - steerPos[1] = startPos[1]; // keep Z value - steerPosFlag = steerPathFlags[ns]; - steerPosRef = steerPathPolys[ns]; - - return true; -} - -dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPos, - dtPolyRef const* polyPath, uint32 polyPathSize, - float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize) -{ - *smoothPathSize = 0; - uint32 nsmoothPath = 0; - - dtPolyRef polys[MAX_PATH_LENGTH]; - memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize); - uint32 npolys = polyPathSize; - - float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos))) - return DT_FAILURE; - - if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos))) - return DT_FAILURE; - - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - - // Move towards target a small advancement at a time until target reached or - // when ran out of memory to store the path. - while (npolys && nsmoothPath < maxSmoothPathSize) - { - // Find location to steer towards. - float steerPos[VERTEX_SIZE]; - unsigned char steerPosFlag; - dtPolyRef steerPosRef = INVALID_POLYREF; - - if (!GetSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) - break; - - bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END); - bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION); - - // Find movement delta. - float delta[VERTEX_SIZE]; - dtVsub(delta, steerPos, iterPos); - float len = dtSqrt(dtVdot(delta, delta)); - // If the steer target is end of path or off-mesh link, do not move past the location. - if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE) - len = 1.0f; - else - len = SMOOTH_PATH_STEP_SIZE / len; - - float moveTgt[VERTEX_SIZE]; - dtVmad(moveTgt, iterPos, delta, len); - - // Move - float result[VERTEX_SIZE]; - const static uint32 MAX_VISIT_POLY = 16; - dtPolyRef visited[MAX_VISIT_POLY]; - - uint32 nvisited = 0; - _navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); - npolys = FixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); - - _navMeshQuery->getPolyHeight(polys[0], result, &result[1]); - result[1] += 0.5f; - dtVcopy(iterPos, result); - - // Handle end of path and off-mesh links when close enough. - if (endOfPath && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) - { - // Reached end of path. - dtVcopy(iterPos, targetPos); - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - } - break; - } - else if (offMeshConnection && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) - { - // Advance the path up to and over the off-mesh connection. - dtPolyRef prevRef = INVALID_POLYREF; - dtPolyRef polyRef = polys[0]; - uint32 npos = 0; - while (npos < npolys && polyRef != steerPosRef) - { - prevRef = polyRef; - polyRef = polys[npos]; - npos++; - } - - for (uint32 i = npos; i < npolys; ++i) - polys[i-npos] = polys[i]; - - npolys -= npos; - - // Handle the connection. - float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; - if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))) - { - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos); - nsmoothPath++; - } - // Move position at the other side of the off-mesh link. - dtVcopy(iterPos, endPos); - _navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); - iterPos[1] += 0.5f; - } - } - - // Store results. - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - } - } - - *smoothPathSize = nsmoothPath; - - // this is most likely a loop - return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; -} - -bool PathGenerator::InRangeYZX(const float* v1, const float* v2, float r, float h) const -{ - const float dx = v2[0] - v1[0]; - const float dy = v2[1] - v1[1]; // elevation - const float dz = v2[2] - v1[2]; - return (dx * dx + dz * dz) < r * r && fabsf(dy) < h; -} - -bool PathGenerator::InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const -{ - G3D::Vector3 d = p1 - p2; - return (d.x * d.x + d.y * d.y) < r * r && fabsf(d.z) < h; -} - -float PathGenerator::Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const -{ - return (p1 - p2).squaredLength(); -} + +} \ No newline at end of file diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index ac66b7cec57..507f8e8defb 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -26,18 +26,6 @@ class Unit; -// 74*4.0f=296y number_of_points*interval = max_path_len -// this is way more than actual evade range -// I think we can safely cut those down even more -#define MAX_PATH_LENGTH 74 -#define MAX_POINT_PATH_LENGTH 74 - -#define SMOOTH_PATH_STEP_SIZE 4.0f -#define SMOOTH_PATH_SLOP 0.3f - -#define VERTEX_SIZE 3 -#define INVALID_POLYREF 0 - enum PathType { PATHFIND_BLANK = 0x00, // path not built yet @@ -59,10 +47,6 @@ class PathGenerator // return: true if new path was calculated, false otherwise (no change needed) bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); - // option setters - use optional - void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; } - void SetPathLengthLimit(float distance) { _pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); } - // result getters G3D::Vector3 const& GetStartPosition() const { return _startPosition; } G3D::Vector3 const& GetEndPosition() const { return _endPosition; } @@ -73,17 +57,9 @@ class PathGenerator PathType GetPathType() const { return _type; } private: - - dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references - uint32 _polyLength; // number of polygons in the path - Movement::PointsArray _pathPoints; // our actual (x,y,z) path to the target PathType _type; // tells what kind of path this is - bool _useStraightPath; // type of path will be generated - bool _forceDestination; // when set, we will always arrive at given point - uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) - G3D::Vector3 _startPosition; // {x, y, z} of current location G3D::Vector3 _endPosition; // {x, y, z} of the destination G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination @@ -97,37 +73,9 @@ class PathGenerator void SetStartPosition(G3D::Vector3 const& point) { _startPosition = point; } void SetEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; _endPosition = point; } void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; } - void NormalizePath(); - - void Clear() - { - _polyLength = 0; - _pathPoints.clear(); - } - - bool InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const; - float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const; - bool InRangeYZX(float const* v1, float const* v2, float r, float h) const; - dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = NULL) const; - dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const; - bool HaveTile(G3D::Vector3 const& p) const; - - void BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos); - void BuildPointPath(float const* startPoint, float const* endPoint); - void BuildShortcut(); - - NavTerrain GetNavTerrain(float x, float y, float z); void CreateFilter(); void UpdateFilter(); - - // smooth path aux functions - uint32 FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited); - bool GetSteerTarget(float const* startPos, float const* endPos, float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos, - unsigned char& steerPosFlag, dtPolyRef& steerPosRef); - dtStatus FindSmoothPath(float const* startPos, float const* endPos, - dtPolyRef const* polyPath, uint32 polyPathSize, - float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize); }; #endif diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index b2e8a89c86d..804a7f25a12 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5162,7 +5162,6 @@ SpellCastResult Spell::CheckCast(bool strict) target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); - m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index d0b1fdc2abd..0beb10af4fc 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -92,10 +92,10 @@ public: player->GetPosition(x, y, z); // path - PathGenerator path(target); + /*PathGenerator path(target); path.SetUseStraightPath(useStraightPath); bool result = path.CalculatePath(x, y, z); - + Movement::PointsArray const& pointPath = path.GetPath(); handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); @@ -108,13 +108,63 @@ public: handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z); handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z); handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); + */ + float m_spos[3]; + m_spos[0] = -y; + m_spos[1] = z; + m_spos[2] = -x; + + // + float m_epos[3]; + m_epos[0] = -target->GetPositionY(); + m_epos[1] = target->GetPositionZ(); + m_epos[2] = -target->GetPositionX(); + + // + dtQueryFilter m_filter; + m_filter.setIncludeFlags(3); + m_filter.setExcludeFlags(2); + + // + float m_polyPickExt[3]; + m_polyPickExt[0] = 2.5f; + m_polyPickExt[1] = 2.5f; + m_polyPickExt[2] = 2.5f; + + // + dtPolyRef m_startRef; + dtPolyRef m_endRef; + + const dtNavMesh* navMesh = MMAP::MMapFactory::CreateOrGetMMapManager()->GetNavMesh(player->GetMapId()); + const dtNavMeshQuery* navMeshQuery = MMAP::MMapFactory::CreateOrGetMMapManager()->GetNavMeshQuery(player->GetMapId(), handler->GetSession()->GetPlayer()->GetInstanceId()); + + float nearestPt[3]; + + navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + + if ( !m_startRef || !m_endRef ) + { + std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; + return 0; + } + + int hops; + dtPolyRef* hopBuffer = new dtPolyRef[8192]; + dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192); + + int resultHopCount; + float* straightPath = new float[2048*3]; + unsigned char* pathFlags = new unsigned char[2048]; + dtPolyRef* pathRefs = new dtPolyRef[2048]; + + status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); + for (uint32 i = 0; i < resultHopCount; ++i) + player->SummonCreature(VISUAL_WAYPOINT, -straightPath[i * 3 + 2], -straightPath[i * 3 + 0], straightPath[i * 3 + 1], 0, TEMPSUMMON_TIMED_DESPAWN, 9000); if (!player->IsGameMaster()) handler->PSendSysMessage("Enable GM mode to see the path points."); - for (uint32 i = 0; i < pointPath.size(); ++i) - player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); - return true; } @@ -143,8 +193,8 @@ public: float const* min = navmesh->getParams()->orig; float x, y, z; player->GetPosition(x, y, z); - float location[VERTEX_SIZE] = {y, z, x}; - float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; + float location[] = {y, z, x}; + float extents[] = {3.0f, 5.0f, 3.0f}; int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); @@ -153,14 +203,14 @@ public: // navmesh poly -> navmesh tile location dtQueryFilter filter = dtQueryFilter(); - dtPolyRef polyRef = INVALID_POLYREF; + dtPolyRef polyRef = 0; if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL))) { handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)"); return true; } - if (polyRef == INVALID_POLYREF) + if (polyRef == 0) handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)"); else { diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 9cc7eea5509..51b13ce6fd0 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -381,8 +381,8 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_TEST) { - float start[] = { 16226.200195f, 16257.000000f, 13.202200f }; - float end[] = { 16245.725586f, 16382.465820f, 47.384956f }; + float start[] = { -1.37402868f, -21.7641087f, -20.1751060f }; + float end[] = { -22.756405f, -62.745014f, -21.371508f }; // float m_spos[3]; @@ -411,7 +411,7 @@ int main(int argc, char* argv[]) dtPolyRef m_startRef; dtPolyRef m_endRef; - FILE* mmap = fopen("mmaps/001.mmap", "rb"); + FILE* mmap = fopen("mmaps/389.mmap", "rb"); dtNavMeshParams params; int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); @@ -430,7 +430,7 @@ int main(int argc, char* argv[]) for (int j = 0; j <= 32; ++j) { char buff[100]; - sprintf(buff, "mmaps/001%02i%02i.mmtile", i, j); + sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j); LoadTile(navMesh, buff); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 51df91d2652..cdc3131b3db 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -42,13 +42,13 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, InstanceConfig.mergeRegionArea = 100; InstanceConfig.walkableSlopeAngle = 50.0f; InstanceConfig.detailSampleDist = 3.0f; - InstanceConfig.detailSampleMaxError = 1.5f; + InstanceConfig.detailSampleMaxError = 1.25f; InstanceConfig.walkableClimb = 1.0f / InstanceConfig.ch; InstanceConfig.walkableHeight = 2.1f / InstanceConfig.ch; InstanceConfig.walkableRadius = 0.6f / InstanceConfig.cs; InstanceConfig.maxEdgeLen = 8 * InstanceConfig.walkableRadius; InstanceConfig.maxVertsPerPoly = 6; - InstanceConfig.maxSimplificationError = 1.25f; + InstanceConfig.maxSimplificationError = 1.3f; InstanceConfig.borderSize = 0; Context = new rcContext; -- cgit v1.2.3 From 6e994f11894d639f8566a14a60026df7749f79e3 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sat, 5 Oct 2013 18:52:46 -0500 Subject: Core/MMaps: Bump mmaps version to 5 --- src/server/game/Miscellaneous/SharedDefines.h | 2 +- src/tools/mesh_extractor/Utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 6ed0982e631..c2daca325e4 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3541,7 +3541,7 @@ enum PartyResult }; const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' -#define MMAP_VERSION 3 +#define MMAP_VERSION 5 struct MmapTileHeader { diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index d6bb421a633..472cf6dbd1b 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -334,7 +334,7 @@ public: }; #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 3 +#define MMAP_VERSION 5 struct MmapTileHeader { -- cgit v1.2.3 From 64ab895f1e36470bc0623111d77bf7b815984ed1 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sat, 5 Oct 2013 18:56:09 -0500 Subject: Tools/MeshExtractor: Create the mmaps output directory automatically. --- src/tools/mesh_extractor/MeshExtractor.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 51b13ce6fd0..1ed09e5d9dc 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -19,6 +19,9 @@ CacheClass* Cache; void ExtractMMaps(std::set& mapIds, uint32 threads) { + std::string basePath = "mmaps/"; + Utils::CreateDir(basePath); + DBC* dbc = MPQHandler->GetDBC("Map"); printf("Map.dbc contains %u rows.\n", dbc->Records.size()); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) -- cgit v1.2.3 From 79ad827895acc0439336a48055164c4242a89a90 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sat, 5 Oct 2013 22:18:38 -0500 Subject: Tools/MeshExtractor: Rewrote the MeshExtractor to use a custom Stream class instead of FILE pointers, this way we avoid the errors that were caused by reaching the maximum limit of the tmpfile function, and the maximum number of open file streams at any given time. P.S: This was no easy task, damnit. --- src/tools/mesh_extractor/ADT.cpp | 2 +- src/tools/mesh_extractor/CMakeLists.txt | 2 +- src/tools/mesh_extractor/Chunk.cpp | 16 +- src/tools/mesh_extractor/Chunk.h | 8 +- src/tools/mesh_extractor/ChunkedData.cpp | 37 ++- src/tools/mesh_extractor/ChunkedData.h | 5 +- src/tools/mesh_extractor/DBC.cpp | 37 +-- src/tools/mesh_extractor/DBC.h | 4 +- src/tools/mesh_extractor/DoodadHandler.cpp | 31 +- src/tools/mesh_extractor/DoodadHandler.h | 17 +- src/tools/mesh_extractor/LiquidHandler.cpp | 20 +- src/tools/mesh_extractor/MPQ.cpp | 14 +- src/tools/mesh_extractor/MPQ.h | 9 +- src/tools/mesh_extractor/MPQManager.cpp | 29 +- src/tools/mesh_extractor/MPQManager.h | 7 +- src/tools/mesh_extractor/MapChunk.cpp | 14 +- src/tools/mesh_extractor/MapChunk.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 1 - src/tools/mesh_extractor/Model.cpp | 31 +- src/tools/mesh_extractor/Model.h | 3 +- src/tools/mesh_extractor/Stream.cpp | 47 +++ src/tools/mesh_extractor/Stream.h | 53 ++++ src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/Utils.cpp | 424 ++++++++++--------------- src/tools/mesh_extractor/Utils.h | 44 +-- src/tools/mesh_extractor/WDT.cpp | 14 +- src/tools/mesh_extractor/WorldModelGroup.cpp | 45 +-- src/tools/mesh_extractor/WorldModelHandler.cpp | 46 ++- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 14 +- 30 files changed, 468 insertions(+), 512 deletions(-) create mode 100644 src/tools/mesh_extractor/Stream.cpp create mode 100644 src/tools/mesh_extractor/Stream.h (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 79ece1213d4..3d3fbdd6365 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -8,7 +8,7 @@ ADT::ADT( std::string file, int x, int y ) : ObjectData(NULL), Data(NULL), HasOb { Data = new ChunkedData(file); ObjectData = new ChunkedData(file); - if (ObjectData->Stream) + if (ObjectData->_Stream) HasObjectData = true; else ObjectData = NULL; diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 9ed8472051d..f5dbb0fd7ff 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -47,4 +47,4 @@ if( UNIX ) install(TARGETS MeshExtractor DESTINATION bin) elseif( WIN32 ) install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() +endif() \ No newline at end of file diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index 4605ae0f0dd..a89bb5cadce 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -8,24 +8,24 @@ int32 Chunk::FindSubChunkOffset(std::string name) if (name.size() != 4) return -1; - FILE* stream = GetStream(); + Stream* stream = GetStream(); uint32 matched = 0; - while (uint32(ftell(stream)) < Utils::Size(stream)) + while (stream->GetPos() < stream->GetSize()) { - char b = 0; - if (fread(&b, sizeof(char), 1, stream) != 1 || b != name[matched]) + char b = stream->Read(); + if (b != name[matched]) matched = 0; else ++matched; if (matched == 4) - return ftell(stream) - 4; + return stream->GetPos() - 4; } return -1; } -FILE* Chunk::GetStream() +Stream* Chunk::GetStream() { - fseek(Stream, Offset, SEEK_SET); - return Stream; + _Stream->Seek(Offset, SEEK_SET); + return _Stream; } diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h index f3681a9f576..917a85531da 100644 --- a/src/tools/mesh_extractor/Chunk.h +++ b/src/tools/mesh_extractor/Chunk.h @@ -2,19 +2,21 @@ #define CHUNK_H #include "Define.h" #include +#include "Stream.h" + class ChunkedData; class Chunk { public: - Chunk(const char* name, uint32 length, uint32 offset, FILE* stream) : Name(name), Length(length), Offset(offset), Stream(stream) {} + Chunk(const char* name, uint32 length, uint32 offset, Stream* stream) : Name(name), Length(length), Offset(offset), _Stream(stream) {} int32 FindSubChunkOffset(std::string name); - FILE* GetStream(); + Stream* GetStream(); std::string Name; uint32 Length; uint32 Offset; - FILE* Stream; + Stream* _Stream; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index f273ef946dd..cec6dae7fbe 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -4,18 +4,18 @@ #include -ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : -Stream(stream) +ChunkedData::ChunkedData(Stream* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : +_Stream(stream) { - if (!Stream) + if (!_Stream) return; Load(maxLength, chunksHint); } ChunkedData::ChunkedData( const std::string& file, uint32 chunksHint /*= 300*/ ) { - Stream = MPQHandler->GetFile(file); - if (!Stream) + _Stream = MPQHandler->GetFile(file); + if (!_Stream) return; Load(0, chunksHint); } @@ -23,27 +23,26 @@ ChunkedData::ChunkedData( const std::string& file, uint32 chunksHint /*= 300*/ ) void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) { if (!maxLength) - maxLength = Utils::Size(Stream); + maxLength = _Stream->GetSize(); Chunks.reserve(chunksHint); - uint32 baseOffset = ftell(Stream); + uint32 baseOffset = _Stream->GetPos(); uint32 calcOffset = 0; - while ((calcOffset + baseOffset) < Utils::Size(Stream) && (calcOffset < maxLength)) + while ((calcOffset + baseOffset) < _Stream->GetSize() && (calcOffset < maxLength)) { char nameBytes[5]; - uint32 read = fread(&nameBytes, sizeof(char), 4, Stream); - nameBytes[read] = '\0'; + _Stream->Read(nameBytes, sizeof(char) * 4); + nameBytes[4] = '\0'; std::string name = std::string(nameBytes); - // Utils::Reverse(nameBytes); name = std::string(name.rbegin(), name.rend()); - uint32 length; - if (fread(&length, sizeof(uint32), 1, Stream) != 1) - continue; + + uint32 length = _Stream->Read(); calcOffset += 8; - Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); + + Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, _Stream)); calcOffset += length; // save an extra seek at the end - if ((calcOffset + baseOffset) < Utils::Size(Stream) && calcOffset < maxLength) - fseek(Stream, length, SEEK_CUR); + if ((calcOffset + baseOffset) < _Stream->GetSize() && calcOffset < maxLength) + _Stream->Seek(length, SEEK_CUR); } } @@ -69,6 +68,6 @@ ChunkedData::~ChunkedData() delete *itr; Chunks.clear(); - if (Stream) - fclose(Stream); + if (_Stream) + delete _Stream; } diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index 1e1cb17749e..1b47b54f272 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -3,11 +3,12 @@ #include #include "Chunk.h" +#include "Stream.h" class ChunkedData { public: - ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); + ChunkedData(Stream* stream, uint32 maxLength, uint32 chunksHint = 300); ChunkedData(const std::string &file, uint32 chunksHint = 300); ~ChunkedData(); @@ -16,6 +17,6 @@ public: void Load(uint32 maxLength, uint32 chunksHint); std::vector Chunks; - FILE* Stream; + Stream* _Stream; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 281a11d10dc..52e4d8c3760 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -2,19 +2,15 @@ #include "DBC.h" #include "Define.h" -DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) +DBC::DBC(Stream* stream) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { - char magic[5]; - uint32 count = 0; - count += fread(&magic, sizeof(char), 4, stream); - magic[4] = '\0'; - count += fread(&RecordCount, sizeof(uint32), 1, stream); + stream->Read(4); // Read the magic "WDBC" + + RecordCount = stream->Read(); Records.reserve(RecordCount); - count += fread(&Fields, sizeof(uint32), 1, stream); - count += fread(&RecordSize, sizeof(uint32), 1, stream); - count += fread(&StringBlockSize, sizeof(uint32), 1, stream); - if (count != 8) - printf("DBC::DBC: Failed to read some data expected 8, read %u\n", count); + Fields = stream->Read(); + RecordSize = stream->Read(); + StringBlockSize = stream->Read(); for (int i = 0; i < RecordCount; i++) { @@ -28,17 +24,18 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) IsFaulty = true; break; } - uint32 tmp; - if (fread(&tmp, sizeof(uint32), 1, stream) != 1) - printf("DBC::DBC: Failed to read some data expected 1, read 0\n"); - rec->Values.push_back(tmp); + rec->Values.push_back(stream->Read()); size += 4; } } - StringBlock = new uint8[StringBlockSize]; - count = fread(StringBlock, sizeof(uint8), StringBlockSize, stream); - if (count != StringBlockSize) - printf("DBC::DBC: Failed to read some data expected %u, read %u\n", StringBlockSize, count); + StringBlock = (uint8*)stream->Read(StringBlockSize); +} + +DBC::~DBC() +{ + delete[] StringBlock; + for (std::vector::iterator itr = Records.begin(); itr != Records.end(); ++itr) + delete *itr; } std::string DBC::GetStringByOffset( int offset ) @@ -56,7 +53,7 @@ std::string DBC::GetStringByOffset( int offset ) strcpy(d, (const char*)(StringBlock + offset)); d[len] = '\0'; std::string val = std::string(d); - delete [] d; + delete[] d; return val; } diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 5ed57754e73..339e896949d 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -3,13 +3,15 @@ #include #include #include "Define.h" +#include "Stream.h" class Record; class DBC { public: - DBC(FILE* stream); + DBC(Stream* stream); + ~DBC(); std::string GetStringByOffset(int offset); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 72c051500e1..4619f418e55 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -17,20 +17,18 @@ DoodadHandler::DoodadHandler( ADT* adt ) : ReadDoodadPaths(mmid, mmdx); } -void DoodadHandler::ProcessInternal( MapChunk* mcnk ) +void DoodadHandler::ProcessInternal(MapChunk* mcnk) { if (!IsSane()) return; uint32 refCount = mcnk->Header.DoodadRefs; - FILE* stream = mcnk->Source->GetStream(); - fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); + Stream* stream = mcnk->Source->GetStream(); + stream->Seek(mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); + for (uint32 i = 0; i < refCount; i++) { - int32 index; - int32 count; - if ((count = fread(&index, sizeof(int32), 1, stream)) != 1) - printf("DoodadHandler::ProcessInternal: Failed to read some data expected 1, read %d\n", count); + int32 index = stream->Read(); if (index < 0 || uint32(index) >= _definitions->size()) continue; DoodadDefinition doodad = (*_definitions)[index]; @@ -56,7 +54,7 @@ void DoodadHandler::ProcessInternal( MapChunk* mcnk ) InsertModelGeometry(doodad, model); } // Restore the stream position - fseek(stream, mcnk->Source->Offset, SEEK_SET); + stream->Seek(mcnk->Source->Offset, SEEK_SET); } void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) @@ -64,7 +62,7 @@ void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) int32 count = chunk->Length / 36; _definitions = new std::vector; _definitions->reserve(count); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); for (int i = 0; i < count; i++) { DoodadDefinition def; @@ -80,14 +78,13 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) _paths->reserve(paths); for (int i = 0; i < paths; i++) { - FILE* idStream = id->GetStream(); - fseek(idStream, i * 4, SEEK_CUR); - uint32 offset; - if (fread(&offset, sizeof(uint32), 1, idStream) != 1) - printf("DoodadHandler::ReadDoodadPaths: Failed to read some data expected 1, read 0\n"); - FILE* dataStream = data->GetStream(); - fseek(dataStream, offset + data->Offset, SEEK_SET); - _paths->push_back(Utils::ReadString(dataStream)); + Stream* idStream = id->GetStream(); + idStream->Seek(i * 4, SEEK_CUR); + uint32 offset = idStream->Read(); + + Stream* dataStream = data->GetStream(); + dataStream->Seek(offset + data->Offset, SEEK_SET); + _paths->push_back(dataStream->ReadString()); } } diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 51377f32d01..fcf8c2ede28 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -4,6 +4,7 @@ #include "Utils.h" #include "Chunk.h" #include "Model.h" +#include "Stream.h" #include #include @@ -22,18 +23,14 @@ public: return Vector3(vec.z, vec.x, vec.y); } - void Read(FILE* stream) + void Read(Stream* stream) { - int count = 0; - - count += fread(&MmidIndex, sizeof(uint32), 1, stream); - count += fread(&UniqueId, sizeof(uint32), 1, stream); - Position = (Vector3::Read(stream)); + MmidIndex = stream->Read(); + UniqueId = stream->Read(); + Position = Vector3::Read(stream); Rotation = Vector3::Read(stream); - count += fread(&DecimalScale, sizeof(uint16), 1, stream); - count += fread(&Flags, sizeof(uint16), 1, stream); - if (count != 4) - printf("DoodadDefinition::Read: Failed to read some data expected 4, read %d\n", count); + DecimalScale = stream->Read(); + Flags = stream->Read(); } }; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 33a661a9adf..6317748ea23 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -15,7 +15,7 @@ void LiquidHandler::HandleNewLiquid() Vertices.reserve(1000); Triangles.reserve(1000); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); H2OHeader header[256]; MCNKData.reserve(256); for (int i = 0; i < 256; i++) @@ -30,7 +30,7 @@ void LiquidHandler::HandleNewLiquid() MCNKData.push_back(MCNKLiquidData(NULL, H2ORenderMask())); continue; } - fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); + stream->Seek(chunk->Offset + h.OffsetInformation, SEEK_SET); H2OInformation information = H2OInformation::Read(stream); float** heights = new float*[9]; @@ -43,24 +43,22 @@ void LiquidHandler::HandleNewLiquid() H2ORenderMask renderMask; if (information.LiquidType != 2) { - fseek(stream, chunk->Offset + h.OffsetRender, SEEK_SET); + stream->Seek(chunk->Offset + h.OffsetRender, SEEK_SET); renderMask = H2ORenderMask::Read(stream); if ((Utils::IsAllZero(renderMask.Mask, 8) || (information.Width == 8 && information.Height == 8)) && information.OffsetMask2) { - fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); + stream->Seek(chunk->Offset + information.OffsetMask2, SEEK_SET); uint32 size = ceil(information.Width * information.Height / 8.0f); - uint8* altMask = new uint8[size]; - if (fread(altMask, sizeof(uint8), size, stream) == size) - for (uint32 mi = 0; mi < size; mi++) - renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; + uint8* altMask = (uint8*)stream->Read(size); + for (uint32 mi = 0; mi < size; mi++) + renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; delete[] altMask; } - fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); + stream->Seek(chunk->Offset + information.OffsetHeightmap, SEEK_SET); for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) - if (fread(&heights[x][y], sizeof(float), 1, stream) != 1) - return; + heights[x][y] = stream->Read(); } else { diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index 896d7bc32ac..5e822a6835c 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -1,5 +1,6 @@ #include "MPQ.h" #include "MPQManager.h" +#include "Stream.h" #include #include @@ -108,15 +109,8 @@ void MPQFile::close() eof = true; } -FILE* MPQFile::GetFileStream() +Stream* MPQFile::GetFileStream() { - FILE* file = tmpfile(); - if (!file) - { - printf("Could not create temporary file. Please run as Administrator or root\n"); - exit(1); - } - fwrite(buffer, sizeof(char), size, file); - fseek(file, 0, SEEK_SET); - return file; + Stream* stream = new Stream(buffer, size); + return stream; } diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index 30e11741550..d548f16adc1 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -3,6 +3,7 @@ #include "libmpq/mpq.h" #include "Define.h" +#include "Stream.h" #include #include #include @@ -13,7 +14,7 @@ class MPQArchive { public: - mpq_archive_s *mpq_a; + mpq_archive_s* mpq_a; std::vector Files; @@ -53,8 +54,8 @@ class MPQFile { //MPQHANDLE handle; bool eof; - char *buffer; - libmpq__off_t pointer,size; + char* buffer; + libmpq__off_t pointer, size; // disable copying MPQFile(const MPQFile& /*f*/) {} @@ -64,7 +65,7 @@ public: MPQFile(const char* filename); // filenames are not case sensitive ~MPQFile() { close(); } size_t Read(void* dest, size_t bytes); - FILE* GetFileStream(); + Stream* GetFileStream(); size_t getSize() { return size; } size_t getPos() { return pointer; } char* getBuffer() { return buffer; } diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 950e284f92e..cd98a5e017b 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -2,6 +2,7 @@ #include "MPQ.h" #include "DBC.h" #include "Utils.h" +#include "Stream.h" #include char const* MPQManager::Files[] = { @@ -83,7 +84,7 @@ void MPQManager::InitializeDBC() printf("Using default locale: %s\n", Languages[BaseLocale]); } -FILE* MPQManager::GetFile(const std::string& path ) +Stream* MPQManager::GetFile(const std::string& path ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); MPQFile file(path.c_str()); @@ -98,11 +99,11 @@ DBC* MPQManager::GetDBC(const std::string& name ) return new DBC(GetFile(path)); } -FILE* MPQManager::GetFileFromLocale( const std::string& path, uint32 locale ) +Stream* MPQManager::GetFileFromLocale( const std::string& path, uint32 locale ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); std::deque files = LocaleFiles[locale]; - FILE* ret = NULL; + Stream* ret = NULL; for (std::deque::iterator itr = files.begin(); itr != files.end(); ++itr) { mpq_archive* mpq_a = (*itr)->mpq_a; @@ -123,22 +124,15 @@ FILE* MPQManager::GetFileFromLocale( const std::string& path, uint32 locale ) //libmpq_file_getdata libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - // Pack the return into a FILE stream - ret = tmpfile(); - if (!ret) - { - printf("Could not create temporary file. Please run as Administrator or root\n"); - exit(1); - } - fwrite(buffer, sizeof(uint8), size, ret); - fseek(ret, 0, SEEK_SET); + ret = new Stream(buffer, size); + delete[] buffer; break; } return ret; } -FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) +Stream* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); mpq_archive* mpq_a = file->mpq_a; @@ -161,14 +155,7 @@ FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); // Pack the return into a FILE stream - FILE* ret = tmpfile(); - if (!ret) - { - printf("Could not create temporary file. Please run as Administrator or root\n"); - exit(1); - } - fwrite(buffer, sizeof(uint8), size, ret); - fseek(ret, 0, SEEK_SET); + Stream* ret = new Stream((char*)buffer, size); delete[] buffer; return ret; } diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 3514674b9bf..3fd27b6bffd 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -2,6 +2,7 @@ #define MPQ_MANAGER_H #include "MPQ.h" +#include "Stream.h" #include #include #include @@ -14,9 +15,9 @@ public: ~MPQManager() {} void Initialize(); - FILE* GetFile(const std::string& path); - FILE* GetFileFrom(const std::string& path, MPQArchive* file); - FILE* GetFileFromLocale(const std::string& path, uint32 locale); + Stream* GetFile(const std::string& path); + Stream* GetFileFrom(const std::string& path, MPQArchive* file); + Stream* GetFileFromLocale(const std::string& path, uint32 locale); DBC* GetDBC(const std::string& name); std::vector GetAllFiles(std::string extension); diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 789166d5c9b..ffed64b13af 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -4,9 +4,9 @@ MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) { - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); Header.Read(stream); - fseek(stream, chunk->Offset, SEEK_SET); + stream->Seek(chunk->Offset, SEEK_SET); Index = Header.IndexX + Header.IndexY * 16; GenerateVertices(stream); } @@ -47,9 +47,9 @@ void MapChunk::GenerateTriangles() } } -void MapChunk::GenerateVertices( FILE* stream ) +void MapChunk::GenerateVertices(Stream* stream) { - fseek(stream, Header.OffsetMCVT, SEEK_CUR); + stream->Seek(Header.OffsetMCVT, SEEK_CUR); Vertices.reserve(125); for (int j = 0; j < 17; j++) @@ -57,9 +57,7 @@ void MapChunk::GenerateVertices( FILE* stream ) int values = j % 2 ? 8 : 9; for (int i = 0; i < values; i++) { - float tmp; - if (fread(&tmp, sizeof(float), 1, stream) != 1) - printf("MapChunk::GenerateVertices: Failed to read some data expected 1, read 0\n"); + float tmp = stream->Read(); Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); if (values == 8) vert.y -= Constants::UnitSize * 0.5f; @@ -67,7 +65,7 @@ void MapChunk::GenerateVertices( FILE* stream ) } } // Restore stream position. - fseek(stream, Source->Offset, SEEK_SET); + stream->Seek(Source->Offset, SEEK_SET); } bool MapChunk::HasHole( uint32 map, int x, int y ) diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index e7d835ae0e3..a317c3a371b 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -12,7 +12,7 @@ public: MapChunk(ADT* _adt, Chunk* chunk); void GenerateTriangles(); - void GenerateVertices(FILE* stream); + void GenerateVertices(Stream* stream); static bool HasHole(uint32 map, int x, int y); ADT* Adt; Chunk* Source; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 1ed09e5d9dc..22afa763099 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -352,7 +352,6 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) int main(int argc, char* argv[]) { - _setmaxstdio(2048); uint32 threads = 4, extractFlags = 0; std::set mapIds; diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index 5fb521d5a36..0b21ad1027d 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -2,15 +2,15 @@ #include "MPQManager.h" #include "Utils.h" -Model::Model( std::string path ) : IsCollidable(false), IsBad(false) +Model::Model(std::string path) : IsCollidable(false), IsBad(false) { - Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); - if (!Stream) + _Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + if (!_Stream) { IsBad = true; return; } - Header.Read(Stream); + Header.Read(_Stream); if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) { @@ -23,17 +23,17 @@ Model::Model( std::string path ) : IsCollidable(false), IsBad(false) Model::~Model() { - if (Stream) - fclose(Stream); + if (_Stream) + delete _Stream; } void Model::ReadVertices() { - fseek(Stream, Header.OffsetBoundingVertices, SEEK_SET); + _Stream->Seek(Header.OffsetBoundingVertices, SEEK_SET); Vertices.reserve(Header.CountBoundingVertices); for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) { - Vertices.push_back(Vector3::Read(Stream)); + Vertices.push_back(Vector3::Read(_Stream)); if (Constants::ToWoWCoords) Vertices[i] = Utils::ToWoWCoords(Vertices[i]); } @@ -41,27 +41,24 @@ void Model::ReadVertices() void Model::ReadBoundingTriangles() { - fseek(Stream, Header.OffsetBoundingTriangles, SEEK_SET); + _Stream->Seek(Header.OffsetBoundingTriangles, SEEK_SET); Triangles.reserve(Header.CountBoundingTriangles / 3); for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; - int count = 0; - count += fread(&tri.V0, sizeof(uint16), 1, Stream); - count += fread(&tri.V1, sizeof(uint16), 1, Stream); - count += fread(&tri.V2, sizeof(uint16), 1, Stream); - if (count != 3) - printf("Model::ReadBoundingTriangles: Error reading data, expected 3, read %d\n", count); + tri.V0 = _Stream->Read(); + tri.V1 = _Stream->Read(); + tri.V2 = _Stream->Read(); Triangles.push_back(tri); } } void Model::ReadBoundingNormals() { - fseek(Stream, Header.OffsetBoundingNormals, SEEK_SET); + _Stream->Seek(Header.OffsetBoundingNormals, SEEK_SET); Normals.reserve(Header.CountBoundingNormals); for (uint32 i = 0; i < Header.CountBoundingNormals; i++) - Normals.push_back(Vector3::Read(Stream)); + Normals.push_back(Vector3::Read(_Stream)); } diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h index ed8627dad6f..fcbdd81145c 100644 --- a/src/tools/mesh_extractor/Model.h +++ b/src/tools/mesh_extractor/Model.h @@ -2,6 +2,7 @@ #define MODEL_H #include #include "Utils.h" +#include "Stream.h" class Model { @@ -17,7 +18,7 @@ public: std::vector Normals; std::vector > Triangles; bool IsCollidable; - FILE* Stream; + Stream* _Stream; bool IsBad; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Stream.cpp b/src/tools/mesh_extractor/Stream.cpp new file mode 100644 index 00000000000..f775d97d114 --- /dev/null +++ b/src/tools/mesh_extractor/Stream.cpp @@ -0,0 +1,47 @@ +#include "Stream.h" +#include + +Stream::Stream(char* buffer, uint32 size) : _size(size), _position(0) +{ + _buffer = new char[size]; + memcpy(_buffer, buffer, size); // Initialize the buffer +} + +Stream::~Stream() +{ + delete[] _buffer; +} + +char* Stream::Read(uint32 size) +{ + char* buff = new char[size]; + memcpy(buff, &_buffer[_position], size); + _position += size; + return buff; +} + +void Stream::Seek(uint32 position, uint32 type) +{ + switch (type) + { + case SEEK_SET: + _position = position; + break; + case SEEK_CUR: + _position += position; + break; + } +} + +std::string Stream::ReadString() +{ + std::string str; + while (true) + { + char b = Read(); + if (b == 0) + break; + str.push_back(b); + } + return str; +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/Stream.h b/src/tools/mesh_extractor/Stream.h new file mode 100644 index 00000000000..76d9511bbc4 --- /dev/null +++ b/src/tools/mesh_extractor/Stream.h @@ -0,0 +1,53 @@ +#ifndef STREAM_H +#define STREAM_H + +#include "Define.h" +#include + +class Stream +{ +public: + Stream(char* buffer, uint32 size); + ~Stream(); + + template + T Read() + { + T ret = *((T*)(&_buffer[_position])); + _position += sizeof(T); + return ret; + } + + template + void Read(T* dest, uint32 size) + { + memcpy(dest, &_buffer[_position], size); + _position += size; + } + + char* Read(uint32 size); + std::string ReadString(); + + void Reset() + { + _position = 0; + } + + void Seek(uint32 position, uint32 type); + + uint32 GetSize() + { + return _size; + } + + uint32 GetPos() + { + return _position; + } + +private: + char* _buffer; + uint32 _size; + uint32 _position; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index cdc3131b3db..5d82fb17e25 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -228,7 +228,7 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty), tx, ty); // If this condition is met, it means that this WDT does not contain the ADT - if (!_adt->Data->Stream) + if (!_adt->Data->_Stream) { delete _adt; continue; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 24cfb5cd1db..834303d164f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -1,6 +1,7 @@ #include "Utils.h" #include "WorldModelHandler.h" #include "Constants.h" +#include "Stream.h" #include #include "G3D/Matrix4.h" #include "G3D/Quat.h" @@ -47,31 +48,6 @@ void Utils::Reverse(char word[]) } } -std::string Utils::ReadString( FILE* file ) -{ - std::string ret; - while (true) - { - char b; - if (fread(&b, sizeof(char), 1, file) != 1 || b == 0) - break; - ret.push_back(b); - } - return ret; -} - -uint32 Utils::Size( FILE* file ) -{ - // store the old position - uint32 offset = ftell(file); - // Get file size - fseek(file, 0, SEEK_END); - uint32 size = ftell(file); - // reset back to the old position - fseek(file, offset, SEEK_SET); - return size; -} - Vector3 Utils::ToRecast(const Vector3& val ) { return Vector3(-val.y, val.z, -val.x); @@ -136,12 +112,9 @@ std::string Utils::GetPathBase(const std::string& path ) return path; } -Vector3 Vector3::Read( FILE* file ) +Vector3 Vector3::Read(Stream* file) { - Vector3 ret; - if (fread(&ret, sizeof(Vector3), 1, file) != 1) - printf("Vector3::Read: Failed to read some data expected 1, read 0\n"); - return ret; + return file->Read(); } Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int x, int y, bool translate) @@ -167,41 +140,36 @@ std::string Utils::Replace( std::string str, const std::string& oldStr, const st return str; } -void Utils::SaveToDisk( FILE* stream, const std::string& path ) +void Utils::SaveToDisk(Stream* stream, const std::string& path) { FILE* disk = fopen(path.c_str(), "wb"); if (!disk) { printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); - fclose(stream); + delete stream; return; } - uint32 size = Utils::Size(stream); - uint8* data = new uint8[size]; - // Read the data to an array - size_t read = fread(data, size, 1, stream); - if (read != 1) - { - printf("SaveToDisk: Error reading from Stream while trying to save file %s to disk.\n", path.c_str()); - fclose(disk); - fclose(stream); - return; - } + uint32 size = stream->GetSize(); + stream->Reset(); // Reset the stream just in case + // Read the data to an array + char* data = stream->Read(size); + // And write it in the file size_t wrote = fwrite(data, size, 1, disk); if (wrote != 1) { printf("SaveToDisk: Error writing to the file while trying to save %s to disk.\n", path.c_str()); - fclose(stream); + delete[] data; + delete stream; fclose(disk); return; } // Close the filestream fclose(disk); - fclose(stream); + delete stream; // Free the used memory delete[] data; @@ -222,206 +190,172 @@ std::string Utils::GetExtension( std::string path ) return extension; } -void MapChunkHeader::Read(FILE* stream) -{ - int count = 0; - - count += fread(&Flags, sizeof(uint32), 1, stream); - count += fread(&IndexX, sizeof(uint32), 1, stream); - count += fread(&IndexY, sizeof(uint32), 1, stream); - count += fread(&Layers, sizeof(uint32), 1, stream); - count += fread(&DoodadRefs, sizeof(uint32), 1, stream); - count += fread(&OffsetMCVT, sizeof(uint32), 1, stream); - count += fread(&OffsetMCNR, sizeof(uint32), 1, stream); - count += fread(&OffsetMCLY, sizeof(uint32), 1, stream); - count += fread(&OffsetMCRF, sizeof(uint32), 1, stream); - count += fread(&OffsetMCAL, sizeof(uint32), 1, stream); - count += fread(&SizeMCAL, sizeof(uint32), 1, stream); - count += fread(&OffsetMCSH, sizeof(uint32), 1, stream); - count += fread(&SizeMCSH, sizeof(uint32), 1, stream); - count += fread(&AreaId, sizeof(uint32), 1, stream); - count += fread(&MapObjectRefs, sizeof(uint32), 1, stream); - count += fread(&Holes, sizeof(uint32), 1, stream); +void MapChunkHeader::Read(Stream* stream) +{ + Flags = stream->Read(); + IndexX = stream->Read(); + IndexY = stream->Read(); + Layers = stream->Read(); + DoodadRefs = stream->Read(); + OffsetMCVT = stream->Read(); + OffsetMCNR = stream->Read(); + OffsetMCLY = stream->Read(); + OffsetMCRF = stream->Read(); + OffsetMCAL = stream->Read(); + SizeMCAL = stream->Read(); + OffsetMCSH = stream->Read(); + SizeMCSH = stream->Read(); + AreaId = stream->Read(); + MapObjectRefs = stream->Read(); + Holes = stream->Read(); LowQualityTextureMap = new uint32[4]; - count += fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - count += fread(&PredTex, sizeof(uint32), 1, stream); - count += fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - count += fread(&OffsetMCSE, sizeof(uint32), 1, stream); - count += fread(&SoundEmitters, sizeof(uint32), 1, stream); - count += fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); + stream->Read(LowQualityTextureMap, sizeof(uint32) * 4); + PredTex = stream->Read(); + NumberEffectDoodad = stream->Read(); + OffsetMCSE = stream->Read(); + SoundEmitters = stream->Read(); + OffsetMCLQ = stream->Read(); + SizeMCLQ = stream->Read(); Position = Vector3::Read(stream); - count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); - - if (count != 27) - printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); + OffsetMCCV = stream->Read(); } -void MHDR::Read(FILE* stream) +void MHDR::Read(Stream* stream) { int count = 0; - count += fread(&Flags, sizeof(uint32), 1, stream); - count += fread(&OffsetMCIN, sizeof(uint32), 1, stream); - count += fread(&OffsetMTEX, sizeof(uint32), 1, stream); - count += fread(&OffsetMMDX, sizeof(uint32), 1, stream); - count += fread(&OffsetMMID, sizeof(uint32), 1, stream); - count += fread(&OffsetMWMO, sizeof(uint32), 1, stream); - count += fread(&OffsetMWID, sizeof(uint32), 1, stream); - count += fread(&OffsetMDDF, sizeof(uint32), 1, stream); - count += fread(&OffsetMODF, sizeof(uint32), 1, stream); - count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); - count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); - count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); - - if (count != 12) - printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); + Flags = stream->Read(); + OffsetMCIN = stream->Read(); + OffsetMTEX = stream->Read(); + OffsetMMDX = stream->Read(); + OffsetMMID = stream->Read(); + OffsetMWMO = stream->Read(); + OffsetMWID = stream->Read(); + OffsetMDDF = stream->Read(); + OffsetMODF = stream->Read(); + OffsetMFBO = stream->Read(); + OffsetMH2O = stream->Read(); + OffsetMTFX = stream->Read(); } -void ModelHeader::Read(FILE* stream) +void ModelHeader::Read(Stream* stream) { - int count = 0; - - count += fread(&Magic, sizeof(char), 4, stream); + stream->Read(Magic, 4); Magic[4] = '\0'; // null-terminate it. - count += fread(&Version, sizeof(uint32), 1, stream); - count += fread(&LengthModelName, sizeof(uint32), 1, stream); - count += fread(&OffsetName, sizeof(uint32), 1, stream); - count += fread(&ModelFlags, sizeof(uint32), 1, stream); - count += fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - count += fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - count += fread(&CountAnimations, sizeof(uint32), 1, stream); - count += fread(&OffsetAnimations, sizeof(uint32), 1, stream); - count += fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - count += fread(&CountBones, sizeof(uint32), 1, stream); - count += fread(&OffsetBones, sizeof(uint32), 1, stream); - count += fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - count += fread(&CountVertices, sizeof(uint32), 1, stream); - count += fread(&OffsetVertices, sizeof(uint32), 1, stream); - count += fread(&CountViews, sizeof(uint32), 1, stream); - count += fread(&CountColors, sizeof(uint32), 1, stream); - count += fread(&OffsetColors, sizeof(uint32), 1, stream); - count += fread(&CountTextures, sizeof(uint32), 1, stream); - count += fread(&OffsetTextures, sizeof(uint32), 1, stream); - count += fread(&CountTransparency, sizeof(uint32), 1, stream); - count += fread(&OffsetTransparency, sizeof(uint32), 1, stream); - count += fread(&CountUvAnimation, sizeof(uint32), 1, stream); - count += fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - count += fread(&CountTexReplace, sizeof(uint32), 1, stream); - count += fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - count += fread(&CountRenderFlags, sizeof(uint32), 1, stream); - count += fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - count += fread(&CountBoneLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - count += fread(&CountTexLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - count += fread(&CountTexUnits, sizeof(uint32), 1, stream); - count += fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - count += fread(&CountTransLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - count += fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + Version = stream->Read(); + LengthModelName = stream->Read(); + OffsetName = stream->Read(); + ModelFlags = stream->Read(); + CountGlobalSequences = stream->Read(); + OffsetGlobalSequences = stream->Read(); + CountAnimations = stream->Read(); + OffsetAnimations = stream->Read(); + CountAnimationLookup = stream->Read(); + OffsetAnimationLookup = stream->Read(); + CountBones = stream->Read(); + OffsetBones = stream->Read(); + CountKeyBoneLookup = stream->Read(); + OffsetKeyBoneLookup = stream->Read(); + CountVertices = stream->Read(); + OffsetVertices = stream->Read(); + CountViews = stream->Read(); + CountColors = stream->Read(); + OffsetColors = stream->Read(); + CountTextures = stream->Read(); + OffsetTextures = stream->Read(); + CountTransparency = stream->Read(); + OffsetTransparency = stream->Read(); + CountUvAnimation = stream->Read(); + OffsetUvAnimation = stream->Read(); + CountTexReplace = stream->Read(); + OffsetTexReplace = stream->Read(); + CountRenderFlags = stream->Read(); + OffsetRenderFlags = stream->Read(); + CountBoneLookup = stream->Read(); + OffsetBoneLookup = stream->Read(); + CountTexLookup = stream->Read(); + OffsetTexLookup = stream->Read(); + CountTexUnits = stream->Read(); + OffsetTexUnits = stream->Read(); + CountTransLookup = stream->Read(); + OffsetTransLookup = stream->Read(); + CountUvAnimLookup = stream->Read(); + OffsetUvAnimLookup = stream->Read(); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); - count += fread(&VertexRadius, sizeof(float), 1, stream); + VertexRadius = stream->Read(); BoundingBox[0] = Vector3::Read(stream); BoundingBox[1] = Vector3::Read(stream); - count += fread(&BoundingRadius, sizeof(float), 1, stream); - count += fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - count += fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - - if (count != 51) - printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); - + BoundingRadius = stream->Read(); + CountBoundingTriangles = stream->Read(); + OffsetBoundingTriangles = stream->Read(); + CountBoundingVertices = stream->Read(); + OffsetBoundingVertices = stream->Read(); + CountBoundingNormals = stream->Read(); + OffsetBoundingNormals = stream->Read(); } -WorldModelHeader WorldModelHeader::Read(FILE* stream) +WorldModelHeader WorldModelHeader::Read(Stream* stream) { WorldModelHeader ret; int count = 0; - - count += fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - count += fread(&ret.CountGroups, sizeof(uint32), 1, stream); - count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountLights, sizeof(uint32), 1, stream); - count += fread(&ret.CountModels, sizeof(uint32), 1, stream); - count += fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - count += fread(&ret.CountSets, sizeof(uint32), 1, stream); - count += fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - count += fread(&ret.WmoId, sizeof(uint32), 1, stream); + ret.CountMaterials = stream->Read(); + ret.CountGroups = stream->Read(); + ret.CountPortals = stream->Read(); + ret.CountLights = stream->Read(); + ret.CountModels = stream->Read(); + ret.CountDoodads = stream->Read(); + ret.CountSets = stream->Read(); + ret.AmbientColorUnk = stream->Read(); + ret.WmoId = stream->Read(); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - - if (count != 10) - printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); + ret.LiquidTypeRelated = stream->Read(); return ret; } -DoodadInstance DoodadInstance::Read(FILE* stream) +DoodadInstance DoodadInstance::Read(Stream* stream) { DoodadInstance ret; - int count = 0; - count += fread(&ret.FileOffset, sizeof(uint32), 1, stream); + ret.FileOffset = stream->Read(); ret.Position = Vector3::Read(stream); - count += fread(&ret.QuatW, sizeof(float), 1, stream); - count += fread(&ret.QuatX, sizeof(float), 1, stream); - count += fread(&ret.QuatY, sizeof(float), 1, stream); - count += fread(&ret.QuatZ, sizeof(float), 1, stream); - count += fread(&ret.Scale, sizeof(float), 1, stream); - count += fread(&ret.LightColor, sizeof(uint32), 1, stream); - - if (count != 7) - printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); - + ret.QuatW = stream->Read(); + ret.QuatX = stream->Read(); + ret.QuatY = stream->Read(); + ret.QuatZ = stream->Read(); + ret.Scale = stream->Read(); + ret.LightColor = stream->Read(); return ret; } -DoodadSet DoodadSet::Read(FILE* stream) +DoodadSet DoodadSet::Read(Stream* stream) { DoodadSet ret; - char name[21]; - int count = 0; - - count += fread(&name, sizeof(char), 20, stream); - name[20] = '\0'; - ret.Name = name; - count += fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - count += fread(&ret.CountInstances, sizeof(uint32), 1, stream); - count += fread(&ret.UnknownZero, sizeof(uint32), 1, stream); - - if (count != 23) - printf("DoodadSet::Read: Failed to read some data expected 23, read %d\n", count); + ret.Name = std::string(stream->Read(20), 20); + ret.FirstInstanceIndex = stream->Read(); + ret.CountInstances = stream->Read(); + ret.UnknownZero = stream->Read(); + return ret; } -LiquidHeader LiquidHeader::Read(FILE* stream) +LiquidHeader LiquidHeader::Read(Stream* stream) { LiquidHeader ret; - int count = 0; - count += fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - count += fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - count += fread(&ret.Width, sizeof(uint32), 1, stream); - count += fread(&ret.Height, sizeof(uint32), 1, stream); + ret.CountXVertices = stream->Read(); + ret.CountYVertices = stream->Read(); + ret.Width = stream->Read(); + ret.Height = stream->Read(); ret.BaseLocation = Vector3::Read(stream); - count += fread(&ret.MaterialId, sizeof(uint16), 1, stream); - - if (count != 5) - printf("LiquidHeader::Read: Failed to read some data expected 5, read %d\n", count); + ret.MaterialId = stream->Read(); return ret; } -LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) +LiquidData LiquidData::Read(Stream* stream, LiquidHeader& header) { LiquidData ret; ret.HeightMap = new float*[header.CountXVertices]; @@ -436,35 +370,22 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) { for (uint32 x = 0; x < header.CountXVertices; x++) { - uint32 discard; - float tmp; - if (fread(&discard, sizeof(uint32), 1, stream) == 1 && - fread(&tmp, sizeof(float), 1, stream) == 1) - { - ret.HeightMap[x][y] = tmp; - } + stream->Read(); // Dummy value + ret.HeightMap[x][y] = stream->Read(); } } for (uint32 y = 0; y < header.Height; y++) - { for (uint32 x = 0; x < header.Width; x++) - { - uint8 tmp = 0; - if (fread(&tmp, sizeof(uint8), 1, stream) == 1) - ret.RenderFlags[x][y] = tmp; - } - } + ret.RenderFlags[x][y] = stream->Read(); return ret; } -H2ORenderMask H2ORenderMask::Read(FILE* stream) +H2ORenderMask H2ORenderMask::Read(Stream* stream) { H2ORenderMask ret; - int32 count; - if ((count = fread(&ret.Mask, sizeof(uint8), 8, stream)) != 8) - printf("H2OHeader::Read: Failed to read some data expected 8, read %d\n", count); + stream->Read(ret.Mask, sizeof(uint8) * 8); return ret; } @@ -480,38 +401,31 @@ bool MCNKLiquidData::IsWater(int x, int y, float height) return false; } -H2OHeader H2OHeader::Read(FILE* stream) +H2OHeader H2OHeader::Read(Stream* stream) { H2OHeader ret; - int count = 0; - count += fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - count += fread(&ret.LayerCount, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetRender, sizeof(uint32), 1, stream); - - if (count != 3) - printf("H2OHeader::Read: Failed to read some data expected 3, read %d\n", count); - + + ret.OffsetInformation = stream->Read(); + ret.LayerCount = stream->Read(); + ret.OffsetRender = stream->Read(); + return ret; } -H2OInformation H2OInformation::Read(FILE* stream) +H2OInformation H2OInformation::Read(Stream* stream) { H2OInformation ret; - int count = 0; - count += fread(&ret.LiquidType, sizeof(uint16), 1, stream); - count += fread(&ret.Flags, sizeof(uint16), 1, stream); - count += fread(&ret.HeightLevel1, sizeof(float), 1, stream); - count += fread(&ret.HeightLevel2, sizeof(float), 1, stream); - count += fread(&ret.OffsetX, sizeof(uint8), 1, stream); - count += fread(&ret.OffsetY, sizeof(uint8), 1, stream); - count += fread(&ret.Width, sizeof(uint8), 1, stream); - count += fread(&ret.Height, sizeof(uint8), 1, stream); - count += fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); - - if (count != 10) - printf("H2OInformation::Read: Failed to read some data expected 10, read %d\n", count); - + ret.LiquidType = stream->Read(); + ret.Flags = stream->Read(); + ret.HeightLevel1 = stream->Read(); + ret.HeightLevel2 = stream->Read(); + ret.OffsetX = stream->Read(); + ret.OffsetY = stream->Read(); + ret.Width = stream->Read(); + ret.Height = stream->Read(); + ret.OffsetMask2 = stream->Read(); + ret.OffsetHeightmap = stream->Read(); + return ret; } @@ -524,24 +438,20 @@ char* Utils::GetPlainName(const char* FileName) return (char*)FileName; } -WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) +WMOGroupHeader WMOGroupHeader::Read(Stream* stream) { WMOGroupHeader ret; - int count = 0; - count += fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); - count += fread(&ret.Flags, sizeof(uint32), 1, stream); + ret.OffsetGroupName = stream->Read(); + ret.OffsetDescriptiveName = stream->Read(); + ret.Flags = stream->Read(); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - count += fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountBatches, sizeof(uint16), 4, stream); - count += fread(&ret.Fogs, sizeof(uint8), 4, stream); - count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - count += fread(&ret.WmoId, sizeof(uint32), 1, stream); - - if (count != 15) - printf("WMOGroupHeader::Read: Failed to read some data expected 15, read %d\n", count); - + ret.OffsetPortals = stream->Read(); + ret.CountPortals = stream->Read(); + stream->Read(ret.CountBatches, sizeof(uint16) * 4); + stream->Read(ret.Fogs, sizeof(uint8) * 4); + ret.LiquidTypeRelated = stream->Read(); + ret.WmoId = stream->Read(); + return ret; } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 472cf6dbd1b..617da2b2244 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -10,6 +10,8 @@ #include "Define.h" #include "Constants.h" +#include "Stream.h" + #include struct WorldModelDefinition; @@ -42,7 +44,7 @@ struct Vector3 return Vector3(x * s, y * s, z * s); } - static Vector3 Read(FILE* file); + static Vector3 Read(Stream* file); }; struct TilePos @@ -93,7 +95,7 @@ public: Vector3 Position; uint32 OffsetMCCV; - void Read(FILE* stream); + void Read(Stream* stream); }; class MHDR @@ -113,7 +115,7 @@ public: uint32 OffsetMH2O; uint32 OffsetMTFX; - void Read(FILE* stream); + void Read(Stream* stream); }; class ModelHeader @@ -170,7 +172,7 @@ public: uint32 CountBoundingNormals; uint32 OffsetBoundingNormals; - void Read(FILE* stream); + void Read(Stream* stream); }; class WorldModelHeader @@ -189,7 +191,7 @@ public: Vector3 BoundingBox[2]; uint32 LiquidTypeRelated; - static WorldModelHeader Read(FILE* stream); + static WorldModelHeader Read(Stream* stream); }; class DoodadInstance @@ -206,7 +208,7 @@ public: float Scale; uint32 LightColor; - static DoodadInstance Read(FILE* stream); + static DoodadInstance Read(Stream* stream); }; class DoodadSet @@ -218,7 +220,7 @@ public: uint32 CountInstances; uint32 UnknownZero; - static DoodadSet Read(FILE* stream); + static DoodadSet Read(Stream* stream); }; class LiquidHeader @@ -232,7 +234,7 @@ public: Vector3 BaseLocation; uint16 MaterialId; - static LiquidHeader Read(FILE* stream); + static LiquidHeader Read(Stream* stream); }; class LiquidData @@ -247,7 +249,7 @@ public: return RenderFlags[x][y] != 0x0F; } - static LiquidData Read(FILE* stream, LiquidHeader& header); + static LiquidData Read(Stream* stream, LiquidHeader& header); }; class H2ORenderMask @@ -261,7 +263,7 @@ public: return (Mask[y] >> x & 1) != 0; } - static H2ORenderMask Read(FILE* stream); + static H2ORenderMask Read(Stream* stream); }; class MCNKLiquidData @@ -284,7 +286,7 @@ public: uint32 LayerCount; uint32 OffsetRender; - static H2OHeader Read(FILE* stream); + static H2OHeader Read(Stream* stream); }; class H2OInformation @@ -302,7 +304,7 @@ public: uint32 OffsetMask2; uint32 OffsetHeightmap; - static H2OInformation Read(FILE* stream); + static H2OInformation Read(Stream* stream); }; class WMOGroupHeader @@ -321,7 +323,7 @@ public: uint32 LiquidTypeRelated; uint32 WmoId; - static WMOGroupHeader Read(FILE* stream); + static WMOGroupHeader Read(Stream* stream); }; // Dummy class to act as an interface. @@ -352,8 +354,6 @@ class Utils { public: static void Reverse(char word[]); - static std::string ReadString(FILE* file); - static uint32 Size(FILE* file); static Vector3 ToRecast(const Vector3& val ); static std::string GetAdtPath(const std::string& world, int x, int y); static std::string FixModelPath(const std::string& path); @@ -377,14 +377,14 @@ public: return false; return true; } - static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - static void CreateDir( const std::string& Path ); - static void SaveToDisk(FILE* stream, const std::string& path); - static Vector3 ToWoWCoords(const Vector3& vec ); - static std::string GetExtension( std::string path ); + static std::string Replace(std::string str, const std::string& oldStr, const std::string& newStr); + static void CreateDir(const std::string& Path); + static void SaveToDisk(Stream* stream, const std::string& path); + static Vector3 ToWoWCoords(const Vector3& vec); + static std::string GetExtension( std::string path); static char* GetPlainName(const char* FileName); static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true); - static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false ); - static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true ); + static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false); + static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true); }; #endif diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index 2a5a18c9848..4a1d9c45b58 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -20,7 +20,7 @@ void WDT::ReadGlobalModel() IsGlobalModel = true; ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); - ModelFile = Utils::ReadString(fileChunk->GetStream()); + ModelFile = fileChunk->GetStream()->ReadString(); Model = new WorldModelRoot(ModelFile); } @@ -30,20 +30,14 @@ void WDT::ReadTileTable() if (!chunk) return; IsValid = true; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { const uint32 hasTileFlag = 0x1; - uint32 flags; - uint32 discard; - int count = 0; - count += fread(&flags, sizeof(uint32), 1, stream); - count += fread(&discard, sizeof(uint32), 1, stream); - - if (count != 2) - printf("WDT::ReadTileTable: Failed to read some data expected 2, read %d\n", count); + uint32 flags = stream->Read(); + uint32 discard = stream->Read(); if (flags & hasTileFlag) TileTable.push_back(TilePos(x, y)); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index f76df73aaa6..08b315b9db3 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -3,10 +3,10 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) +WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) { Data = new ChunkedData(path); - if (!Data->Stream) + if (!Data->_Stream) { IsBad = true; return; @@ -18,8 +18,8 @@ WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupInde Name = Utils::GetPlainName(path.c_str()); - FILE* stream = mainChunk->GetStream(); - fseek(stream, firstSub, SEEK_SET); + Stream* stream = mainChunk->GetStream(); + stream->Seek(firstSub, SEEK_SET); SubData = new ChunkedData(stream, mainChunk->Length - firstSub); ReadHeader(); @@ -40,7 +40,7 @@ void WorldModelGroup::ReadNormals() uint32 normalCount = chunk->Length / 12; ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); Normals.reserve(normalCount); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); for (uint32 i = 0; i < normalCount; i++) Normals.push_back(Vector3::Read(stream)); } @@ -52,7 +52,7 @@ void WorldModelGroup::ReadLiquid() return; HasLiquidData = true; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); LiquidDataHeader = LiquidHeader::Read(stream); LiquidDataGeometry = LiquidData::Read(stream, LiquidDataHeader); } @@ -65,7 +65,7 @@ void WorldModelGroup::ReadVertices() uint32 verticeCount = chunk->Length / 12; Vertices.reserve(verticeCount); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); for (uint32 i = 0; i < verticeCount; i++) Vertices.push_back(Vector3::Read(stream)); } @@ -78,19 +78,13 @@ void WorldModelGroup::ReadTriangles() uint32 triangleCount = chunk->Length / 6; ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); Triangles.reserve(triangleCount); for (uint32 i = 0; i < triangleCount; i++) { - uint16 v0; - uint16 v1; - uint16 v2; - int count = 0; - count += fread(&v0, sizeof(uint16), 1, stream); - count += fread(&v1, sizeof(uint16), 1, stream); - count += fread(&v2, sizeof(uint16), 1, stream); - if (count != 3) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 3, read %d\n", count); + uint16 v0 = stream->Read(); + uint16 v1 = stream->Read(); + uint16 v2 = stream->Read(); Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); } @@ -102,20 +96,15 @@ void WorldModelGroup::ReadMaterials() if (!chunk) return; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); uint32 triangleCount = chunk->Length / 2; TriangleFlags.reserve(triangleCount); TriangleMaterials.reserve(triangleCount); for (uint32 i = 0; i < triangleCount; i++) { - uint8 tmp; - if (fread(&tmp, sizeof(uint8), 1, stream) != 1) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); - TriangleFlags.push_back(tmp); + TriangleFlags.push_back(stream->Read()); // Read again for material. - if (fread(&tmp, sizeof(uint8), 1, stream) != 1) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); - TriangleMaterials.push_back(tmp); + TriangleMaterials.push_back(stream->Read()); } } @@ -125,7 +114,7 @@ void WorldModelGroup::ReadHeader() if (!chunk) return; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); Header = WMOGroupHeader::Read(stream); } @@ -137,7 +126,5 @@ void WorldModelGroup::ReadBatches() MOBALength = chunk->Length / 2; MOBA = new uint16[MOBALength]; - uint32 count = (uint32)fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); - if (count != MOBALength) - printf("WorldModelGroup::ReadBatches: Error reading data, expected %u, read %u\n", MOBALength, count); + chunk->GetStream()->Read(MOBA, sizeof(uint16) * MOBALength); } diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 3565a1d6af0..d9f9cef2b96 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -4,27 +4,24 @@ #include "Cache.h" #include "Model.h" #include "Define.h" +#include "Stream.h" #include "G3D/Matrix4.h" #include "G3D/Quat.h" #include -WorldModelDefinition WorldModelDefinition::Read( FILE* file ) +WorldModelDefinition WorldModelDefinition::Read(Stream* file) { WorldModelDefinition ret; - int count = 0; - count += fread(&ret.MwidIndex, sizeof(uint32), 1, file); - count += fread(&ret.UniqueId, sizeof(uint32), 1, file); + ret.MwidIndex = file->Read(); + ret.UniqueId = file->Read(); ret.Position = Vector3::Read(file); ret.Rotation = Vector3::Read(file); ret.UpperExtents = Vector3::Read(file); ret.LowerExtents = Vector3::Read(file); - count += fread(&ret.Flags, sizeof(uint16), 1, file); - count += fread(&ret.DoodadSet, sizeof(uint16), 1, file); - uint32 discard; - count += fread(&discard, sizeof(uint32), 1, file); - - if (count != 5) - printf("WorldModelDefinition::Read: Error reading data, expected 5, read %d\n", count); + ret.Flags = file->Read(); + ret.DoodadSet = file->Read(); + file->Read(); // Discarded + return ret; } @@ -41,14 +38,12 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) return; uint32 refCount = mcnk->Header.MapObjectRefs; - FILE* stream = mcnk->Source->GetStream(); - fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); + Stream* stream = mcnk->Source->GetStream(); + stream->Seek(mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); // Start looping at the last Doodad Ref index for (uint32 i = mcnk->Header.DoodadRefs; i < refCount; i++) { - int32 index; - if (fread(&index, sizeof(int32), 1, stream) != 1) - printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); + int32 index = stream->Read(); if (index < 0 || uint32(index) >= _definitions->size()) continue; @@ -76,7 +71,7 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) InsertModelGeometry(Vertices, Triangles, wmo, model); } // Restore the stream position - fseek(stream, mcnk->Source->Offset, SEEK_SET); + stream->Seek(mcnk->Source->Offset, SEEK_SET); } void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate ) @@ -185,7 +180,7 @@ void WorldModelHandler::ReadDefinitions() uint32 definitionCount = chunk->Length / definitionSize; _definitions = new std::vector; _definitions->reserve(definitionCount); - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); for (uint32 i = 0; i < definitionCount; i++) _definitions->push_back(WorldModelDefinition::Read(stream)); } @@ -202,14 +197,13 @@ void WorldModelHandler::ReadModelPaths() _paths->reserve(paths); for (uint32 i = 0; i < paths; i++) { - FILE* stream = mwid->GetStream(); - fseek(stream, i * 4, SEEK_CUR); - uint32 offset; - if (fread(&offset, sizeof(uint32), 1, stream) != 1) - printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); - FILE* dataStream = mwmo->GetStream(); - fseek(dataStream, offset + mwmo->Offset, SEEK_SET); - _paths->push_back(Utils::ReadString(dataStream)); + Stream* stream = mwid->GetStream(); + stream->Seek(i * 4, SEEK_CUR); + uint32 offset = stream->Read(); + + Stream* dataStream = mwmo->GetStream(); + dataStream->Seek(offset + mwmo->Offset, SEEK_SET); + _paths->push_back(dataStream->ReadString()); } } diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 87a5ad62938..7924eb3f1a9 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -22,7 +22,7 @@ public: uint16 Flags; uint16 DoodadSet; - static WorldModelDefinition Read(FILE* file); + static WorldModelDefinition Read(Stream* file); }; class WorldModelHandler : public ObjectDataHandler diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index a00506f3b16..db909ad919c 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -37,7 +37,7 @@ void WorldModelRoot::ReadDoodadSets() if (!chunk) return; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); for (uint32 i = 0; i < Header.CountSets; i++) @@ -56,14 +56,14 @@ void WorldModelRoot::ReadDoodadInstances() DoodadInstances.reserve(countInstances); for (uint32 i = 0; i < countInstances; i++) { - FILE* stream = chunk->GetStream(); - fseek(stream, instanceSize * i, SEEK_CUR); + Stream* stream = chunk->GetStream(); + stream->Seek(instanceSize * i, SEEK_CUR); DoodadInstance instance = DoodadInstance::Read(stream); - FILE* nameStream = nameChunk->GetStream(); + Stream* nameStream = nameChunk->GetStream(); if (instance.FileOffset >= nameChunk->Length) continue; - fseek(nameStream, instance.FileOffset, SEEK_CUR); - instance.File = Utils::ReadString(nameStream); + nameStream->Seek(instance.FileOffset, SEEK_CUR); + instance.File = nameStream->ReadString(); DoodadInstances.push_back(instance); } } @@ -74,6 +74,6 @@ void WorldModelRoot::ReadHeader() if (!chunk) return; - FILE* stream = chunk->GetStream(); + Stream* stream = chunk->GetStream(); Header = WorldModelHeader::Read(stream); } -- cgit v1.2.3 From 58912635a7a24d53632da35bbae8c6d15e217b41 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 6 Oct 2013 13:47:22 -0500 Subject: Tools/MeshExtractor: Fixed a few errors under GCC and changed a bit how the GenericCache class works. --- src/tools/mesh_extractor/Cache.h | 16 ++++++++++------ src/tools/mesh_extractor/DoodadHandler.cpp | 5 ----- src/tools/mesh_extractor/Geometry.cpp | 4 ++-- src/tools/mesh_extractor/Utils.cpp | 2 +- src/tools/mesh_extractor/Utils.h | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 10 ---------- 6 files changed, 14 insertions(+), 25 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 9b3e046fe1e..6c84324d7fb 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -14,15 +14,14 @@ class GenericCache public: GenericCache() {} - static const uint32 FlushLimit = 300; // We can't get too close to filling up all the memory, and we have to be wary of the maximum number of open streams. + static const uint32 FlushLimit = 300; void Insert(K key, T* val) { ACE_GUARD(ACE_Thread_Mutex, g, mutex); - - if (_items.size() > FlushLimit) - Clear(); - _items[key] = val; + if (_items.find(key) != _items.end()) // Make sure that the object isn't in the cache already + delete _items[key]; // Delete the previous item + _items[key] = val; // Reassign it } T* Get(K key) @@ -31,7 +30,12 @@ public: typename std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; - return NULL; + else + { + T* t = new T(key); // Create the object + _items[key] = t; + return t; + } } void Clear() diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 4619f418e55..506f3192344 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -40,11 +40,6 @@ void DoodadHandler::ProcessInternal(MapChunk* mcnk) std::string path = (*_paths)[doodad.MmidIndex]; Model* model = Cache->ModelCache.Get(path); - if (!model) - { - model = new Model(path); - Cache->ModelCache.Insert(path, model); - } if (!model->IsCollidable) continue; diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index df828dcd573..49be7ef71e7 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -17,7 +17,7 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) max = new float[3]; for (int i = 0; i < 3; ++i) { - max[i] = std::numeric_limits::lowest(); + max[i] = -FLT_MAX; min[i] = std::numeric_limits::max(); } @@ -43,7 +43,7 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) void Geometry::CalculateMinMaxHeight( float& min, float& max ) { min = std::numeric_limits::max(); - max = std::numeric_limits::lowest(); + max = -FLT_MAX; for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) { diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 834303d164f..d533c37f9f7 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -63,7 +63,7 @@ std::string Utils::FixModelPath(const std::string& path ) return Utils::GetPathBase(path) + ".M2"; } -Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate) +Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool translate) { // Sources of information: /// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715 diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 617da2b2244..45cfc6cfd4b 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -383,7 +383,7 @@ public: static Vector3 ToWoWCoords(const Vector3& vec); static std::string GetExtension( std::string path); static char* GetPlainName(const char* FileName); - static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true); + static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool translate = true); static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false); static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true); }; diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index d9f9cef2b96..bf54609ca5b 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -59,11 +59,6 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) std::string path = (*_paths)[wmo.MwidIndex]; WorldModelRoot* model = Cache->WorldModelCache.Get(path); - if (!model) - { - model = new WorldModelRoot(path); - Cache->WorldModelCache.Insert(path, model); - } Vertices.reserve(1000); Triangles.reserve(1000); @@ -111,11 +106,6 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { Model* model = Cache->ModelCache.Get(instance->File); - if (!model) - { - model = new Model(instance->File); - Cache->ModelCache.Insert(instance->File, model); - } if (!model->IsCollidable) continue; -- cgit v1.2.3 From e7b93044fbb07a1a74fda3a977acbb5c01c98961 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 6 Oct 2013 21:30:20 +0200 Subject: Tools/MeshExtractor: Code cleanup and fix threading issue Remove GenericCache:Insert() as no longer needed. Mark BuilderThread as not free anymore as soon as they are assigned to a Tile. Fix signed/unsigned comparison mismatch. --- src/tools/mesh_extractor/Cache.h | 10 ---------- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 6c84324d7fb..5625b6f8926 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -14,16 +14,6 @@ class GenericCache public: GenericCache() {} - static const uint32 FlushLimit = 300; - - void Insert(K key, T* val) - { - ACE_GUARD(ACE_Thread_Mutex, g, mutex); - if (_items.find(key) != _items.end()) // Make sure that the object isn't in the cache already - delete _items[key]; // Delete the previous item - _items[key] = val; // Reassign it - } - T* Get(K key) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index c90a6e527f7..c85e4df8d0e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -24,11 +24,11 @@ public: Y = y; MapId = map; Continent = cont; + Free = false; } int svc() { - Free = false; printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 22afa763099..b55965cfc29 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -462,7 +462,7 @@ int main(int argc, char* argv[]) status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); std::vector FinalPath; FinalPath.reserve(resultHopCount); - for (uint32 i = 0; i < resultHopCount; ++i) + for (int i = 0; i < resultHopCount; ++i) { Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2])); FinalPath.push_back(finalV); -- cgit v1.2.3 From 7d6a47c128527b3ab5e7ebeae6e8c1d5e06f0c7a Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 6 Oct 2013 21:59:52 +0200 Subject: Tools/MeshExtractor: Fix memory cleanup Free memory created with new[] with delete[] . --- src/tools/mesh_extractor/TileBuilder.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5d82fb17e25..534a2e68601 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -334,11 +334,11 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) rcFreeHeightField(hf); rcFreeCompactHeightfield(chf); rcFreeContourSet(contours); - delete vertices; - delete triangles; - delete areas; - delete bmin; - delete bmax; + delete[] vertices; + delete[] triangles; + delete[] areas; + delete[] bmin; + delete[] bmax; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) { -- cgit v1.2.3 From e7f035fdd3aafd33383a162a8c634f3837358ffa Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 6 Oct 2013 15:29:42 -0500 Subject: Tools/MeshExtractor: Fixed a logic mistake. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index c85e4df8d0e..4cb0a676e79 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -72,7 +72,7 @@ void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, i rcCalcBounds(verts, vertCount, bmin, bmax); else { - bmin[1] = FLT_MIN; + bmin[1] = -FLT_MAX; bmax[1] = FLT_MAX; } @@ -185,12 +185,12 @@ void ContinentBuilder::Build() } } - Cache->Clear(); - // Free memory for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) { (*_th)->wait(); delete *_th; } + + Cache->Clear(); } -- cgit v1.2.3 From b1ed66b52dc63240d73e55cf43bc3e4c60e183ef Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 6 Oct 2013 21:22:38 -0500 Subject: Tools/MeshExtractor: Added some locks because concurrency. Race conditions were detected with a race condition detection tool. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 4cb0a676e79..5130f467403 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -8,9 +8,14 @@ #include "Recast.h" #include "DetourCommon.h" +#include +#include +#include + class BuilderThread : public ACE_Task_Base { private: + ACE_Thread_Mutex lock; int X, Y, MapId; std::string Continent; dtNavMeshParams Params; @@ -19,7 +24,8 @@ public: BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} void SetData(int x, int y, int map, const std::string& cont) - { + { + ACE_GUARD(ACE_Thread_Mutex, g, lock); X = x; Y = y; MapId = map; @@ -29,6 +35,7 @@ public: int svc() { + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, lock, 0); printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; @@ -62,7 +69,7 @@ public: return 0; } - bool Free; + ACE_Atomic_Op Free; }; void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) @@ -171,7 +178,7 @@ void ContinentBuilder::Build() { for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) { - if ((*_th)->Free) + if ((*_th)->Free.value()) { (*_th)->SetData(itr->X, itr->Y, MapId, Continent); (*_th)->activate(); -- cgit v1.2.3 From 6f63d430b089908c85446dbe9c2d0e2ab3acb591 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 8 Oct 2013 20:38:42 +0200 Subject: Tools/MeshExtractor: Fix uninitialized values Fix uninitialized struct padding bytes written to output files. These bytes are actually ignored when loading these files, so the main point of this fix is to shut up the Valgrind log. Valgrind log: Syscall param write(buf) points to uninitialised byte(s) at : ??? (syscall-template.S:81) by : _IO_file_write@@GLIBC_2.2.5 (fileops.c:1270) by : new_do_write (fileops.c:546) by : _IO_do_write@@GLIBC_2.2.5 (fileops.c:519) by : _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1341) by : fwrite (iofwrite.c:43) by BuilderThread::svc() (ContinentBuilder.cpp:56) by : ACE_Task_Base::svc_run(void*) (in /usr/lib/libACE-6.0.3.so) by : ACE_Thread_Adapter::invoke_i() (in /usr/lib/libACE-6.0.3.so) by : ACE_Thread_Adapter::invoke() (in /usr/lib/libACE-6.0.3.so) by : start_thread (pthread_create.c:311) by : clone (clone.S:113) Address 0x4039011 is not stack'd, malloc'd or (recently) free'd Uninitialised value was created by a stack allocation at: BuilderThread::svc() (ContinentBuilder.cpp:30) --- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 ++ src/tools/mesh_extractor/Utils.cpp | 10 ++++++++++ src/tools/mesh_extractor/Utils.h | 6 ++---- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 5130f467403..b4b29325171 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -58,6 +58,7 @@ public: return 0; } MmapTileHeader header; + Utils::InitializeMmapTileHeader(header); header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); fwrite(nav, sizeof(unsigned char), builder.DataSize, f); @@ -149,6 +150,7 @@ void ContinentBuilder::Build() } MmapTileHeader mheader; + Utils::InitializeMmapTileHeader(mheader); mheader.size = builder->DataSize; fwrite(&mheader, sizeof(MmapTileHeader), 1, f); fwrite(nav, sizeof(unsigned char), builder->DataSize, f); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index d533c37f9f7..255362d0e9c 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -455,3 +455,13 @@ WMOGroupHeader WMOGroupHeader::Read(Stream* stream) return ret; } + +void Utils::InitializeMmapTileHeader(MmapTileHeader& header) +{ + memset(&header, 0, sizeof(MmapTileHeader)); + header.mmapMagic = MMAP_MAGIC; + header.dtVersion = DT_NAVMESH_VERSION; + header.mmapVersion = MMAP_VERSION; + header.size = 0; + header.usesLiquids = true; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 45cfc6cfd4b..231aa181e01 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -344,10 +344,7 @@ struct MmapTileHeader uint32 dtVersion; uint32 mmapVersion; uint32 size; - bool usesLiquids; - - MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), - mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} + bool usesLiquids : 1; }; class Utils @@ -386,5 +383,6 @@ public: static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool translate = true); static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false); static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true); + static void InitializeMmapTileHeader(MmapTileHeader& header); }; #endif -- cgit v1.2.3 From 4ce12dc481323c11b4830d06f8080412d855cc64 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Thu, 17 Oct 2013 11:10:42 -0500 Subject: Tools/MeshExtractor: Don't load neighbor ADTs each time we generate an ADT. --- src/tools/mesh_extractor/TileBuilder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 534a2e68601..7e2f7fe3c47 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -217,7 +217,8 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) CalculateTileBounds(bmin, bmax, navMeshParams); _Geometry->CalculateMinMaxHeight(bmin[1], bmax[1]); - // again, we load everything - wasteful but who cares + // This is commented out to reduce the size of the resulting files (and the time it takes to generate them), we shouldn't need to load 4 more ADTs each time. + /*// again, we load everything - wasteful but who cares for (int ty = Y - 1; ty <= Y + 1; ty++) { for (int tx = X - 1; tx <= X + 1; tx++) @@ -237,7 +238,7 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) _Geometry->AddAdt(_adt); delete _adt; } - } + }*/ OutputDebugVertices(); -- cgit v1.2.3 From d30eecf4e4b7766b7f46b9ca3f0c6741b08d79af Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 15:47:23 -0500 Subject: Updated some code to use the STL --- src/tools/mesh_extractor/Utils.cpp | 10 ++-------- src/tools/mesh_extractor/Utils.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index c2a7577937a..0591c121895 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -54,15 +54,9 @@ void Utils::CreateDir( const std::string& Path ) #endif } -void Utils::Reverse(char word[]) +void Utils::Reverse(std::string& str) { - int len = strlen(word); - for (int i = 0;i < len / 2; i++) - { - word[i] ^= word[len-i-1]; - word[len-i-1] ^= word[i]; - word[i] ^= word[len-i-1]; - } + std::reverse(str.begin(), str.end()); } Vector3 Utils::ToRecast(const Vector3& val ) diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ad521852271..87b6a40582a 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -367,7 +367,7 @@ struct MmapTileHeader class Utils { public: - static void Reverse(char word[]); + static void Reverse(std::string& str); static Vector3 ToRecast(const Vector3& val ); static std::string GetAdtPath(const std::string& world, int x, int y); static std::string FixModelPath(const std::string& path); -- cgit v1.2.3 From 55936274e9cdf3d985588ecbae1c9845a1a9705e Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 18:19:33 -0500 Subject: Fixed a few memory leaks. --- src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 5 ++ src/tools/mesh_extractor/Utils.cpp | 75 ++++++++++++---------------- src/tools/mesh_extractor/Utils.h | 22 ++++++-- src/tools/mesh_extractor/WorldModelGroup.cpp | 4 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 6 files changed, 60 insertions(+), 50 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index eb3bed43fdb..1484864d7a3 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -21,7 +21,7 @@ DBC::DBC(Stream* stream) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { - stream->Read(4); // Read the magic "WDBC" + delete[] stream->Read(4); // Read the magic "WDBC" RecordCount = stream->Read(); Records.reserve(RecordCount); diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index ce9ea4fc84f..fa59d1bc7f0 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -113,5 +113,10 @@ void LiquidHandler::HandleNewLiquid() Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); } } + + // At this stage, heights is no longer needed, so we deallocate it + for (int j = 0; j < 9; ++j) + delete[] heights[j]; + delete[] heights; } } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 0591c121895..937de4b443a 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -219,7 +219,6 @@ void MapChunkHeader::Read(Stream* stream) AreaId = stream->Read(); MapObjectRefs = stream->Read(); Holes = stream->Read(); - LowQualityTextureMap = new uint32[4]; stream->Read(LowQualityTextureMap, sizeof(uint32) * 4); PredTex = stream->Read(); NumberEffectDoodad = stream->Read(); @@ -233,8 +232,6 @@ void MapChunkHeader::Read(Stream* stream) void MHDR::Read(Stream* stream) { - int count = 0; - Flags = stream->Read(); OffsetMCIN = stream->Read(); OffsetMTEX = stream->Read(); @@ -306,24 +303,20 @@ void ModelHeader::Read(Stream* stream) OffsetBoundingNormals = stream->Read(); } -WorldModelHeader WorldModelHeader::Read(Stream* stream) +void WorldModelHeader::Read(Stream* stream) { - WorldModelHeader ret; - int count = 0; - ret.CountMaterials = stream->Read(); - ret.CountGroups = stream->Read(); - ret.CountPortals = stream->Read(); - ret.CountLights = stream->Read(); - ret.CountModels = stream->Read(); - ret.CountDoodads = stream->Read(); - ret.CountSets = stream->Read(); - ret.AmbientColorUnk = stream->Read(); - ret.WmoId = stream->Read(); - ret.BoundingBox[0] = Vector3::Read(stream); - ret.BoundingBox[1] = Vector3::Read(stream); - ret.LiquidTypeRelated = stream->Read(); - - return ret; + CountMaterials = stream->Read(); + CountGroups = stream->Read(); + CountPortals = stream->Read(); + CountLights = stream->Read(); + CountModels = stream->Read(); + CountDoodads = stream->Read(); + CountSets = stream->Read(); + AmbientColorUnk = stream->Read(); + WmoId = stream->Read(); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); + LiquidTypeRelated = stream->Read(); } DoodadInstance DoodadInstance::Read(Stream* stream) @@ -344,8 +337,9 @@ DoodadInstance DoodadInstance::Read(Stream* stream) DoodadSet DoodadSet::Read(Stream* stream) { DoodadSet ret; - - ret.Name = std::string(stream->Read(20), 20); + char* name = stream->Read(20); + ret.Name = std::string(name, 20); + delete[] name; ret.FirstInstanceIndex = stream->Read(); ret.CountInstances = stream->Read(); ret.UnknownZero = stream->Read(); @@ -353,44 +347,41 @@ DoodadSet DoodadSet::Read(Stream* stream) return ret; } -LiquidHeader LiquidHeader::Read(Stream* stream) +void LiquidHeader::Read(Stream* stream) { - LiquidHeader ret; - ret.CountXVertices = stream->Read(); - ret.CountYVertices = stream->Read(); - ret.Width = stream->Read(); - ret.Height = stream->Read(); - ret.BaseLocation = Vector3::Read(stream); - ret.MaterialId = stream->Read(); - - return ret; + CountXVertices = stream->Read(); + CountYVertices = stream->Read(); + Width = stream->Read(); + Height = stream->Read(); + BaseLocation = Vector3::Read(stream); + MaterialId = stream->Read(); } -LiquidData LiquidData::Read(Stream* stream, LiquidHeader& header) +void LiquidData::Read(Stream* stream, LiquidHeader& header) { - LiquidData ret; - ret.HeightMap = new float*[header.CountXVertices]; + CountXVertices = header.CountXVertices; + Width = header.Width; + + HeightMap = new float*[header.CountXVertices]; for (uint32 i = 0; i < header.CountXVertices; ++i) - ret.HeightMap[i] = new float[header.CountYVertices]; + HeightMap[i] = new float[header.CountYVertices]; - ret.RenderFlags = new uint8*[header.Width]; + RenderFlags = new uint8*[header.Width]; for (uint32 i = 0; i < header.Width; ++i) - ret.RenderFlags[i] = new uint8[header.Height]; + RenderFlags[i] = new uint8[header.Height]; for (uint32 y = 0; y < header.CountYVertices; y++) { for (uint32 x = 0; x < header.CountXVertices; x++) { stream->Read(); // Dummy value - ret.HeightMap[x][y] = stream->Read(); + HeightMap[x][y] = stream->Read(); } } for (uint32 y = 0; y < header.Height; y++) for (uint32 x = 0; x < header.Width; x++) - ret.RenderFlags[x][y] = stream->Read(); - - return ret; + RenderFlags[x][y] = stream->Read(); } H2ORenderMask H2ORenderMask::Read(Stream* stream) diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 87b6a40582a..00f89f717c4 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -102,7 +102,7 @@ public: uint32 AreaId; uint32 MapObjectRefs; uint32 Holes; - uint32* LowQualityTextureMap; + uint32 LowQualityTextureMap[4]; uint32 PredTex; uint32 NumberEffectDoodad; uint32 OffsetMCSE; @@ -208,7 +208,7 @@ public: Vector3 BoundingBox[2]; uint32 LiquidTypeRelated; - static WorldModelHeader Read(Stream* stream); + void Read(Stream* stream); }; class DoodadInstance @@ -251,22 +251,36 @@ public: Vector3 BaseLocation; uint16 MaterialId; - static LiquidHeader Read(Stream* stream); + void Read(Stream* stream); }; class LiquidData { public: LiquidData() {} + + ~LiquidData() + { + for (uint32 i = 0; i < CountXVertices; ++i) + delete[] HeightMap[i]; + delete[] HeightMap; + + for (uint32 i = 0; i < Width; ++i) + delete[] RenderFlags[i]; + delete[] RenderFlags; + } + float** HeightMap; uint8** RenderFlags; + uint32 CountXVertices; + uint32 Width; bool ShouldRender(int x, int y) { return RenderFlags[x][y] != 0x0F; } - static LiquidData Read(Stream* stream, LiquidHeader& header); + void Read(Stream* stream, LiquidHeader& header); }; class H2ORenderMask diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 2e4d31086b2..2864edb23f2 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -70,8 +70,8 @@ void WorldModelGroup::ReadLiquid() HasLiquidData = true; Stream* stream = chunk->GetStream(); - LiquidDataHeader = LiquidHeader::Read(stream); - LiquidDataGeometry = LiquidData::Read(stream, LiquidDataHeader); + LiquidDataHeader.Read(stream); + LiquidDataGeometry.Read(stream, LiquidDataHeader); } void WorldModelGroup::ReadVertices() diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 360a8dfed59..32ff2923c75 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -92,5 +92,5 @@ void WorldModelRoot::ReadHeader() return; Stream* stream = chunk->GetStream(); - Header = WorldModelHeader::Read(stream); + Header.Read(stream); } -- cgit v1.2.3 From 1011376b951b97d15fed2855cfcfc069a6a4b9b1 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 18:48:18 -0500 Subject: Ignore the build on some test maps. --- src/tools/mesh_extractor/MeshExtractor.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index e0991d7942f..1f123a6452c 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -34,6 +34,28 @@ MPQManager* MPQHandler; CacheClass* Cache; +bool IgnoreMap(uint32 id) +{ + switch (id) + { + case 13: // test.wdt + case 25: // ScottTest.wdt + case 29: // Test.wdt + case 42: // Colin.wdt + case 169: // EmeraldDream.wdt (unused, and very large) + case 451: // development.wdt + case 573: // ExteriorTest.wdt + case 597: // CraigTest.wdt + case 605: // development_nonweighted.wdt + case 606: // QA_DVD.wdt + return true; + default: + break; + } + + return false; +} + void ExtractMMaps(std::set& mapIds, uint32 threads) { std::string basePath = "mmaps/"; @@ -45,8 +67,8 @@ void ExtractMMaps(std::set& mapIds, uint32 threads) { uint32 mapId = (*itr)->Values[0]; - // Skip this map if a list of specific maps was provided and this one is not contained in it. - if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) + // Skip this map if a list of specific maps was provided and this one is not contained in it, or if the map is in the ignore list. + if ((!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) || IgnoreMap(mapId)) { if (Constants::Debug) printf("Map %u will not be built.\n", mapId); -- cgit v1.2.3 From 5c5c14e0d4d85ee525baa7810fb0eab81d424c15 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 19:43:46 -0500 Subject: Move the WorldModelGroup when loading the WorldModelRoot groups to the Groups vector to prevent undefined behavior on destruction --- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 32ff2923c75..b5ee186afd0 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -44,7 +44,7 @@ void WorldModelRoot::ReadGroups() sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); WorldModelGroup group(name, i); if (!group.IsBad) - Groups.push_back(group); + Groups.push_back(std::move(group)); } } -- cgit v1.2.3 From 8cc77ff1fdc1f4ee788710383516d8794fb31a72 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 20:27:37 -0500 Subject: Don't delete the liquid height data in the destructor as it is called after ReadGroups ends, so the pointers are deleted but they are still referenced in the objects contained inside the Groups vector. --- src/tools/mesh_extractor/Utils.h | 4 ++-- src/tools/mesh_extractor/WDT.cpp | 3 ++- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 00f89f717c4..07a76282a45 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -261,13 +261,13 @@ public: ~LiquidData() { - for (uint32 i = 0; i < CountXVertices; ++i) + /*for (uint32 i = 0; i < CountXVertices; ++i) delete[] HeightMap[i]; delete[] HeightMap; for (uint32 i = 0; i < Width; ++i) delete[] RenderFlags[i]; - delete[] RenderFlags; + delete[] RenderFlags;*/ } float** HeightMap; diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index 3dfd45b666e..b22e9ff136b 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -20,6 +20,7 @@ #include "ChunkedData.h" #include "Utils.h" #include "WorldModelHandler.h" +#include "Cache.h" WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false), Model(NULL) { @@ -38,7 +39,7 @@ void WDT::ReadGlobalModel() IsGlobalModel = true; ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); ModelFile = fileChunk->GetStream()->ReadString(); - Model = new WorldModelRoot(ModelFile); + Model = Cache->WorldModelCache.Get(ModelFile); } void WDT::ReadTileTable() diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index b5ee186afd0..32ff2923c75 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -44,7 +44,7 @@ void WorldModelRoot::ReadGroups() sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); WorldModelGroup group(name, i); if (!group.IsBad) - Groups.push_back(std::move(group)); + Groups.push_back(group); } } -- cgit v1.2.3 From b89585e843e96b8edc6c8cccc53374fcb5cd1946 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 21:02:15 -0500 Subject: Tools/MeshExtractor: Added some stuff to make the switch to C++11 easier --- src/tools/mesh_extractor/WorldModelGroup.cpp | 18 ++++++++++++++++++ src/tools/mesh_extractor/WorldModelGroup.h | 4 ++++ src/tools/mesh_extractor/WorldModelRoot.cpp | 8 +++++--- 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 2864edb23f2..ae17a77fc38 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -28,6 +28,24 @@ WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : GroupIndex( IsBad = true; return; } + Load(path); +} + +WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) +{ + Data = new ChunkedData(stream, stream->GetSize()); + Load(path); +} + +WorldModelGroup::~WorldModelGroup() +{ + delete Data; + delete SubData; + delete[] MOBA; +} + +void WorldModelGroup::Load(std::string& path) +{ Chunk* mainChunk = Data->GetChunkByName("MOGP"); int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); if (firstSub == -1) diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h index b3c2c2bd940..20d453ee028 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.h +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -24,6 +24,10 @@ class WorldModelGroup { public: WorldModelGroup(std::string path, int groupIndex); + WorldModelGroup(Stream* stream, std::string path, int groupIndex); + ~WorldModelGroup(); + void Load(std::string& path); + ChunkedData* Data; ChunkedData* SubData; int GroupIndex; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 32ff2923c75..a288713c646 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -18,6 +18,7 @@ #include "WorldModelRoot.h" #include "ChunkedData.h" #include "Utils.h" +#include "MPQManager.h" WorldModelRoot::WorldModelRoot( std::string path ) { @@ -42,9 +43,10 @@ void WorldModelRoot::ReadGroups() { char name[200]; sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); - WorldModelGroup group(name, i); - if (!group.IsBad) - Groups.push_back(group); + Stream* stream = MPQHandler->GetFile(name); + if (!stream) + continue; + Groups.emplace_back(WorldModelGroup(stream, name, i)); // @ToDo: Use the real signature of emplace_back with variadic templates once we make the full switch to C++11 (At least Visual Studio 2012) } } -- cgit v1.2.3 From 473e4a7b7b72f5e316e0508d5232d4e96fa0168f Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 21:02:43 -0500 Subject: Tools/MeshExtractor: Missing changes from previous commit --- src/tools/mesh_extractor/WorldModelGroup.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index ae17a77fc38..9c577879867 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -39,9 +39,12 @@ WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupInde WorldModelGroup::~WorldModelGroup() { + /* + @ToDo: Uncomment this when emplace_back is properly used in void WorldModelRoot::ReadGroups() or replace with smart pointers delete Data; delete SubData; delete[] MOBA; + */ } void WorldModelGroup::Load(std::string& path) -- cgit v1.2.3 From 15d66d19b42759ccbb1900082c736a3953fcd3c9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 21:37:43 -0500 Subject: Tools/MeshExtractor: Fixed the threading, threads should no longer behave in a weird way. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 143 +++++++++----------------- src/tools/mesh_extractor/ContinentBuilder.h | 63 ++++++++++++ 2 files changed, 113 insertions(+), 93 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index e2c5616db31..8321a7924a1 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -16,80 +16,13 @@ */ #include "ContinentBuilder.h" -#include "TileBuilder.h" #include "WDT.h" #include "Utils.h" #include "DetourNavMesh.h" #include "Cache.h" -#include "ace/Task.h" #include "Recast.h" #include "DetourCommon.h" -#include -#include -#include - -class BuilderThread : public ACE_Task_Base -{ -private: - ACE_Thread_Mutex lock; - int X, Y, MapId; - std::string Continent; - dtNavMeshParams Params; - ContinentBuilder* cBuilder; -public: - BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} - - void SetData(int x, int y, int map, const std::string& cont) - { - ACE_GUARD(ACE_Thread_Mutex, g, lock); - X = x; - Y = y; - MapId = map; - Continent = cont; - Free = false; - } - - int svc() - { - ACE_GUARD_RETURN(ACE_Thread_Mutex, g, lock, 0); - printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(cBuilder, Continent, X, Y, MapId); - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); - FILE* f = fopen(buff, "r"); - if (f) // Check if file already exists. - { - printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); - fclose(f); - Free = true; - return 0; - } - uint8* nav = builder.BuildTiled(Params); - if (nav) - { - f = fopen(buff, "wb"); - if (!f) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return 0; - } - MmapTileHeader header; - Utils::InitializeMmapTileHeader(header); - header.size = builder.DataSize; - fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder.DataSize, f); - fclose(f); - } - dtFree(nav); - printf("[%02i,%02i] Tile Built!\n", X, Y); - Free = true; - return 0; - } - - ACE_Atomic_Op Free; -}; - void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) { // this is for elevation @@ -136,8 +69,6 @@ void ContinentBuilder::Build() dtNavMeshParams params; - std::vector Threads; - if (TileMap->IsGlobalModel) { printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId); @@ -187,36 +118,62 @@ void ContinentBuilder::Build() fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); - for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(this, params)); + std::vector _threads; + BuilderThreadPool* pool = NumberOfThreads > 0 ? new BuilderThreadPool() : NULL; + printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + pool->Enqueue(new TileBuildRequest(this, Continent, itr->X, itr->Y, MapId, params)); + + for (uint32 i = 0; i < NumberOfThreads; ++i) + _threads.push_back(new BuilderThread(this, pool->Queue())); + + // Free memory + for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) { - bool next = false; - while (!next) - { - for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) - { - if ((*_th)->Free.value()) - { - (*_th)->SetData(itr->X, itr->Y, MapId, Continent); - (*_th)->activate(); - next = true; - break; - } - } - // Wait for 20 seconds - ACE_OS::sleep(ACE_Time_Value (0, 20000)); - } + (*_th)->wait(); + delete *_th; } - } - // Free memory - for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) - { - (*_th)->wait(); - delete *_th; + delete pool; } Cache->Clear(); } + +int TileBuildRequest::call() +{ + printf("[%02i,%02i] Building tile\n", X, Y); + // Build the tile and return negative on error + TileBuilder tile(_builder, _continent, X, Y, _mapId); + char buff[100]; + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", _mapId, Y, X); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. + { + printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); + fclose(f); + return 0; + } + uint8* nav = tile.BuildTiled(_params); + if (nav) + { + f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + dtFree(nav); + return -1; + } + MmapTileHeader header; + Utils::InitializeMmapTileHeader(header); + header.size = tile.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(unsigned char), tile.DataSize, f); + fclose(f); + } + dtFree(nav); + printf("[%02i,%02i] Tile Built!\n", X, Y); + return 0; +} diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 5349b8e1ba5..ce1eef9b642 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -17,9 +17,15 @@ #ifndef CONT_BUILDER_H #define CONT_BUILDER_H + #include #include "WDT.h" #include "Define.h" +#include "TileBuilder.h" + +#include +#include +#include class ContinentBuilder { @@ -44,4 +50,61 @@ private: int tileXMax; int tileYMax; }; + +class TileBuildRequest : public ACE_Method_Request +{ +public: + TileBuildRequest(ContinentBuilder* builder, std::string& continent, uint32 x, uint32 y, uint32 mapId, dtNavMeshParams& params) : _builder(builder), _continent(continent), X(x), Y(y), _mapId(mapId), _params(params) { } + + virtual int call(); + +private: + uint32 _mapId; + ContinentBuilder* _builder; + std::string& _continent; + uint32 X; + uint32 Y; + dtNavMeshParams& _params; +}; + +class BuilderThreadPool +{ +public: + BuilderThreadPool() : _queue(new ACE_Activation_Queue()) {} + ~BuilderThreadPool() { _queue->queue()->close(); delete _queue; } + + void Enqueue(TileBuildRequest* request) + { + _queue->enqueue(request); + } + + ACE_Activation_Queue* Queue() { return _queue; } + +private: + ACE_Activation_Queue* _queue; +}; + +class BuilderThread : public ACE_Task_Base +{ +private: + ContinentBuilder* _builder; + ACE_Activation_Queue* _queue; +public: + BuilderThread(ContinentBuilder* builder, ACE_Activation_Queue* queue) : _builder(builder), _queue(queue) { activate(); } + + int svc() + { + /// @ Set a timeout for dequeue attempts (only used when the queue is empty) as it will never get populated after thread starts + ACE_Time_Value timeout(5); + ACE_Method_Request* request = NULL; + while ((request = _queue->dequeue(&timeout)) != NULL) + { + request->call(); + delete request; + request = NULL; + } + return 0; + } +}; + #endif -- cgit v1.2.3 From 0a693b1568bde79c0fc35ee0d4d91051f3bcbd99 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 22:59:23 -0500 Subject: Tools/MeshExtractor: Fixed a mistake in the WorldModelGroup constructor. --- src/tools/mesh_extractor/WorldModelGroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 9c577879867..283c51e24f6 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -31,7 +31,7 @@ WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : GroupIndex( Load(path); } -WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) +WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) { Data = new ChunkedData(stream, stream->GetSize()); Load(path); -- cgit v1.2.3 From 401527c351a7dee7768b70ca5e73bde52f9b2977 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 23:04:35 -0500 Subject: Tools: Only build the previous mmaps_generator when meshextractor isn't selected for building. --- src/tools/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 3adccf105de..f4a4aee92f6 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -11,7 +11,8 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) -add_subdirectory(mmaps_generator) if (WITH_MESHEXTRACTOR) add_subdirectory(mesh_extractor) +else() + add_subdirectory(mmaps_generator) endif() -- cgit v1.2.3 From ca118b10e9d854fa050a1a677954660fda0ff99d Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 29 Dec 2013 23:21:36 -0500 Subject: Tools/MeshExtractor: Fixed some delete miss-matches --- src/tools/mesh_extractor/TileBuilder.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index a3845c561a2..1a3a90f2168 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -183,11 +183,11 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) rcFreeHeightField(hf); rcFreeCompactHeightfield(chf); rcFreeContourSet(contours); - delete vertices; - delete triangles; - delete areas; - delete bmin; - delete bmax; + delete[] vertices; + delete[] triangles; + delete[] areas; + delete[] bmin; + delete[] bmax; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) { -- cgit v1.2.3 From 85218f443639eea8bc7c511c83cf4ca0c45f11af Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 31 Dec 2013 01:09:09 +0100 Subject: Tools/MeshExtractor: Fix warnings --- src/server/collision/Management/MMapManager.cpp | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index d3bfe17aaa4..c29d6fa4b56 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -222,7 +222,7 @@ namespace MMAP else { --_loadedTiles; - TC_LOG_INFO("maps", "MMAP::UnloadMap: Unloaded mmtile [%02u, %02u] from %03u", mapId, x, y, mapId); + TC_LOG_INFO("maps", "MMAP::UnloadMap: Unloaded mmtile [%02u, %02u] from %03u", x, y, mapId); } } diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 1f123a6452c..3b6efabd0c2 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -62,7 +62,7 @@ void ExtractMMaps(std::set& mapIds, uint32 threads) Utils::CreateDir(basePath); DBC* dbc = MPQHandler->GetDBC("Map"); - printf("Map.dbc contains %u rows.\n", dbc->Records.size()); + printf("Map.dbc contains " SIZEFMTD " rows.\n", dbc->Records.size()); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { uint32 mapId = (*itr)->Values[0]; -- cgit v1.2.3 From 91f93feff5c32c345fceabd6807fe44ea059c3f4 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 30 Dec 2013 22:55:53 -0500 Subject: Tools/MeshExtractor: Adjusted some config values and added some testing code. --- src/tools/mesh_extractor/MeshExtractor.cpp | 34 +++++++++++++++++++++--------- src/tools/mesh_extractor/TileBuilder.cpp | 8 +++---- 2 files changed, 28 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 3b6efabd0c2..f756bf087bd 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -422,8 +422,8 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_TEST) { - float start[] = { -1.37402868f, -21.7641087f, -20.1751060f }; - float end[] = { -22.756405f, -62.745014f, -21.371508f }; + float start[] = { -45.4745407f, -29.5000954f, -21.4456501f }; + float end[] = { -107.686218f, -32.3544769f, -30.3459435f }; // float m_spos[3]; @@ -489,24 +489,38 @@ int main(int argc, char* argv[]) return 0; } - int hops; - dtPolyRef* hopBuffer = new dtPolyRef[8192]; - dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192); + dtStatus status; + status = navMeshQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter); + while (status != DT_SUCCESS) + status = navMeshQuery->updateSlicedFindPath(1, 0); - int resultHopCount; - float* straightPath = new float[2048*3]; - unsigned char* pathFlags = new unsigned char[2048]; dtPolyRef* pathRefs = new dtPolyRef[2048]; + int pcount = 0; + int resultHopCount = 0; + float* straightPath = new float[2048 * 3]; + unsigned char* pathFlags = new unsigned char[2048]; + dtPolyRef* hopBuffer = new dtPolyRef[8192]; - status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); + navMeshQuery->finalizeSlicedFindPath(pathRefs, &pcount, 200); std::vector FinalPath; + + for (int i = 0; i < pcount; ++i) + { + navMeshQuery->findStraightPath(m_spos, m_epos, &pathRefs[i], 1, + straightPath, pathFlags, + hopBuffer, &resultHopCount, 200); + Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[0 * 3 + 0], straightPath[0 * 3 + 1], straightPath[0 * 3 + 2])); + FinalPath.push_back(finalV); + printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z); + } + /* FinalPath.reserve(resultHopCount); for (int i = 0; i < resultHopCount; ++i) { Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2])); FinalPath.push_back(finalV); printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z); - } + }*/ } return 0; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 1a3a90f2168..f9563485c8b 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -43,8 +43,8 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 2.1 / Config.ch; - Config.walkableRadius = 0.6f / Config.cs; + Config.walkableHeight = 2.1; + Config.walkableRadius = 0.6f; Config.maxEdgeLen = Config.walkableRadius * 8; Config.borderSize = Config.walkableRadius + 8; Config.tileSize = 1800; @@ -61,8 +61,8 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, InstanceConfig.detailSampleDist = 3.0f; InstanceConfig.detailSampleMaxError = 1.25f; InstanceConfig.walkableClimb = 1.0f / InstanceConfig.ch; - InstanceConfig.walkableHeight = 2.1f / InstanceConfig.ch; - InstanceConfig.walkableRadius = 0.6f / InstanceConfig.cs; + InstanceConfig.walkableHeight = 2.1f; + InstanceConfig.walkableRadius = 0.6f; InstanceConfig.maxEdgeLen = 8 * InstanceConfig.walkableRadius; InstanceConfig.maxVertsPerPoly = 6; InstanceConfig.maxSimplificationError = 1.3f; -- cgit v1.2.3 From bd57e06cafdb925ed6b07e3acad7e486f3286328 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 31 Dec 2013 15:08:37 +0100 Subject: Tools/MeshExtractor: Store WorldModelGroup references in WorldModelRoot --- src/tools/mesh_extractor/MeshExtractor.cpp | 3 ++- src/tools/mesh_extractor/WorldModelHandler.cpp | 6 ++++-- src/tools/mesh_extractor/WorldModelRoot.cpp | 7 ++++++- src/tools/mesh_extractor/WorldModelRoot.h | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index f756bf087bd..0e2ca46b399 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -253,8 +253,9 @@ void ExtractGameobjectModels() fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); const char grp[] = { 'G' , 'R' , 'P', ' ' }; - for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) + for (std::vector::iterator groupItr = model.Groups.begin(); groupItr != model.Groups.end(); ++groupItr) { + WorldModelGroup* itr2 = *groupItr; const WMOGroupHeader& header = itr2->Header; fwrite(&header.Flags, sizeof(uint32), 1, output); fwrite(&header.WmoId, sizeof(uint32), 1, output); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index e4238b1e321..2f4c1b6323c 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -88,8 +88,9 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate ) { - for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + for (std::vector::iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) { + WorldModelGroup* group = *groupItr; uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) { @@ -136,8 +137,9 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } - for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + for (std::vector::iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) { + WorldModelGroup* group = *groupItr; if (!group->HasLiquidData) continue; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index a288713c646..d80e5a1691a 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,6 +33,11 @@ WorldModelRoot::WorldModelRoot( std::string path ) WorldModelRoot::~WorldModelRoot() { delete Data; + /* @ToDo: uncomment this once the ~WorldModelGroup() doesn't cause a crash anymore + for (std::vector::iterator group = Groups.begin(); group != Groups.end(); ++group) + delete *group; + + Groups.clear();*/ } void WorldModelRoot::ReadGroups() @@ -46,7 +51,7 @@ void WorldModelRoot::ReadGroups() Stream* stream = MPQHandler->GetFile(name); if (!stream) continue; - Groups.emplace_back(WorldModelGroup(stream, name, i)); // @ToDo: Use the real signature of emplace_back with variadic templates once we make the full switch to C++11 (At least Visual Studio 2012) + Groups.push_back(new WorldModelGroup(stream, name, i)); } } diff --git a/src/tools/mesh_extractor/WorldModelRoot.h b/src/tools/mesh_extractor/WorldModelRoot.h index c2303ceafe4..7b1248246ca 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.h +++ b/src/tools/mesh_extractor/WorldModelRoot.h @@ -34,7 +34,7 @@ public: WorldModelHeader Header; std::vector DoodadInstances; std::vector DoodadSets; - std::vector Groups; + std::vector Groups; private: void ReadGroups(); void ReadDoodadSets(); -- cgit v1.2.3 From a7c77322eb1c195c6b4b0220406f10d5d2c7ed9c Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 31 Dec 2013 15:39:47 +0100 Subject: Tools/MeshExtractor: Fix uninitialized values causing crashes Fix uninitialized values causing crashes in the destructor. --- src/tools/mesh_extractor/ChunkedData.cpp | 3 ++- src/tools/mesh_extractor/Utils.h | 8 ++++---- src/tools/mesh_extractor/WorldModelGroup.cpp | 8 +++----- src/tools/mesh_extractor/WorldModelRoot.cpp | 3 +-- 4 files changed, 10 insertions(+), 12 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 00c528352aa..a3c3ec4b92c 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -85,6 +85,7 @@ ChunkedData::~ChunkedData() delete *itr; Chunks.clear(); + /* WorldModelGroup Data and SubData share the same _Stream so it's deleted twice and it crahes if (_Stream) - delete _Stream; + delete _Stream;*/ } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 07a76282a45..0f2df672250 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -243,7 +243,7 @@ public: class LiquidHeader { public: - LiquidHeader() {} + LiquidHeader() : CountXVertices(0), CountYVertices(0), Width(0), Height(0), BaseLocation(0,0,0), MaterialId(0) {} uint32 CountXVertices; uint32 CountYVertices; uint32 Width; @@ -257,17 +257,17 @@ public: class LiquidData { public: - LiquidData() {} + LiquidData() : HeightMap(NULL), RenderFlags(NULL), CountXVertices(0), Width(0) {} ~LiquidData() { - /*for (uint32 i = 0; i < CountXVertices; ++i) + for (uint32 i = 0; i < CountXVertices; ++i) delete[] HeightMap[i]; delete[] HeightMap; for (uint32 i = 0; i < Width; ++i) delete[] RenderFlags[i]; - delete[] RenderFlags;*/ + delete[] RenderFlags; } float** HeightMap; diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 283c51e24f6..454756f2baf 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -20,7 +20,7 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) +WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), IsBad(false), HasLiquidData(false) { Data = new ChunkedData(path); if (!Data->_Stream) @@ -31,7 +31,7 @@ WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : GroupIndex( Load(path); } -WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) +WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), IsBad(false), HasLiquidData(false) { Data = new ChunkedData(stream, stream->GetSize()); Load(path); @@ -39,12 +39,10 @@ WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupInde WorldModelGroup::~WorldModelGroup() { - /* - @ToDo: Uncomment this when emplace_back is properly used in void WorldModelRoot::ReadGroups() or replace with smart pointers delete Data; delete SubData; delete[] MOBA; - */ + } void WorldModelGroup::Load(std::string& path) diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index d80e5a1691a..cdeeec5ad26 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,11 +33,10 @@ WorldModelRoot::WorldModelRoot( std::string path ) WorldModelRoot::~WorldModelRoot() { delete Data; - /* @ToDo: uncomment this once the ~WorldModelGroup() doesn't cause a crash anymore for (std::vector::iterator group = Groups.begin(); group != Groups.end(); ++group) delete *group; - Groups.clear();*/ + Groups.clear(); } void WorldModelRoot::ReadGroups() -- cgit v1.2.3 From 7ccf9b948c1fa7cef9f90da72d1c96984a8a3998 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 31 Dec 2013 16:05:24 +0100 Subject: Tools/MeshExtractor: Fix warnings --- src/tools/mesh_extractor/ContinentBuilder.h | 2 +- src/tools/mesh_extractor/MPQManager.cpp | 1 - src/tools/mesh_extractor/ObjectDataHandler.h | 1 + src/tools/mesh_extractor/Stream.h | 6 ++++++ src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/Utils.cpp | 2 +- src/tools/mesh_extractor/WDT.cpp | 2 +- src/tools/mesh_extractor/WorldModelGroup.cpp | 4 ++-- 8 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index ce1eef9b642..8ecad9d9722 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -54,7 +54,7 @@ private: class TileBuildRequest : public ACE_Method_Request { public: - TileBuildRequest(ContinentBuilder* builder, std::string& continent, uint32 x, uint32 y, uint32 mapId, dtNavMeshParams& params) : _builder(builder), _continent(continent), X(x), Y(y), _mapId(mapId), _params(params) { } + TileBuildRequest(ContinentBuilder* builder, std::string& continent, uint32 x, uint32 y, uint32 mapId, dtNavMeshParams& params) : _mapId(mapId), _builder(builder), _continent(continent), X(x), Y(y), _params(params) { } virtual int call(); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 82e4a2b5bff..987e53eb340 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -56,7 +56,6 @@ void MPQManager::InitializeDBC() { BaseLocale = -1; uint32 size = sizeof(Languages) / sizeof(char*); - MPQArchive* _baseLocale = NULL; for (uint32 i = 0; i < size; ++i) { std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h index 3b18427db47..346241f9ae0 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.h +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -24,6 +24,7 @@ class ObjectDataHandler { public: ObjectDataHandler(ADT* _adt) : Source(_adt) {} + virtual ~ObjectDataHandler() {} void ProcessMapChunk(MapChunk* chunk); virtual void ProcessInternal(MapChunk* data) = 0; diff --git a/src/tools/mesh_extractor/Stream.h b/src/tools/mesh_extractor/Stream.h index 76d9511bbc4..9aaeba3369c 100644 --- a/src/tools/mesh_extractor/Stream.h +++ b/src/tools/mesh_extractor/Stream.h @@ -25,6 +25,12 @@ public: _position += size; } + template + void Skip() + { + _position += sizeof(T); + } + char* Read(uint32 size); std::string ReadString(); diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index f9563485c8b..e5c274380e9 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -91,7 +91,7 @@ void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& OutputDebugVertices(); } -uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) +uint8* TileBuilder::BuildInstance( dtNavMeshParams& /*navMeshParams*/ ) { float* bmin = NULL, *bmax = NULL; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 937de4b443a..5395fb1c92b 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -92,7 +92,7 @@ Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool t return ret; } -Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate ) +Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& /*root*/, Vector3& vec, bool translate ) { G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index b22e9ff136b..ef554d7606f 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -55,7 +55,7 @@ void WDT::ReadTileTable() { const uint32 hasTileFlag = 0x1; uint32 flags = stream->Read(); - uint32 discard = stream->Read(); + stream->Skip(); if (flags & hasTileFlag) TileTable.push_back(TilePos(x, y)); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 454756f2baf..57d1126a239 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -20,7 +20,7 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), IsBad(false), HasLiquidData(false) +WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), HasLiquidData(false), IsBad(false) { Data = new ChunkedData(path); if (!Data->_Stream) @@ -31,7 +31,7 @@ WorldModelGroup::WorldModelGroup(std::string path, int groupIndex) : SubData(NUL Load(path); } -WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), IsBad(false), HasLiquidData(false) +WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupIndex) : SubData(NULL), GroupIndex(groupIndex), MOBA(NULL), MOBALength(0), HasLiquidData(false), IsBad(false) { Data = new ChunkedData(stream, stream->GetSize()); Load(path); -- cgit v1.2.3 From 31bd3bab3fddd2734f4abc9dd40aa0d1c02b8706 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 31 Dec 2013 14:11:05 -0500 Subject: Tools/MeshExtractor: Fixed a crash when parsing liquid data (Thanks @Cyberium). Added some support for other liquid types in the liquid chunks (Namely Magma and Slime) --- src/tools/mesh_extractor/Constants.h | 2 ++ src/tools/mesh_extractor/LiquidHandler.cpp | 40 ++++++++++++++++++++++-------- src/tools/mesh_extractor/LiquidHandler.h | 3 ++- src/tools/mesh_extractor/MapChunk.cpp | 4 +-- src/tools/mesh_extractor/Utils.cpp | 11 ++++++++ src/tools/mesh_extractor/Utils.h | 3 ++- 6 files changed, 49 insertions(+), 14 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 5a89be9fe9c..7d9d6f92b92 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -26,6 +26,8 @@ public: TRIANGLE_TYPE_UNKNOWN, TRIANGLE_TYPE_TERRAIN, TRIANGLE_TYPE_WATER, + TRIANGLE_TYPE_MAGMA, + TRIANGLE_TYPE_SLIME, TRIANGLE_TYPE_DOODAD, TRIANGLE_TYPE_WMO }; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index fa59d1bc7f0..6800cb773f7 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -23,6 +23,13 @@ LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) HandleNewLiquid(); } +LiquidHandler::~LiquidHandler() +{ + for (std::vector::iterator itr = MCNKData.begin(); itr != MCNKData.end(); ++itr) + delete *itr; + MCNKData.clear(); +} + void LiquidHandler::HandleNewLiquid() { Chunk* chunk = Source->Data->GetChunkByName("MH2O"); @@ -44,12 +51,13 @@ void LiquidHandler::HandleNewLiquid() if (h.LayerCount == 0) { // Need to fill in missing data with dummies. - MCNKData.push_back(MCNKLiquidData(NULL, H2ORenderMask())); + MCNKData.push_back(new MCNKLiquidData(NULL, H2ORenderMask())); continue; } stream->Seek(chunk->Offset + h.OffsetInformation, SEEK_SET); H2OInformation information = H2OInformation::Read(stream); + // This pointer will be passed to the MCNKLiquidData constructor, from that point on, it is the job of MCNKLiquidData's destructor to release it. float** heights = new float*[9]; for (int j = 0; j < 9; ++j) { @@ -88,7 +96,7 @@ void LiquidHandler::HandleNewLiquid() heights[x][y] = information.HeightLevel1; } - MCNKData.push_back(MCNKLiquidData(heights, renderMask)); + MCNKData.push_back(new MCNKLiquidData(heights, renderMask)); for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) { @@ -108,15 +116,27 @@ void LiquidHandler::HandleNewLiquid() Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); Vertices.push_back(Vector3(location.x, location.y - Constants::UnitSize, location.z)); Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); - - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1)); - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + + // Define the liquid type + Constants::TriangleType type = Constants::TRIANGLE_TYPE_UNKNOWN; + switch (information.LiquidType) + { + case 1: // Water + case 2: // Ocean + default: + type = Constants::TRIANGLE_TYPE_WATER; + break; + case 3: + type = Constants::TRIANGLE_TYPE_MAGMA; + break; + case 4: + type = Constants::TRIANGLE_TYPE_SLIME; + break; + } + + Triangles.push_back(Triangle(type, vertOffset, vertOffset+2, vertOffset + 1)); + Triangles.push_back(Triangle(type, vertOffset + 2, vertOffset + 3, vertOffset + 1)); } } - - // At this stage, heights is no longer needed, so we deallocate it - for (int j = 0; j < 9; ++j) - delete[] heights[j]; - delete[] heights; } } diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index c053b621088..2bb503cc7e7 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -27,11 +27,12 @@ class LiquidHandler { public: LiquidHandler(ADT* adt); + ~LiquidHandler(); ADT* Source; std::vector Vertices; std::vector > Triangles; - std::vector MCNKData; + std::vector MCNKData; private: void HandleNewLiquid(); }; diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index f9d49762209..ee6b4584396 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -47,12 +47,12 @@ void MapChunk::GenerateTriangles() Constants::TriangleType triangleType = Constants::TRIANGLE_TYPE_TERRAIN; if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { - MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; + MCNKLiquidData* data = Adt->_LiquidHandler->MCNKData[Index]; float maxHeight = std::max( std::max( std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), Vertices[bottomRight].z), Vertices[center].z); - if (data.IsWater(x, y, maxHeight)) + if (data->IsWater(x, y, maxHeight)) triangleType = Constants::TRIANGLE_TYPE_WATER; } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 5395fb1c92b..9344776ae1f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -403,6 +403,17 @@ bool MCNKLiquidData::IsWater(int x, int y, float height) return false; } +MCNKLiquidData::~MCNKLiquidData() +{ + if (!Heights) + return; + + for (uint32 i = 0; i < 9; ++i) + delete[] Heights[i]; + delete[] Heights; + Heights = NULL; +} + H2OHeader H2OHeader::Read(Stream* stream) { H2OHeader ret; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 0f2df672250..ec826c701f9 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -300,8 +300,9 @@ public: class MCNKLiquidData { public: - MCNKLiquidData() {} + MCNKLiquidData() : Heights(NULL) {} MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} + ~MCNKLiquidData(); float** Heights; H2ORenderMask Mask; -- cgit v1.2.3 From 7b9dbfb1db1ee7464302add948c9779876f00ff1 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 31 Dec 2013 16:22:24 -0500 Subject: Tools/MeshExtractor: Fixed a few leaks and added the liquid vertices to the output data. --- src/tools/mesh_extractor/ADT.cpp | 5 +++++ src/tools/mesh_extractor/ChunkedData.cpp | 2 +- src/tools/mesh_extractor/Geometry.cpp | 4 ++++ src/tools/mesh_extractor/LiquidHandler.cpp | 26 +++++++++++++++++++++++--- src/tools/mesh_extractor/LiquidHandler.h | 1 + src/tools/mesh_extractor/WorldModelGroup.cpp | 4 ++++ 6 files changed, 38 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 39b600d21b7..ee7e1b12b44 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -33,6 +33,11 @@ ADT::ADT( std::string file, int x, int y ) : ObjectData(NULL), Data(NULL), HasOb ADT::~ADT() { + // Temporarily delete the underlying streams, they are guaranteed to be different + // @TODO: Remove this code once the ChunkedData destructor properly releases _Stream + delete ObjectData->_Stream; + delete Data->_Stream; + delete ObjectData; delete Data; diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index a3c3ec4b92c..8237449191a 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -85,7 +85,7 @@ ChunkedData::~ChunkedData() delete *itr; Chunks.clear(); - /* WorldModelGroup Data and SubData share the same _Stream so it's deleted twice and it crahes + /* WorldModelGroup Data and SubData share the same _Stream so it's deleted twice and it crashes if (_Stream) delete _Stream;*/ } diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index a11dda85659..62a10a65c16 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -20,6 +20,7 @@ #include "ADT.h" #include "WorldModelHandler.h" #include "DoodadHandler.h" +#include "LiquidHandler.h" #include Geometry::Geometry() : Transform(false) @@ -142,5 +143,8 @@ void Geometry::AddAdt( ADT* adt ) if (!adt->_WorldModelHandler->Triangles.empty()) AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); + + if (!adt->_LiquidHandler->Triangles.empty()) + AddData(adt->_LiquidHandler->Vertices, adt->_LiquidHandler->Triangles); } diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 6800cb773f7..7d93275f283 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -21,6 +21,7 @@ LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) { HandleNewLiquid(); + HandleOldLiquid(); } LiquidHandler::~LiquidHandler() @@ -66,7 +67,7 @@ void LiquidHandler::HandleNewLiquid() } H2ORenderMask renderMask; - if (information.LiquidType != 2) + if (information.LiquidType != 2 && information.LiquidType != 6 && information.LiquidType != 10) // Skip Ocean, Slow Ocean and Fast Ocean { stream->Seek(chunk->Offset + h.OffsetRender, SEEK_SET); renderMask = H2ORenderMask::Read(stream); @@ -123,13 +124,21 @@ void LiquidHandler::HandleNewLiquid() { case 1: // Water case 2: // Ocean + case 5: // Slow Water + case 6: // Slow Ocean + case 9: // Fast Water + case 10: // Fast Ocean default: type = Constants::TRIANGLE_TYPE_WATER; break; - case 3: + case 3: // Magma + case 7: // Slow Magma + case 11: // Fast Magma type = Constants::TRIANGLE_TYPE_MAGMA; break; - case 4: + case 4: // Slime + case 8: // Slow Slime + case 12: // Fast Slime type = Constants::TRIANGLE_TYPE_SLIME; break; } @@ -140,3 +149,14 @@ void LiquidHandler::HandleNewLiquid() } } } + +void LiquidHandler::HandleOldLiquid() +{ + for (uint32 i = 0; i < 256; ++i) + { + MapChunk* mapChunk = Source->MapChunks[i]; + if (!mapChunk->Header.OffsetMCLQ || mapChunk->Header.SizeMCLQ <= 8) + continue; + printf("Found old liquid"); + } +} diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index 2bb503cc7e7..d7f493e2719 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -35,5 +35,6 @@ public: std::vector MCNKData; private: void HandleNewLiquid(); + void HandleOldLiquid(); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 57d1126a239..3e16894ced6 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -39,6 +39,10 @@ WorldModelGroup::WorldModelGroup(Stream* stream, std::string path, int groupInde WorldModelGroup::~WorldModelGroup() { + // Temporarily delete the underlying stream, it is the same pointer for both Data and SubData. + // @TODO: Remove this code once the ChunkedData destructor properly releases _Stream + delete Data->_Stream; + delete Data; delete SubData; delete[] MOBA; -- cgit v1.2.3 From 060bc7817fef6751f0c7c24b2efc12a2f3754dae Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 31 Dec 2013 17:19:18 -0500 Subject: Tools/MeshExtractor: Added some consts --- src/tools/mesh_extractor/Cache.h | 2 +- src/tools/mesh_extractor/ChunkedData.cpp | 2 +- src/tools/mesh_extractor/ChunkedData.h | 2 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/ContinentBuilder.h | 2 +- src/tools/mesh_extractor/DBC.cpp | 6 +++--- src/tools/mesh_extractor/DBC.h | 10 ++++----- src/tools/mesh_extractor/DoodadHandler.cpp | 8 +++---- src/tools/mesh_extractor/DoodadHandler.h | 4 ++-- src/tools/mesh_extractor/Geometry.cpp | 6 +++--- src/tools/mesh_extractor/Geometry.h | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 30 ++++++++++++-------------- src/tools/mesh_extractor/MPQ.h | 8 +++---- src/tools/mesh_extractor/MPQManager.cpp | 12 +++++++++-- src/tools/mesh_extractor/MPQManager.h | 3 ++- src/tools/mesh_extractor/MeshExtractor.cpp | 8 +++---- src/tools/mesh_extractor/Stream.h | 4 ++-- src/tools/mesh_extractor/TileBuilder.cpp | 8 +++---- src/tools/mesh_extractor/TileBuilder.h | 6 +++--- src/tools/mesh_extractor/Utils.cpp | 4 ++-- src/tools/mesh_extractor/Utils.h | 4 ++-- src/tools/mesh_extractor/WDT.cpp | 4 ++-- src/tools/mesh_extractor/WDT.h | 4 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 23 ++++++++++---------- src/tools/mesh_extractor/WorldModelHandler.h | 4 ++-- 25 files changed, 87 insertions(+), 81 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 499983c6eb0..75496b5364d 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -31,7 +31,7 @@ class GenericCache public: GenericCache() {} - T* Get(K key) + T const* Get(K key) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); typename std::map::iterator itr = _items.find(key); diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 8237449191a..b288b5712cd 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -63,7 +63,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) } } -int ChunkedData::GetFirstIndex( const std::string& name ) +int ChunkedData::GetFirstIndex( const std::string& name ) const { for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index 349750b6c85..112bdb47199 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -29,7 +29,7 @@ public: ChunkedData(const std::string &file, uint32 chunksHint = 300); ~ChunkedData(); - int GetFirstIndex(const std::string& name); + int GetFirstIndex(const std::string& name) const; Chunk* GetChunkByName(const std::string& name); void Load(uint32 maxLength, uint32 chunksHint); diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 8321a7924a1..1e4b63ccec9 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -23,7 +23,7 @@ #include "Recast.h" #include "DetourCommon.h" -void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) const { // this is for elevation if (verts && vertCount) diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 8ecad9d9722..249fad05eb1 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -36,7 +36,7 @@ public: {} void Build(); - void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); + void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) const; void CalculateTileBounds(); float bmin[3]; float bmax[3]; diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 1484864d7a3..5bebc34a389 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -55,7 +55,7 @@ DBC::~DBC() delete *itr; } -std::string DBC::GetStringByOffset( int offset ) +std::string DBC::GetStringByOffset( int offset ) const { int len = 0; for (uint32 i = offset; i < StringBlockSize; i++) @@ -74,10 +74,10 @@ std::string DBC::GetStringByOffset( int offset ) return val; } -Record* DBC::GetRecordById( int id ) +Record const* DBC::GetRecordById( int id ) const { // we assume Id is index 0 - for (std::vector::iterator itr = Records.begin(); itr != Records.end(); ++itr) + for (std::vector::const_iterator itr = Records.begin(); itr != Records.end(); ++itr) if ((*itr)->Values[0] == id) return *itr; return NULL; diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 61912cd456d..33f5437ebe2 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -30,9 +30,9 @@ public: DBC(Stream* stream); ~DBC(); - std::string GetStringByOffset(int offset); + std::string GetStringByOffset(int offset) const; - Record* GetRecordById(int id); + Record const* GetRecordById(int id) const; std::string Name; std::vector Records; @@ -52,18 +52,18 @@ public: DBC* Source; std::vector Values; - int operator[](int index) + int operator[](int index) const { return Values[index]; } template - T GetValue(int index) + T GetValue(int index) const { return *(T*)(&Values[index]); } - std::string GetString(int index) + const std::string GetString(int index) const { return Source->GetStringByOffset(Values[index]); } diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 90f676ef769..5363855740e 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -56,7 +56,7 @@ void DoodadHandler::ProcessInternal(MapChunk* mcnk) continue; std::string path = (*_paths)[doodad.MmidIndex]; - Model* model = Cache->ModelCache.Get(path); + Model const* model = Cache->ModelCache.Get(path); if (!model->IsCollidable) continue; @@ -100,14 +100,14 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) +void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model const* model) { uint32 vertOffset = Vertices.size(); - for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) + for (std::vector::const_iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) Vertices.push_back(Utils::TransformDoodadVertex(def, *itr)); // Vertices have to be converted based on the information from the DoodadDefinition struct - for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) + for (std::vector >::const_iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index b02fcc664d1..d7d3e0917b5 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -59,7 +59,7 @@ public: std::vector Vertices; std::vector > Triangles; - bool IsSane() { return _definitions && _paths; } + bool IsSane() const { return _definitions && _paths; } protected: @@ -68,7 +68,7 @@ protected: private: void ReadDoodadDefinitions(Chunk* chunk); void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(const DoodadDefinition& def, Model* model); + void InsertModelGeometry(const DoodadDefinition& def, Model const* model); std::set _drawn; std::vector* _definitions; std::vector* _paths; diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 62a10a65c16..2ae05c0b736 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -92,12 +92,12 @@ void Geometry::AddData( std::vector& verts, std::vector(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } -void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) +void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) const { verts = new float[Vertices.size() * 3]; for (uint32 i = 0; i < Vertices.size(); ++i) { - Vector3& vert = Vertices[i]; + const Vector3& vert = Vertices[i]; verts[(i * 3) + 0] = vert.x; verts[(i * 3) + 1] = vert.y; verts[(i * 3) + 2] = vert.z; @@ -106,7 +106,7 @@ void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) tris = new int[Triangles.size() * 3]; for (uint32 i = 0; i < Triangles.size(); ++i) { - Triangle& tri = Triangles[i]; + const Triangle& tri = Triangles[i]; tris[(i * 3) + 0] = (int)tri.V0; tris[(i * 3) + 1] = (int)tri.V1; tris[(i * 3) + 2] = (int)tri.V2; diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h index f2ea43e381e..cd71ac5a828 100644 --- a/src/tools/mesh_extractor/Geometry.h +++ b/src/tools/mesh_extractor/Geometry.h @@ -31,7 +31,7 @@ public: void CalculateMinMaxHeight(float& min, float& max); void AddData(std::vector& verts, std::vector >& tris); void AddAdt(ADT* adt); - void GetRawData(float*& verts, int*& tris, uint8*& areas); + void GetRawData(float*& verts, int*& tris, uint8*& areas) const; std::vector Vertices; std::vector > Triangles; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 7d93275f283..1b6f5ce944e 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -17,6 +17,8 @@ #include "LiquidHandler.h" #include "Utils.h" +#include "DBC.h" +#include "MPQManager.h" LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) { @@ -58,6 +60,11 @@ void LiquidHandler::HandleNewLiquid() stream->Seek(chunk->Offset + h.OffsetInformation, SEEK_SET); H2OInformation information = H2OInformation::Read(stream); + // Load the LiquidTypes DBC + DBC const* liquidTypes = MPQHandler->GetDBC("LiquidTypes"); + Record const* liquid = liquidTypes->GetRecordById(information.LiquidType); + ASSERT(liquid); + // This pointer will be passed to the MCNKLiquidData constructor, from that point on, it is the job of MCNKLiquidData's destructor to release it. float** heights = new float*[9]; for (int j = 0; j < 9; ++j) @@ -65,9 +72,9 @@ void LiquidHandler::HandleNewLiquid() heights[j] = new float[9]; memset(heights[j], 0, sizeof(float) * 9); } - + H2ORenderMask renderMask; - if (information.LiquidType != 2 && information.LiquidType != 6 && information.LiquidType != 10) // Skip Ocean, Slow Ocean and Fast Ocean + if (liquid->GetValue(3) != 1) // Read the liquid type and skip Ocean, Slow Ocean and Fast Ocean { stream->Seek(chunk->Offset + h.OffsetRender, SEEK_SET); renderMask = H2ORenderMask::Read(stream); @@ -120,25 +127,16 @@ void LiquidHandler::HandleNewLiquid() // Define the liquid type Constants::TriangleType type = Constants::TRIANGLE_TYPE_UNKNOWN; - switch (information.LiquidType) + switch (liquid->GetValue(3)) { - case 1: // Water - case 2: // Ocean - case 5: // Slow Water - case 6: // Slow Ocean - case 9: // Fast Water - case 10: // Fast Ocean - default: + case 0: // Water + case 1: // Ocean type = Constants::TRIANGLE_TYPE_WATER; break; - case 3: // Magma - case 7: // Slow Magma - case 11: // Fast Magma + case 2: // Magma type = Constants::TRIANGLE_TYPE_MAGMA; break; - case 4: // Slime - case 8: // Slow Slime - case 12: // Fast Slime + case 3: // Slime type = Constants::TRIANGLE_TYPE_SLIME; break; } diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index c9b55545f1f..df39e901d5d 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -83,17 +83,17 @@ public: ~MPQFile() { close(); } size_t Read(void* dest, size_t bytes); Stream* GetFileStream(); - size_t getSize() { return size; } - size_t getPos() { return pointer; } + size_t getSize() const { return size; } + size_t getPos() const { return pointer; } char* getBuffer() { return buffer; } char* getPointer() { return buffer + pointer; } - bool isEof() { return eof; } + bool isEof() const { return eof; } void seek(int offset); void seekRelative(int offset); void close(); }; -inline void flipcc(char *fcc) +inline void flipcc(char* fcc) { char t; t=fcc[0]; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 987e53eb340..4834ca368c0 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -109,10 +109,18 @@ Stream* MPQManager::GetFile(const std::string& path ) return file.GetFileStream(); } -DBC* MPQManager::GetDBC(const std::string& name ) +DBC const* MPQManager::GetDBC(const std::string& name ) { + std::map::const_iterator itr = LoadedDBCs.find(name); + if (itr != LoadedDBCs.end()) + return itr->second; + std::string path = "DBFilesClient\\" + name + ".dbc"; - return new DBC(GetFile(path)); + DBC* dbc = new DBC(GetFile(path)); + + LoadedDBCs[name] = dbc; + + return dbc; } Stream* MPQManager::GetFileFromLocale( const std::string& path, uint32 locale ) diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 32a60917c82..d44030319cf 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -36,7 +36,7 @@ public: Stream* GetFileFrom(const std::string& path, MPQArchive* file); Stream* GetFileFromLocale(const std::string& path, uint32 locale); - DBC* GetDBC(const std::string& name); + DBC const* GetDBC(const std::string& name); std::vector GetAllFiles(std::string extension); std::deque Archives; @@ -51,6 +51,7 @@ protected: void InitializeDBC(); private: ACE_Thread_Mutex mutex; + std::map LoadedDBCs; }; extern MPQManager* MPQHandler; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0e2ca46b399..6e0cd11740c 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -61,9 +61,9 @@ void ExtractMMaps(std::set& mapIds, uint32 threads) std::string basePath = "mmaps/"; Utils::CreateDir(basePath); - DBC* dbc = MPQHandler->GetDBC("Map"); + DBC const* dbc = MPQHandler->GetDBC("Map"); printf("Map.dbc contains " SIZEFMTD " rows.\n", dbc->Records.size()); - for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + for (std::vector::const_iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { uint32 mapId = (*itr)->Values[0]; @@ -146,8 +146,8 @@ void ExtractGameobjectModels() return; } - DBC* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); - for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + DBC const* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); + for (std::vector::const_iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { std::string path = (*itr)->GetString(1); std::string fileName = Utils::GetPlainName(path.c_str()); diff --git a/src/tools/mesh_extractor/Stream.h b/src/tools/mesh_extractor/Stream.h index 9aaeba3369c..647ff9d5357 100644 --- a/src/tools/mesh_extractor/Stream.h +++ b/src/tools/mesh_extractor/Stream.h @@ -41,12 +41,12 @@ public: void Seek(uint32 position, uint32 type); - uint32 GetSize() + uint32 GetSize() const { return _size; } - uint32 GetPos() + uint32 GetPos() const { return _position; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index e5c274380e9..faee5b767cd 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -71,7 +71,7 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, Context = new rcContext; } -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& /*navMeshParams*/ ) +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& /*navMeshParams*/ ) const { bmin = new float[3]; bmax = new float[3]; @@ -81,7 +81,7 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } -void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def) +void TileBuilder::AddGeometry(WorldModelRoot const* root, const WorldModelDefinition& def) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -226,7 +226,7 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) adt->Read(); _Geometry->AddAdt(adt); delete adt; - + if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; @@ -387,7 +387,7 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) return NULL; } -void TileBuilder::OutputDebugVertices() +void TileBuilder::OutputDebugVertices() const { if (Constants::Debug) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index fb8950c552b..6171d407212 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -32,11 +32,11 @@ public: TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId); ~TileBuilder(); - void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); + void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams) const; uint8* BuildTiled(dtNavMeshParams& navMeshParams); uint8* BuildInstance(dtNavMeshParams& navMeshParams); - void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def); - void OutputDebugVertices(); + void AddGeometry(WorldModelRoot const* root, const WorldModelDefinition& def); + void OutputDebugVertices() const; std::string World; int X; int Y; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 9344776ae1f..b8ebc0b8fd3 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -92,7 +92,7 @@ Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool t return ret; } -Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& /*root*/, Vector3& vec, bool translate ) +Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& /*root*/, const Vector3& vec, bool translate) { G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); @@ -374,7 +374,7 @@ void LiquidData::Read(Stream* stream, LiquidHeader& header) { for (uint32 x = 0; x < header.CountXVertices; x++) { - stream->Read(); // Dummy value + stream->Skip(); HeightMap[x][y] = stream->Read(); } } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ec826c701f9..8424d92baa9 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -275,7 +275,7 @@ public: uint32 CountXVertices; uint32 Width; - bool ShouldRender(int x, int y) + bool ShouldRender(int x, int y) const { return RenderFlags[x][y] != 0x0F; } @@ -414,7 +414,7 @@ public: static char* GetPlainName(const char* FileName); static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3 vec, bool translate = true); static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false); - static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true); + static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, const Vector3& vec, bool translate = true); static void InitializeMmapTileHeader(MmapTileHeader& header); }; #endif diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index ef554d7606f..c4afec32a63 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -64,9 +64,9 @@ void WDT::ReadTileTable() } } -bool WDT::HasTile( int x, int y ) +bool WDT::HasTile( int x, int y ) const { - for (std::vector::iterator itr = TileTable.begin(); itr != TileTable.end(); ++itr) + for (std::vector::const_iterator itr = TileTable.begin(); itr != TileTable.end(); ++itr) if (itr->X == x && itr->Y == y) return true; return false; diff --git a/src/tools/mesh_extractor/WDT.h b/src/tools/mesh_extractor/WDT.h index d1e8e30918d..0deb5830e75 100644 --- a/src/tools/mesh_extractor/WDT.h +++ b/src/tools/mesh_extractor/WDT.h @@ -36,8 +36,8 @@ public: bool IsValid; std::string ModelFile; WorldModelDefinition ModelDefinition; - WorldModelRoot* Model; - bool HasTile(int x, int y); + WorldModelRoot const* Model; + bool HasTile(int x, int y) const; private: void ReadGlobalModel(); void ReadTileTable(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 2f4c1b6323c..00e2d462dbf 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -75,7 +75,7 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) continue; std::string path = (*_paths)[wmo.MwidIndex]; - WorldModelRoot* model = Cache->WorldModelCache.Get(path); + WorldModelRoot const* model = Cache->WorldModelCache.Get(path); Vertices.reserve(1000); Triangles.reserve(1000); @@ -86,13 +86,13 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) stream->Seek(mcnk->Source->Offset, SEEK_SET); } -void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate ) +void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot const* root, bool translate ) { - for (std::vector::iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) + for (std::vector::const_iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) { - WorldModelGroup* group = *groupItr; + WorldModelGroup const* group = *groupItr; uint32 vertOffset = verts.size(); - for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) + for (std::vector::const_iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) { Vector3 v = Utils::TransformDoodadVertex(def, *itr2, translate); // If translate is false, then we were called directly from the TileBuilder to add data to it's _Geometry member, hence, we have to manually convert the vertices to Recast format. @@ -123,34 +123,33 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { - Model* model = Cache->ModelCache.Get(instance->File); + Model const* model = Cache->ModelCache.Get(instance->File); if (!model->IsCollidable) continue; int vertOffset = verts.size(); - for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) + for (std::vector::const_iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) { Vector3 v = Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2, false), translate); verts.push_back(translate ? v : Utils::ToRecast(v)); } - for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) + for (std::vector >::const_iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } - for (std::vector::iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) + for (std::vector::const_iterator groupItr = root->Groups.begin(); groupItr != root->Groups.end(); ++groupItr) { - WorldModelGroup* group = *groupItr; + WorldModelGroup const* group = *groupItr; if (!group->HasLiquidData) continue; const LiquidHeader& liquidHeader = group->LiquidDataHeader; - LiquidData& liquidDataGeometry = group->LiquidDataGeometry; + const LiquidData& liquidDataGeometry = group->LiquidDataGeometry; for (uint32 y = 0; y < liquidHeader.Height; y++) { for (uint32 x = 0; x < liquidHeader.Width; x++) { - if (!liquidDataGeometry.ShouldRender(x, y)) continue; diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 9e5b1d1a3f7..ddc6f589147 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -50,8 +50,8 @@ public: std::vector Vertices; std::vector > Triangles; - bool IsSane() { return _definitions && _paths; } - static void InsertModelGeometry(std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate = true); + bool IsSane() const { return _definitions && _paths; } + static void InsertModelGeometry(std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot const* root, bool translate = true); protected: void ProcessInternal(MapChunk* data); private: -- cgit v1.2.3 From a63780fd90701ed81a0a5f2030e82ab1f6927ab4 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 31 Dec 2013 18:03:04 -0500 Subject: Tools/MeshExtractor: Fixed continent meshes, exclude triangles with material 0xFF from the mesh. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 4 ++-- src/tools/mesh_extractor/MeshExtractor.cpp | 4 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 1e4b63ccec9..9e64e7a1b05 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -110,8 +110,8 @@ void ContinentBuilder::Build() } else { - params.maxPolys = 32768; - params.maxTiles = 4096; + params.maxPolys = 1024; + params.maxTiles = TileMap->TileTable.size(); rcVcopy(params.orig, Constants::Origin); params.tileHeight = Constants::TileSize; params.tileWidth = Constants::TileSize; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 6e0cd11740c..de791b04d36 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -453,7 +453,7 @@ int main(int argc, char* argv[]) dtPolyRef m_startRef; dtPolyRef m_endRef; - FILE* mmap = fopen("mmaps/389.mmap", "rb"); + FILE* mmap = fopen("mmaps/631.mmap", "rb"); dtNavMeshParams params; int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); @@ -472,7 +472,7 @@ int main(int argc, char* argv[]) for (int j = 0; j <= 32; ++j) { char buff[100]; - sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j); + sprintf(buff, "mmaps/631%02i%02i.mmtile", i, j); LoadTile(navMesh, buff); } } diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 00e2d462dbf..18a90365c5b 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -102,8 +102,9 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v for (uint32 i = 0; i < group->Triangles.size(); ++i) { // only include colliding tris - if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) + if ((group->TriangleFlags[i] & 0x04) != 0 || group->TriangleMaterials[i] == 0xFF) continue; + Triangle tri = group->Triangles[i]; tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset)); } -- cgit v1.2.3