forked from Jnnshschl/AmeisenNavigation
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
more tweaks and work on the export tool, finished terrain export
- Loading branch information
Showing
29 changed files
with
1,195 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#pragma once | ||
|
||
struct DbcHeader | ||
{ | ||
char magic[4]; | ||
unsigned int recordCount; | ||
unsigned int fieldCount; | ||
unsigned int recordSize; | ||
unsigned int stringTableSize; | ||
}; | ||
|
||
class DbcFile | ||
{ | ||
unsigned char* Data; | ||
|
||
public: | ||
DbcFile(unsigned char* data) noexcept | ||
: Data(data) | ||
{} | ||
|
||
~DbcFile() noexcept | ||
{ | ||
if (Data) free(Data); | ||
} | ||
|
||
inline DbcHeader* GetHeader() const noexcept { return reinterpret_cast<DbcHeader*>(Data); } | ||
constexpr inline unsigned char* GetData() const noexcept { return Data + sizeof(DbcHeader); } | ||
|
||
inline unsigned int GetRecordCount() const noexcept { return GetHeader()->recordCount; } | ||
inline unsigned int GetFieldCount() const noexcept { return GetHeader()->fieldCount; } | ||
inline unsigned int GetRecordSize() const noexcept { return GetHeader()->recordSize; } | ||
inline unsigned int GetStringTableSize() const noexcept { return GetHeader()->stringTableSize; } | ||
inline unsigned char* GetStringTable() const noexcept { return GetData() + (GetRecordSize() * GetRecordCount()); } | ||
|
||
template<typename T> | ||
constexpr inline T Read(unsigned int id, unsigned int field) noexcept | ||
{ | ||
return *((T*)(GetData() + (id * GetRecordSize() + (field * 4)))); | ||
} | ||
|
||
inline const char* ReadString(unsigned int id, unsigned int field) noexcept | ||
{ | ||
return reinterpret_cast<char*>(GetStringTable() + Read<unsigned int>(id, field)); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,107 @@ | ||
#include "Main.hpp" | ||
|
||
int main() | ||
int main() noexcept | ||
{ | ||
const std::string mpqFilter{ ".mpq" }; | ||
std::vector<std::filesystem::path> mpqFiles{}; | ||
std::vector<std::pair<SFILE_FIND_DATA, std::filesystem::path>> dbcFiles{}; | ||
MpqManager mpqManager(GAME_DIR); | ||
|
||
for (const auto& entry : std::filesystem::recursive_directory_iterator("C:\\Spiele\\World of Warcraft 3.3.5a\\Data\\")) | ||
unsigned char* mapDbcData = nullptr; | ||
unsigned int mapDbcSize = 0; | ||
std::vector<std::pair<unsigned int, std::string>> maps; | ||
|
||
if (mpqManager.GetFileContent("DBFilesClient\\Map.dbc", mapDbcData, mapDbcSize)) | ||
{ | ||
if (entry.is_regular_file()) | ||
{ | ||
const auto& path = entry.path(); | ||
const auto& ext = path.extension().string(); | ||
DbcFile mapDbc(mapDbcData); | ||
|
||
if (std::equal(mpqFilter.begin(), mpqFilter.end(), ext.begin(), [](char a, char b) { return std::tolower(a) == std::tolower(b); })) | ||
{ | ||
mpqFiles.push_back(path); | ||
} | ||
for (unsigned int i = 0u; i < mapDbc.GetRecordCount(); ++i) | ||
{ | ||
maps.push_back(std::make_pair(mapDbc.Read<unsigned int>(i, 0u), mapDbc.ReadString(i, 1u))); | ||
} | ||
} | ||
|
||
std::sort(mpqFiles.begin(), mpqFiles.end(), NaturalCompare); | ||
unsigned char* liquidTypeDbcData = nullptr; | ||
unsigned int liquidTypeDbcSize = 0; | ||
std::unordered_map<unsigned int, LiquidType> liquidTypes; | ||
|
||
for (const auto& mpqFile : mpqFiles) | ||
if (mpqManager.GetFileContent("DBFilesClient\\LiquidType.dbc", liquidTypeDbcData, liquidTypeDbcSize)) | ||
{ | ||
std::cout << mpqFile << std::endl; | ||
continue; | ||
DbcFile liquidTypeDbc(liquidTypeDbcData); | ||
|
||
if (void* mpq; SFileOpenArchive(mpqFile.c_str(), 0, MPQ_OPEN_READ_ONLY, &mpq)) | ||
for (unsigned int i = 0u; i < liquidTypeDbc.GetRecordCount(); ++i) | ||
{ | ||
SFILE_FIND_DATA findData{}; | ||
void* fileFind = SFileFindFirstFile(mpq, "*.dbc", &findData, nullptr); | ||
liquidTypes[liquidTypeDbc.Read<unsigned int>(i, 0u)] = static_cast<LiquidType>(liquidTypeDbc.Read<unsigned int>(i, 3u)); | ||
} | ||
} | ||
|
||
// #pragma omp parallel for schedule(dynamic) | ||
for (int mapIndex = 0; mapIndex < 1; ++mapIndex) // maps.size() | ||
{ | ||
const auto& [id, name] = maps[mapIndex]; | ||
const auto mapsPath = std::format("World\\Maps\\{}\\{}", name, name); | ||
|
||
const auto wdtPath = std::format("{}.wdt", mapsPath); | ||
unsigned char* wdtData = nullptr; | ||
unsigned int wdtSize = 0; | ||
|
||
if (mpqManager.GetFileContent(wdtPath.c_str(), wdtData, wdtSize)) | ||
{ | ||
Wdt wdt(wdtData); | ||
|
||
std::vector<Vector3> verts; | ||
std::vector<Tri> tris; | ||
|
||
while (fileFind) | ||
for (int i = 0; i < 1; ++i) // WDT_MAP_SIZE * WDT_MAP_SIZE | ||
{ | ||
dbcFiles.push_back(std::make_pair(findData, mpqFile)); | ||
const auto x = 48; // i % WDT_MAP_SIZE; | ||
const auto y = 32; // i / WDT_MAP_SIZE; | ||
|
||
if (!SFileFindNextFile(fileFind, &findData)) | ||
if (wdt.Main()->adt[x][y].exists) | ||
{ | ||
break; | ||
const auto adtPath = std::format("{}_{}_{}.adt", mapsPath, y, x); | ||
unsigned char* adtData = nullptr; | ||
unsigned int adtSize = 0; | ||
|
||
std::cout << "[Maps] " << name << ": ADT(" << x << ", " << y << ") " << adtPath << std::endl; | ||
|
||
if (mpqManager.GetFileContent(adtPath.c_str(), adtData, adtSize)) | ||
{ | ||
Adt adt(adtData); | ||
|
||
for (int a = 0; a < ADT_CELLS_PER_GRID * ADT_CELLS_PER_GRID; ++a) | ||
{ | ||
const int cx = a / ADT_CELLS_PER_GRID; | ||
const int cy = a % ADT_CELLS_PER_GRID; | ||
|
||
adt.GetTerrainVertsAndTris(cx, cy, verts, tris); | ||
adt.GetLiquidVertsAndTris(cx, cy, verts, tris); | ||
} | ||
} | ||
} | ||
} | ||
|
||
SFileFindClose(fileFind); | ||
SFileCloseArchive(mpq); | ||
} | ||
else | ||
{ | ||
std::cerr << "-> Failed to open MPQ file: " << mpqFile << std::endl; | ||
ExportDebugObjFile(verts, tris); | ||
} | ||
} | ||
|
||
std::sort(dbcFiles.begin(), dbcFiles.end(), [](const auto& a, const auto& b) { return a.second > b.second; }); | ||
return 0; | ||
} | ||
|
||
for (const auto& dbcFile : dbcFiles) | ||
void ExportDebugObjFile(const std::vector<Vector3>& vertexes, const std::vector<Tri>& tris) noexcept | ||
{ | ||
std::cout << "Exporting OBJ file" << std::endl; | ||
std::fstream objFstream; | ||
objFstream << std::fixed << std::showpoint; | ||
objFstream << std::setprecision(8); | ||
objFstream.open("C:\\Users\\Jannis\\source\\repos\\recastnavigation\\RecastDemo\\Bin\\Meshes\\debug.obj", std::fstream::out); | ||
|
||
for (const auto& v3 : vertexes) | ||
{ | ||
std::cout << dbcFile.first.szPlainName << std::endl; | ||
objFstream << "v " << v3.y << " " << v3.z << " " << v3.x << "\n"; | ||
} | ||
|
||
return 0; | ||
} | ||
for (const auto& tri : tris) | ||
{ | ||
objFstream << "f " << tri.a << " " << tri.b << " " << tri.c << "\n"; | ||
} | ||
|
||
objFstream.close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,20 @@ | ||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <filesystem> | ||
#include <format> | ||
#include <fstream> | ||
#include <iostream> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#define STORMLIB_NO_AUTO_LINK | ||
#include <stormlib.h> | ||
#include "Utils/Vector3.hpp" | ||
#include "Utils/Tri.hpp" | ||
#include "Dbc/DbcFile.hpp" | ||
#include "Mpq/MpqManager.hpp" | ||
#include "Wow/Adt.hpp" | ||
#include "Wow/LiquidType.hpp" | ||
#include "Wow/Wdt.hpp" | ||
|
||
#include <shlwapi.h> | ||
#pragma comment(lib, "Shlwapi.lib") | ||
constexpr auto GAME_DIR = "C:\\Spiele\\World of Warcraft 3.3.5a\\Data\\"; | ||
|
||
inline auto NaturalCompare(const std::filesystem::path& path1, const std::filesystem::path& path2) | ||
{ | ||
return StrCmpLogicalW(path1.wstring().c_str(), path2.wstring().c_str()); | ||
} | ||
void ExportDebugObjFile(const std::vector<Vector3>& vertexes, const std::vector<Tri>& tris) noexcept; |
Oops, something went wrong.