diff --git a/Libraries/NavWeakness/Include/NavPower.h b/Libraries/NavWeakness/Include/NavPower.h index ae82909..740ec4b 100644 --- a/Libraries/NavWeakness/Include/NavPower.h +++ b/Libraries/NavWeakness/Include/NavPower.h @@ -1,5 +1,5 @@ /* -NavPower.h - v2.0.0 +NavPower.h - v3.0.0 A header file for use with NavPower's binary navmesh files. Licensed under the MIT License @@ -140,7 +140,7 @@ namespace NavPower void writeBinary(std::ostream& f); }; - class NavGraphHeader + class NavGraphHeaderHm { public: uint32_t m_version = 0x28; @@ -163,6 +163,33 @@ namespace NavPower void writeBinary(std::ostream& f); }; + class NavGraphHeaderKnt + { + public: + uint32_t m_version = 0x30; + uint32_t m_layer = 0; + uint32_t m_areaBytes; + uint32_t m_kdTreeBytes; + uint32_t m_unknown0 = 0; + uint32_t m_unknown1 = 0; + uint32_t m_unknown2 = 56; + uint32_t m_linkRecordBytes = 0; + uint32_t m_totalBytes; + uint32_t m_unknown3 = 0; + float m_buildScale = 2.0f; + float m_voxSize = 0.1f; + float m_radius = 0.2f; + float m_stepHeight = 0.3f; + float m_height = 1.8f; // Human Height + BBox m_bbox; + Axis m_buildUpAxis = Axis::Z; + // In NAVPs from 007 First Light the padding isn't just 0x00 + // It is however identical in all files, changing it to all 0x00 makes NPCs disappear completely + uint8_t m_pad[252] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191,20,214,126,45,220,142,102,131,239,87,73,97,255,105,143,97,205,209,30,157,156,22,114,114,230,29,240,132,79,74,119,2,215,232,57,44,83,203,201,18,30,51,116,158,12,244,213,212,159,212,164,89,126,53,207,50,34,244,204,207,211,144,45,72,211,143,117,230,217,29,42,229,192,247,43,120,129,135,68,14,95,80,0,212,97,141,190,123,5,21,7,59,51,130,31,24,112,146,218,100,84,206,177,133,62,105,21,248,70,106,4,150,115,14,217,22,47,103,104,212,247,74,74,208,87,104,118 }; + + void writeBinary(std::ostream& f); + }; + class AreaFlags { public: @@ -308,7 +335,7 @@ namespace NavPower bool IsLeaf() { return m_data & 0x80000000 ? true : false; } void SetIsLeaf(int p_isLeaf) { m_data = (m_data & ~0x80000000) | (p_isLeaf & 0x80000000); } Axis GetSplitAxis() { return (Axis)((m_data >> 28) & 7); } - void SetSplitAxis(Axis p_axis) { m_data = (m_data & ~0x70000000) >> 28 | ((p_axis << 28) & 0x70000000); } + void SetSplitAxis(Axis p_axis) { m_data = (m_data & ~0x70000000) | ((static_cast(p_axis) << 28) & 0x70000000); } uint32_t GetRightOffset() { return m_data & 0xFFFFFFF; } void SetRightOffset(uint32_t p_rightOffset) { m_data = (m_data & ~0xFFFFFFF) | (p_rightOffset & 0xFFFFFFF); } KDNode* GetLeft() { return this + 1; } @@ -389,7 +416,6 @@ namespace NavPower return cross.GetUnitVec(); } - BBox CalculateBBox(); Vec3 CalculateCentroid(); void updateAdjacentDistances() const; }; @@ -403,7 +429,7 @@ namespace NavPower uint32_t m_splitAxis; }; - BBox generateBbox(std::vector s_areas); + BBox generateBbox(const std::vector& s_areas); bool compareX(Area& a1, Area& a2); bool compareY(Area& a1, Area& a2); bool compareZ(Area& a1, Area& a2); @@ -411,16 +437,16 @@ namespace NavPower class NavGraph { public: - Binary::NavGraphHeader* m_hdr; + union { + Binary::NavGraphHeaderHm* m_hdr; + Binary::NavGraphHeaderKnt* m_hdrKnt; + }; std::vector m_areas; Binary::KDTreeData* m_kdTreeData; Binary::KDNode* m_rootKDNode; NavGraph() {}; NavGraph(auto s_NavGraphJson); - - - NavGraph(uintptr_t p_data) { read(p_data); }; // Build m_areas pointer to index map so the pointers can be replaced with indices (+1) in the JSON file std::map AreaPointerToIndexMap(); @@ -448,10 +474,10 @@ namespace NavPower uint32_t generateKdTree(uintptr_t s_nodePtr, std::vector& s_areas, std::map& p_AreaPointerToNavGraphOffsetMap); void writeJson(std::ostream& f); - void readJson(auto s_NavGraphJson); + void readJson(auto s_NavGraphJson, bool s_IsKnt); void writeBinary(std::ostream& f); - void read(uintptr_t& p_data); + void read(uintptr_t& p_data, bool& p_isKnt); // This parses the k-d tree and outputs it as a vector of bounding boxes std::map>> ParseKDTree() @@ -512,11 +538,10 @@ namespace NavPower std::vector m_aNavGraphs; Section(){}; - Section(uintptr_t& p_data) { read(p_data); }; - void read(uintptr_t& p_data); + void read(uintptr_t& p_data, bool& p_isKnt); - void readJson(auto p_SectionJson); + void readJson(auto p_SectionJson, bool s_IsKnt); void writeJson(std::ofstream& f); @@ -528,6 +553,7 @@ namespace NavPower public: Binary::Header* m_hdr; std::vector
m_aSections; + bool m_isKnt; NavMesh() {}; NavMesh(const char* p_NavGraphJsonPath); diff --git a/Libraries/NavWeakness/Src/NavPower.cpp b/Libraries/NavWeakness/Src/NavPower.cpp index 3d08dd1..7920c3b 100644 --- a/Libraries/NavWeakness/Src/NavPower.cpp +++ b/Libraries/NavWeakness/Src/NavPower.cpp @@ -1,5 +1,5 @@ /* -NavPower.cpp - v2.0.0 +NavPower.cpp - v3.0.0 A header file for use with NavPower's binary navmesh files. Licensed under the MIT License @@ -32,6 +32,7 @@ SOFTWARE. #include #include #include +#include uint32_t RangeCheck(uint32_t val, uint32_t min, uint32_t max) { @@ -171,7 +172,7 @@ namespace NavPower f.write((char*)&m_numGraphs, sizeof(m_numGraphs)); } - void Binary::NavGraphHeader::writeBinary(std::ostream& f) + void Binary::NavGraphHeaderHm::writeBinary(std::ostream& f) { f.write((char*)&m_version, sizeof(m_version)); f.write((char*)&m_layer, sizeof(m_layer)); @@ -189,6 +190,28 @@ namespace NavPower f.write((char*)&m_pad, sizeof(m_pad)); } + void Binary::NavGraphHeaderKnt::writeBinary(std::ostream& f) + { + f.write((char*)&m_version, sizeof(m_version)); + f.write((char*)&m_layer, sizeof(m_layer)); + f.write((char*)&m_areaBytes, sizeof(m_areaBytes)); + f.write((char*)&m_kdTreeBytes, sizeof(m_kdTreeBytes)); + f.write((char*)&m_unknown0, sizeof(m_unknown0)); + f.write((char*)&m_unknown1, sizeof(m_unknown1)); + f.write((char*)&m_unknown2, sizeof(m_unknown2)); + f.write((char*)&m_linkRecordBytes, sizeof(m_linkRecordBytes)); + f.write((char*)&m_totalBytes, sizeof(m_totalBytes)); + f.write((char*)&m_unknown3, sizeof(m_unknown3)); + f.write((char*)&m_buildScale, sizeof(m_buildScale)); + f.write((char*)&m_voxSize, sizeof(m_voxSize)); + f.write((char*)&m_radius, sizeof(m_radius)); + f.write((char*)&m_stepHeight, sizeof(m_stepHeight)); + f.write((char*)&m_height, sizeof(m_height)); + m_bbox.writeBinary(f); + f.write((char*)&m_buildUpAxis, sizeof(m_buildUpAxis)); + f.write((char*)&m_pad, sizeof(m_pad)); + } + void Binary::AreaFlags::writeBinary(std::ostream& f) { f.write((char*)&m_flags1, sizeof(m_flags1)); @@ -428,10 +451,20 @@ namespace NavPower } } + bool isKnt(const uint32_t version) { + return version == 0x30; + } + void FixAreaPointers(uintptr_t data, size_t areaBytes) { uintptr_t navGraphStart = data; - uintptr_t curIndex = data + sizeof(Binary::NavGraphHeader); + const uint32_t version = *reinterpret_cast(navGraphStart); + uintptr_t curIndex; + if (isKnt(version)) { + curIndex = data + sizeof(Binary::NavGraphHeaderKnt); + } else { + curIndex = data + sizeof(Binary::NavGraphHeaderHm); + } size_t areaEndPtr = curIndex + areaBytes; while (curIndex != areaEndPtr) @@ -499,29 +532,6 @@ namespace NavPower } } - BBox Area::CalculateBBox() - { - float s_minFloat = -300000000000; - float s_maxFloat = 300000000000; - BBox bbox; - bbox.m_min.X = s_maxFloat; - bbox.m_min.Y = s_maxFloat; - bbox.m_min.Z = s_maxFloat; - bbox.m_max.X = s_minFloat; - bbox.m_max.Y = s_minFloat; - bbox.m_max.Z = s_minFloat; - for (auto& edge : m_edges) - { - bbox.m_max.X = std::max(bbox.m_max.X, edge->m_pos.X); - bbox.m_max.Y = std::max(bbox.m_max.Y, edge->m_pos.Y); - bbox.m_max.Z = std::max(bbox.m_max.Z, edge->m_pos.Z); - bbox.m_min.X = std::min(bbox.m_min.X, edge->m_pos.X); - bbox.m_min.Y = std::min(bbox.m_min.Y, edge->m_pos.Y); - bbox.m_min.Z = std::min(bbox.m_min.Z, edge->m_pos.Z); - } - return bbox; - } - Vec3 Area::CalculateCentroid() { Vec3 normal = CalculateNormal(); @@ -607,17 +617,13 @@ namespace NavPower } } - BBox generateBbox(std::vector s_areas) + BBox generateBbox(const std::vector& s_areas) { - float s_minFloat = -300000000000; - float s_maxFloat = 300000000000; BBox bbox; - bbox.m_min.X = s_maxFloat; - bbox.m_min.Y = s_maxFloat; - bbox.m_min.Z = s_maxFloat; - bbox.m_max.X = s_minFloat; - bbox.m_max.Y = s_minFloat; - bbox.m_max.Z = s_minFloat; + bbox.m_min.X = bbox.m_min.Y = bbox.m_min.Z = std::numeric_limits::max(); + bbox.m_max.X = bbox.m_max.Y = bbox.m_max.Z = -std::numeric_limits::max(); + + if (s_areas.empty()) return bbox; for (auto& area : s_areas) { @@ -784,7 +790,6 @@ namespace NavPower // 3. Completely to the right of the median for (int index = 0; index < s_originalAreas.size(); index++) { - BBox bbox = s_originalAreas[index].CalculateBBox(); float pos = 0; if (nodeSplits.splitAxis == Axis::X) { @@ -889,9 +894,13 @@ namespace NavPower readJson(s_NavGraphJson); } - void NavGraph::readJson(auto s_NavGraphJson) + void NavGraph::readJson(auto s_NavGraphJson, const bool s_IsKnt) { - m_hdr = new Binary::NavGraphHeader(); + if (s_IsKnt) { + m_hdrKnt = new Binary::NavGraphHeaderKnt(); + } else { + m_hdr = new Binary::NavGraphHeaderHm(); + } simdjson::ondemand::array s_AreasJson = s_NavGraphJson["Areas"]; for (auto areaJson : s_AreasJson) @@ -936,7 +945,12 @@ namespace NavPower // Calculate Bbox Areas and Edges BBox bbox = generateBbox(m_areas); - m_hdr->m_bbox.copy(bbox); + + if (s_IsKnt) { + m_hdrKnt->m_bbox.copy(bbox); + } else { + m_hdr->m_bbox.copy(bbox); + } m_kdTreeData->m_bbox.m_min.X = bbox.m_min.X - 0.0002; m_kdTreeData->m_bbox.m_min.Y = bbox.m_min.Y - 0.0002; m_kdTreeData->m_bbox.m_min.Z = bbox.m_min.Z - 0.0002; @@ -958,17 +972,30 @@ namespace NavPower generateKdTree(reinterpret_cast(m_rootKDNode), m_areas, s_AreaPointerToNavGraphOffsetMap); // Set size fields - m_hdr->m_areaBytes = s_areaBytes; - m_hdr->m_kdTreeBytes = sizeof(Binary::KDTreeData) + m_kdTreeData->m_size; - m_hdr->m_totalBytes = sizeof(Binary::NavGraphHeader) + m_hdr->m_areaBytes + m_hdr->m_kdTreeBytes; + + if (s_IsKnt) { + m_hdrKnt->m_areaBytes = s_areaBytes; + m_hdrKnt->m_kdTreeBytes = sizeof(Binary::KDTreeData) + m_kdTreeData->m_size; + m_hdrKnt->m_totalBytes = sizeof(Binary::NavGraphHeaderKnt) + m_hdrKnt->m_areaBytes + m_hdrKnt->m_kdTreeBytes; + } else { + m_hdr->m_areaBytes = s_areaBytes; + m_hdr->m_kdTreeBytes = sizeof(Binary::KDTreeData) + m_kdTreeData->m_size; + m_hdr->m_totalBytes = sizeof(Binary::NavGraphHeaderHm) + m_hdr->m_areaBytes + m_hdr->m_kdTreeBytes; + } } - void NavGraph::writeBinary(std::ostream& f) - { - m_hdr->writeBinary(f); + void NavGraph::writeBinary(std::ostream& f) { // Build m_areas area pointer to NavGraph offset pointer map so the offsets can be written instead of the memory pointers std::map s_AreaPointerToOffsetPointerMap; - unsigned char* s_AreaOffset = reinterpret_cast(sizeof(Binary::NavGraphHeader)); + unsigned char* s_AreaOffset; + uint32_t s_version = *reinterpret_cast(this); + if (isKnt(s_version)) { + m_hdrKnt->writeBinary(f); + s_AreaOffset = reinterpret_cast(sizeof(Binary::NavGraphHeaderKnt)); + } else { + m_hdr->writeBinary(f); + s_AreaOffset = reinterpret_cast(sizeof(Binary::NavGraphHeaderHm)); + } for (auto area : m_areas) { @@ -987,17 +1014,26 @@ namespace NavPower m_rootKDNode->writeBinary(f, p_KdTreeEnd); } - void NavGraph::read(uintptr_t& p_data) + void NavGraph::read(uintptr_t& p_data, bool& p_isKnt) { uintptr_t s_startPointer = p_data; uintptr_t s_endPointer{}; - m_hdr = (Binary::NavGraphHeader*)p_data; - p_data += sizeof(Binary::NavGraphHeader); - - FixAreaPointers(p_data - sizeof(Binary::NavGraphHeader), m_hdr->m_areaBytes); + const uint32_t s_version = *reinterpret_cast(p_data); + if (isKnt(s_version)) { + m_hdrKnt = reinterpret_cast(p_data); + p_data += sizeof(Binary::NavGraphHeaderKnt); + FixAreaPointers(p_data - sizeof(Binary::NavGraphHeaderKnt), m_hdrKnt->m_areaBytes); + s_endPointer = p_data + m_hdrKnt->m_areaBytes; + p_isKnt = true; + } else { + m_hdr = reinterpret_cast(p_data); + p_data += sizeof(Binary::NavGraphHeaderHm); + FixAreaPointers(p_data - sizeof(Binary::NavGraphHeaderHm), m_hdr->m_areaBytes); + s_endPointer = p_data + m_hdr->m_areaBytes; + p_isKnt = false; + } - s_endPointer = p_data + m_hdr->m_areaBytes; while (p_data < s_endPointer) { Area s_area{}; @@ -1029,7 +1065,7 @@ namespace NavPower p_data += sizeof(Binary::KDNode); } - if ((p_data - s_startPointer) != m_hdr->m_totalBytes) + if ((p_data - s_startPointer) != (isKnt(s_version) ? m_hdrKnt->m_totalBytes : m_hdr->m_totalBytes)) { printf("[WARNING] NavGraph - What we read does not match the total bytes!\n"); } @@ -1063,7 +1099,7 @@ namespace NavPower return s_Checksum; } - void Section::read(uintptr_t& p_data) + void Section::read(uintptr_t& p_data, bool& p_isKnt) { m_hdr = (Binary::SectionHeader*)p_data; p_data += sizeof(Binary::SectionHeader); @@ -1079,7 +1115,7 @@ namespace NavPower for (uint32_t i = 0; i < m_setHdr->m_numGraphs; ++i) { NavGraph s_Graph; - s_Graph.read(p_data); + s_Graph.read(p_data, p_isKnt); m_aNavGraphs.push_back(s_Graph); } @@ -1113,14 +1149,14 @@ namespace NavPower } } - void Section::readJson(auto p_SectionJson) + void Section::readJson(auto p_SectionJson, bool s_IsKnt) { m_hdr = new Binary::SectionHeader(); m_setHdr = new Binary::NavSetHeader(); m_hdr->m_size = sizeof(Binary::NavSetHeader); for (const auto& navGraphJson : p_SectionJson["NavGraphs"]) { NavGraph s_NavGraph; - s_NavGraph.readJson(navGraphJson); + s_NavGraph.readJson(navGraphJson, s_IsKnt); m_hdr->m_size += s_NavGraph.m_hdr->m_totalBytes; m_aNavGraphs.push_back(s_NavGraph); } @@ -1141,7 +1177,7 @@ namespace NavPower // Read Sections while ((p_data - s_startPointer) < p_filesize) { Section s_Section; - s_Section.read(p_data); + s_Section.read(p_data, m_isKnt); m_aSections.push_back(s_Section); } } @@ -1151,18 +1187,21 @@ namespace NavPower simdjson::ondemand::parser s_Parser; simdjson::padded_string s_Json = simdjson::padded_string::load(p_NavGraphJsonPath); simdjson::ondemand::document s_NavMeshDocument = s_Parser.iterate(s_Json); - std::string navpJsonVersion = std::string{ std::string_view(s_NavMeshDocument["NavpJsonVersion"]) }; - if (navpJsonVersion != "0.2") + auto s_NavpJsonVersion = std::string{ std::string_view(s_NavMeshDocument["NavpJsonVersion"]) }; + if (s_NavpJsonVersion != "0.3") { - std::cerr << "This version of NavWeakness only supports version 0.2. NavpJsonVersion " << navpJsonVersion << std::endl; - throw std::runtime_error("This version of NavWeakness only supports version 0.2"); + std::cerr << "This version of NavWeakness only supports version 0.3. NavpJsonVersion " << s_NavpJsonVersion << std::endl; + throw std::runtime_error("This version of NavWeakness only supports version 0.3"); } m_hdr = new Binary::Header(); m_hdr->m_imageSize = 0; + auto s_Game = std::string{ std::string_view(s_NavMeshDocument["Game"]) }; + m_isKnt = s_Game == "Knt"; + auto s_SectionsJson = s_NavMeshDocument["Sections"]; for (auto s_SectionJson : s_SectionsJson) { Section s_Section; - s_Section.readJson(s_SectionJson); + s_Section.readJson(s_SectionJson, m_isKnt); m_aSections.push_back(s_Section); // Set size fields m_hdr->m_imageSize += sizeof(Binary::SectionHeader) + s_Section.m_hdr->m_size; @@ -1194,7 +1233,9 @@ namespace NavPower } void NavMesh::writeJson(std::ofstream& f) { - f << "{\"NavpJsonVersion\":\"0.2\",\"Sections\":["; + f << "{\"NavpJsonVersion\":\"0.3\",\"Game\":\""; + f << (m_isKnt ? "Knt" : "HM"); + f << "\",\"Sections\":["; bool first = true; for (auto s_Section : m_aSections) { if (!first) { diff --git a/Libraries/NavWeakness/Src/NavWeakness.cpp b/Libraries/NavWeakness/Src/NavWeakness.cpp index 9a3f034..9a8ca76 100644 --- a/Libraries/NavWeakness/Src/NavWeakness.cpp +++ b/Libraries/NavWeakness/Src/NavWeakness.cpp @@ -46,7 +46,9 @@ NavPower::NavMesh LoadNavMeshFromBinary(const char* p_NavMeshPath) printf("Hdr_checksum: %x\n", s_NavMesh.m_hdr->m_checksum); printf("Hdr_runtimeFlags: %x\n", s_NavMesh.m_hdr->m_runtimeFlags); printf("Hdr_constantFlags: %x\n", s_NavMesh.m_hdr->m_constantFlags); - throw std::runtime_error("Checksums didn't match."); + printf("Checksums didn't match."); + // Commenting this out for now because it doesn't seem to work for First Light + // throw std::runtime_error("Checksums didn't match."); } return s_NavMesh; @@ -85,25 +87,45 @@ void OutputNavMesh_HUMAN_Print(NavPower::NavMesh* p_NavMesh) printf("Set_numGraphs: %x\n", s_Section.m_setHdr->m_numGraphs); for (auto s_NavGraph : s_Section.m_aNavGraphs) { printf("==== NavGraph Header ====\n"); - printf("GraphHdr_version: %x\n", s_NavGraph.m_hdr->m_version); - printf("GraphHdr_layer: %x\n", s_NavGraph.m_hdr->m_layer); - printf("GraphHdr_areaBytes: %x\n", s_NavGraph.m_hdr->m_areaBytes); - printf("GraphHdr_kdTreeBytes: %x\n", s_NavGraph.m_hdr->m_kdTreeBytes); - printf("GraphHdr_linkRecordBytes: %x\n", s_NavGraph.m_hdr->m_linkRecordBytes); - printf("GraphHdr_totalBytes: %x\n", s_NavGraph.m_hdr->m_totalBytes); - printf("GraphHdr_buildScale: %f\n", s_NavGraph.m_hdr->m_buildScale); - printf("GraphHdr_voxSize: %f\n", s_NavGraph.m_hdr->m_voxSize); - printf("GraphHdr_radius: %f\n", s_NavGraph.m_hdr->m_radius); - printf("GraphHdr_stepHeight: %f\n", s_NavGraph.m_hdr->m_stepHeight); - printf("GraphHdr_height: %f\n", s_NavGraph.m_hdr->m_height); - printf("GraphHdr_bbox.min.X: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.X); - printf("GraphHdr_bbox.min.Y: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.Y); - printf("GraphHdr_bbox.min.Z: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.Z); - printf("GraphHdr_bbox.max.X: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.X); - printf("GraphHdr_bbox.max.Y: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.Y); - printf("GraphHdr_bbox.max.Z: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.Z); - printf("GraphHdr_buildUpAxis: %x [%s]\n", s_NavGraph.m_hdr->m_buildUpAxis, NavPower::AxisToString(s_NavGraph.m_hdr->m_buildUpAxis).c_str()); - + if (s_NavMesh.m_isKnt) { + printf("GraphHdr_version: %x\n", s_NavGraph.m_hdrKnt->m_version); + printf("GraphHdr_layer: %x\n", s_NavGraph.m_hdrKnt->m_layer); + printf("GraphHdr_areaBytes: %x\n", s_NavGraph.m_hdrKnt->m_areaBytes); + printf("GraphHdr_kdTreeBytes: %x\n", s_NavGraph.m_hdrKnt->m_kdTreeBytes); + printf("GraphHdr_linkRecordBytes: %x\n", s_NavGraph.m_hdrKnt->m_linkRecordBytes); + printf("GraphHdr_totalBytes: %x\n", s_NavGraph.m_hdrKnt->m_totalBytes); + printf("GraphHdr_buildScale: %f\n", s_NavGraph.m_hdrKnt->m_buildScale); + printf("GraphHdr_voxSize: %f\n", s_NavGraph.m_hdrKnt->m_voxSize); + printf("GraphHdr_radius: %f\n", s_NavGraph.m_hdrKnt->m_radius); + printf("GraphHdr_stepHeight: %f\n", s_NavGraph.m_hdrKnt->m_stepHeight); + printf("GraphHdr_height: %f\n", s_NavGraph.m_hdrKnt->m_height); + printf("GraphHdr_bbox.min.X: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_min.X); + printf("GraphHdr_bbox.min.Y: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_min.Y); + printf("GraphHdr_bbox.min.Z: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_min.Z); + printf("GraphHdr_bbox.max.X: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_max.X); + printf("GraphHdr_bbox.max.Y: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_max.Y); + printf("GraphHdr_bbox.max.Z: %f\n", s_NavGraph.m_hdrKnt->m_bbox.m_max.Z); + printf("GraphHdr_buildUpAxis: %x [%s]\n", s_NavGraph.m_hdrKnt->m_buildUpAxis, NavPower::AxisToString(s_NavGraph.m_hdrKnt->m_buildUpAxis).c_str()); + } else { + printf("GraphHdr_version: %x\n", s_NavGraph.m_hdr->m_version); + printf("GraphHdr_layer: %x\n", s_NavGraph.m_hdr->m_layer); + printf("GraphHdr_areaBytes: %x\n", s_NavGraph.m_hdr->m_areaBytes); + printf("GraphHdr_kdTreeBytes: %x\n", s_NavGraph.m_hdr->m_kdTreeBytes); + printf("GraphHdr_linkRecordBytes: %x\n", s_NavGraph.m_hdr->m_linkRecordBytes); + printf("GraphHdr_totalBytes: %x\n", s_NavGraph.m_hdr->m_totalBytes); + printf("GraphHdr_buildScale: %f\n", s_NavGraph.m_hdr->m_buildScale); + printf("GraphHdr_voxSize: %f\n", s_NavGraph.m_hdr->m_voxSize); + printf("GraphHdr_radius: %f\n", s_NavGraph.m_hdr->m_radius); + printf("GraphHdr_stepHeight: %f\n", s_NavGraph.m_hdr->m_stepHeight); + printf("GraphHdr_height: %f\n", s_NavGraph.m_hdr->m_height); + printf("GraphHdr_bbox.min.X: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.X); + printf("GraphHdr_bbox.min.Y: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.Y); + printf("GraphHdr_bbox.min.Z: %f\n", s_NavGraph.m_hdr->m_bbox.m_min.Z); + printf("GraphHdr_bbox.max.X: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.X); + printf("GraphHdr_bbox.max.Y: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.Y); + printf("GraphHdr_bbox.max.Z: %f\n", s_NavGraph.m_hdr->m_bbox.m_max.Z); + printf("GraphHdr_buildUpAxis: %x [%s]\n", s_NavGraph.m_hdr->m_buildUpAxis, NavPower::AxisToString(s_NavGraph.m_hdr->m_buildUpAxis).c_str()); + } for (int i = 0; i < s_NavGraph.m_areas.size(); i++) { NavPower::Area s_curArea = s_NavGraph.m_areas.at(i); @@ -259,7 +281,7 @@ void OutputNavMesh_JSON_Write(NavPower::NavMesh* p_NavMesh, const char* p_NavMes fileOutputStream.close(); } -// Outputs the navmesh to binary format for use by Hitman WoA +// Outputs the navmesh to json format extern "C" void OutputNavMesh_JSON(const char* p_NavMeshPath, const char* p_NavMeshOutputPath, bool b_SourceIsJson = false) { if (b_SourceIsJson)