Skip to content

Commit c57c958

Browse files
committed
Added multiple z layer airg generation
1 parent 5a9e322 commit c57c958

File tree

8 files changed

+143
-44
lines changed

8 files changed

+143
-44
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ endif()
1212

1313
project(
1414
NavKit
15-
VERSION 0.8.0
15+
VERSION 0.9.0
1616
DESCRIPTION "An app to create NAVP and AIRG files for use with Hitman"
1717
LANGUAGES CXX)
1818

include/NavKit/NavKitConfig.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#define NavKit_VERSION_MAJOR "0"
2-
#define NavKit_VERSION_MINOR "8"
2+
#define NavKit_VERSION_MINOR "9"
33
#define NavKit_VERSION_PATCH "0"

include/NavKit/Navp.h

+7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ class Navp {
3030
float bBoxSizeY;
3131
float bBoxSizeZ;
3232

33+
float lastBBoxPosX;
34+
float lastBBoxPosY;
35+
float lastBBoxPosZ;
36+
float lastBBoxSizeX;
37+
float lastBBoxSizeY;
38+
float lastBBoxSizeZ;
39+
3340
bool stairsCheckboxValue;
3441

3542
void setLastLoadFileName(const char* fileName);

include/NavKit/ReasoningGrid.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
#include <string>
44
#include <vector>
5+
#include <set>
56
#include <iostream>
67
#include <filesystem>
78
#include <fstream>
89
#include <stdlib.h>
910
#include "..\NavWeakness\NavPower.h"
1011
#include "..\RecastDemo\SampleInterfaces.h"
1112
#include "..\..\extern\simdjson\simdjson.h"
13+
#include "NavKit.h"
1214

15+
class NavKit;
1316
class Vec4 {
1417
public:
1518
float x;
@@ -65,5 +68,5 @@ class ReasoningGrid {
6568

6669
const void writeJson(std::ostream& f);
6770
void readJson(const char* p_AirgPath);
68-
void build(NavPower::NavMesh* navMesh, BuildContext* ctx);
71+
static void build(ReasoningGrid* airg, NavPower::NavMesh* navMesh, NavKit* ctx);
6972
};

src/Airg.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,14 @@ void Airg::drawMenu() {
8989
navKit->log(RC_LOG_PROGRESS, msg.data());
9090
if (extension == "JSON") {
9191
saveAirg(fileName);
92+
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{ fileName } + ".").c_str());
9293
}
9394
else if (extension == "AIRG") {
9495
std::string tempJsonFile = fileName;
9596
tempJsonFile += ".temp.json";
9697
saveAirg(tempJsonFile);
9798
airgResourceGenerator->FromJsonFileToResourceFile(tempJsonFile.data(), fileName, false);
99+
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{ fileName } + ".").c_str());
98100
std::filesystem::remove(tempJsonFile);
99101
}
100102
}
@@ -106,8 +108,8 @@ void Airg::drawMenu() {
106108
reasoningGrid = new ReasoningGrid();
107109
std::string msg = "Building Airg from Navp";
108110
navKit->log(RC_LOG_PROGRESS, msg.data());
109-
reasoningGrid->build(navKit->navp->navMesh, &navKit->ctx);
110-
airgLoaded = true;
111+
std::thread buildAirgThread(&ReasoningGrid::build, reasoningGrid, navKit->navp->navMesh, navKit);
112+
buildAirgThread.detach();
111113
}
112114
imguiEndScrollArea();
113115
}
@@ -164,7 +166,6 @@ void Airg::saveAirg(std::string fileName) {
164166
std::ofstream fileOutputStream(s_OutputFileName);
165167
reasoningGrid->writeJson(fileOutputStream);
166168
fileOutputStream.close();
167-
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{fileName} + ".").c_str());
168169
}
169170

170171
void Airg::loadAirg(Airg* airg, char* fileName, bool isFromJson) {

src/Navp.cpp

+42-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ Navp::Navp(NavKit* navKit): navKit(navKit) {
1717
bBoxSizeX = 100.0;
1818
bBoxSizeY = 100.0;
1919
bBoxSizeZ = 100.0;
20+
lastBBoxPosX = 0.0;
21+
lastBBoxPosY = 0.0;
22+
lastBBoxPosZ = 0.0;
23+
lastBBoxSizeX = 100.0;
24+
lastBBoxSizeY = 100.0;
25+
lastBBoxSizeZ = 100.0;
2026

2127
stairsCheckboxValue = false;
2228
loading = false;
@@ -267,12 +273,42 @@ void Navp::drawMenu() {
267273
navKit->sample->handleCommonSettings();
268274

269275
bool bboxChanged = false;
270-
bboxChanged |= imguiSlider("Bounding Box Origin X", &bBoxPosX, -300.0f, 300.0f, 1.0f);
271-
bboxChanged |= imguiSlider("Bounding Box Origin Y", &bBoxPosY, -300.0f, 300.0f, 1.0f);
272-
bboxChanged |= imguiSlider("Bounding Box Origin Z", &bBoxPosZ, -300.0f, 300.0f, 1.0f);
273-
bboxChanged |= imguiSlider("Bounding Box Size X", &bBoxSizeX, 1.0f, 600.0f, 1.0f);
274-
bboxChanged |= imguiSlider("Bounding Box Size Y", &bBoxSizeY, 1.0f, 600.0f, 1.0f);
275-
bboxChanged |= imguiSlider("Bounding Box Size Z", &bBoxSizeZ, 1.0f, 600.0f, 1.0f);
276+
if (imguiSlider("Bounding Box Origin X", &bBoxPosX, -300.0f, 300.0f, 1.0f)) {
277+
if (lastBBoxPosX != bBoxPosX) {
278+
bboxChanged = true;
279+
lastBBoxPosX = bBoxPosX;
280+
}
281+
}
282+
if (imguiSlider("Bounding Box Origin Y", &bBoxPosY, -300.0f, 300.0f, 1.0f)) {
283+
if (lastBBoxPosY != bBoxPosY) {
284+
bboxChanged = true;
285+
lastBBoxPosY = bBoxPosY;
286+
}
287+
}
288+
if (imguiSlider("Bounding Box Origin Z", &bBoxPosZ, -300.0f, 300.0f, 1.0f)) {
289+
if (lastBBoxPosZ != bBoxPosZ) {
290+
bboxChanged = true;
291+
lastBBoxPosZ = bBoxPosZ;
292+
}
293+
}
294+
if (imguiSlider("Bounding Box Size X", &bBoxSizeX, 1.0f, 600.0f, 1.0f)) {
295+
if (lastBBoxSizeX != bBoxSizeX) {
296+
bboxChanged = true;
297+
lastBBoxSizeX = bBoxSizeX;
298+
}
299+
}
300+
if (imguiSlider("Bounding Box Size Y", &bBoxSizeY, 1.0f, 600.0f, 1.0f)) {
301+
if (lastBBoxSizeY != bBoxSizeY) {
302+
bboxChanged = true;
303+
lastBBoxSizeY = bBoxSizeY;
304+
}
305+
}
306+
if (imguiSlider("Bounding Box Size Z", &bBoxSizeZ, 1.0f, 600.0f, 1.0f)) {
307+
if (lastBBoxSizeZ != bBoxSizeZ) {
308+
bboxChanged = true;
309+
lastBBoxSizeZ = bBoxSizeZ;
310+
}
311+
}
276312

277313
if (bboxChanged)
278314
{

src/ReasoningGrid.cpp

+83-31
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,20 @@ int pnpoly(int nvert, float* vertx, float* verty, float testx, float testy)
236236
return c;
237237
}
238238

239-
void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
240-
ctx->log(RC_LOG_PROGRESS, "Started building Airg.");
239+
float calcZ(Vec3 p1, Vec3 p2, Vec3 p3, float x, float y) {
240+
float dx1 = x - p1.X;
241+
float dy1 = y - p1.Y;
242+
float dx2 = p2.X - p1.X;
243+
float dy2 = p2.Y - p1.Y;
244+
float dx3 = p3.X - p1.X;
245+
float dy3 = p3.Y - p1.Y;
246+
return p1.Z + ((dy1 * dx3 - dx1 * dy3) * (p2.Z - p1.Z) + (dx1 * dy2 - dy1 * dx2) * (p3.Z - p1.Z)) / (dx3 * dy2 - dx2 * dy3);
247+
}
248+
249+
void ReasoningGrid::build(ReasoningGrid* airg, NavPower::NavMesh* navMesh, NavKit* navKit) {
250+
navKit->log(RC_LOG_PROGRESS, "Started building Airg.");
241251
double spacing = 2;
252+
double zSpacing = 1;
242253
// grid is set up in this order: Z[Y[X[]]]
243254
std::vector<std::vector<std::vector<int>>> grid;
244255
Vec3 min = navMesh->m_graphHdr->m_bbox.m_min;
@@ -247,39 +258,78 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
247258
Vec3 max = navMesh->m_graphHdr->m_bbox.m_max;
248259
int gridXSize = std::ceil((max.X - min.X) / spacing);
249260
int gridYSize = std::ceil((max.Y - min.Y) / spacing);
250-
int gridZSize = 1;
251-
m_Properties.fGridSpacing = spacing;
252-
m_Properties.nGridWidth = gridYSize;
253-
m_Properties.vMin.x = min.X;
254-
m_Properties.vMin.y = min.Y;
255-
m_Properties.vMin.z = min.Z;
256-
m_Properties.vMin.w = 1;
257-
m_Properties.vMax.x = max.X;
258-
m_Properties.vMax.y = max.Y;
259-
m_Properties.vMax.z = max.Z;
260-
m_Properties.vMax.w = 1;
261+
int gridZSize = std::ceil((max.Z - min.Z) / zSpacing);
262+
gridZSize = gridZSize > 0 ? gridZSize : 1;
263+
airg->m_Properties.fGridSpacing = spacing;
264+
airg->m_Properties.nGridWidth = gridYSize;
265+
airg->m_Properties.vMin.x = min.X;
266+
airg->m_Properties.vMin.y = min.Y;
267+
airg->m_Properties.vMin.z = min.Z;
268+
airg->m_Properties.vMin.w = 1;
269+
airg->m_Properties.vMax.x = max.X;
270+
airg->m_Properties.vMax.y = max.Y;
271+
airg->m_Properties.vMax.z = max.Z;
272+
airg->m_Properties.vMax.w = 1;
273+
274+
std::vector<double> areaZMins;
275+
std::vector<double> areaZMaxes;
276+
277+
for (auto area : navMesh->m_areas) {
278+
const int areaPointCount = area.m_edges.size();
279+
double areaMinZ = 1000;
280+
double areaMaxZ = -1000;
281+
double pointZ = 0;
282+
for (int i = 0; i < areaPointCount; i++) {
283+
pointZ = area.m_edges[i]->m_pos.Z;
284+
areaMinZ = areaMinZ < pointZ ? areaMinZ : pointZ;
285+
areaMaxZ = areaMaxZ > pointZ ? areaMaxZ : pointZ;
286+
}
287+
areaZMins.push_back(areaMinZ);
288+
areaZMaxes.push_back(areaMaxZ);
289+
}
290+
std::vector<std::vector<int>> areasByZLevel;
291+
for (int zi = 0; zi < gridZSize; zi++) {
292+
std::vector<int> areasForZLevel;
293+
for (int areaIndex = 0; areaIndex < navMesh->m_areas.size(); areaIndex++) {
294+
double minZ = min.Z + zi * zSpacing;
295+
double maxZ = min.Z + (zi + 1) * zSpacing;
296+
if ((areaZMins[areaIndex] >= minZ && areaZMins[areaIndex] <= maxZ) ||
297+
(areaZMaxes[areaIndex] >= minZ && areaZMaxes[areaIndex] <= maxZ) ||
298+
(areaZMins[areaIndex] <= minZ && areaZMaxes[areaIndex] >= maxZ)) {
299+
areasForZLevel.push_back(areaIndex);
300+
}
301+
}
302+
areasByZLevel.push_back(areasForZLevel);
303+
}
261304

262305
int wayPointIndex = 0;
263306
for (int zi = 0; zi < gridZSize; zi++) {
264307
std::vector<std::vector<int>> yRow;
308+
navKit->log(rcLogCategory::RC_LOG_PROGRESS, ("Adding waypoints for Z level: " + std::to_string(zi) + " at Z: " + std::to_string(min.Z + zi * zSpacing)).c_str());
309+
double minZ = min.Z + zi * zSpacing;
310+
double maxZ = min.Z + (zi + 1) * zSpacing;
265311
for (int yi = 0; yi < gridYSize; yi++) {
266312
std::vector<int> xRow;
267313
for (int xi = 0; xi < gridXSize; xi++) {
268-
bool pointInArea = false;
269314
double x = min.X + xi * spacing;
270315
double y = min.Y + yi * spacing;
271-
double z = min.Z + zi * spacing;
272-
for (auto area : navMesh->m_areas) {
316+
double z = min.Z + zi * zSpacing;
317+
bool pointInArea = false;
318+
for (int areaIndex : areasByZLevel[zi]) {
319+
auto area = navMesh->m_areas[areaIndex];
273320
const int areaPointCount = area.m_edges.size();
274-
float areaXCoords[10];
275-
float areaYCoords[10];
276-
for (int i = 0; i < areaPointCount; i++) {
277-
areaXCoords[i] = area.m_edges[i]->m_pos.X;
278-
areaYCoords[i] = area.m_edges[i]->m_pos.Y;
279-
}
280-
pointInArea = pnpoly(areaPointCount, areaXCoords, areaYCoords, x, y);
281-
if (pointInArea) {
282-
break;
321+
z = calcZ(area.m_edges[0]->m_pos, area.m_edges[1]->m_pos, area.m_edges[2]->m_pos, x, y) + 0.1;
322+
if (z > (minZ - zSpacing * .8) && z < (maxZ + zSpacing * .8)) {
323+
float areaXCoords[10];
324+
float areaYCoords[10];
325+
for (int i = 0; i < areaPointCount; i++) {
326+
areaXCoords[i] = area.m_edges[i]->m_pos.X;
327+
areaYCoords[i] = area.m_edges[i]->m_pos.Y;
328+
}
329+
pointInArea = pnpoly(areaPointCount, areaXCoords, areaYCoords, x, y);
330+
if (pointInArea) {
331+
break;
332+
}
283333
}
284334
}
285335
xRow.push_back(pointInArea ? wayPointIndex++ : 65535);
@@ -291,16 +341,16 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
291341
waypoint.vPos.w = 1.0;
292342
waypoint.nVisionDataOffset = 0;
293343
waypoint.nLayerIndex = 0;
294-
m_WaypointList.push_back(waypoint);
344+
airg->m_WaypointList.push_back(waypoint);
295345
}
296346
}
297347
yRow.push_back(xRow);
298348
}
299349
grid.push_back(yRow);
300350
}
301351

302-
m_nNodeCount = m_WaypointList.size();
303-
m_deadEndData.m_nSize = m_nNodeCount;
352+
airg->m_nNodeCount = airg->m_WaypointList.size();
353+
airg->m_deadEndData.m_nSize = airg->m_nNodeCount;
304354
// Neighbors: South is 0, increases CCW
305355
std::pair<int, int> gridIndexDiff[8]{
306356
std::pair(0, -1),
@@ -326,12 +376,14 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
326376
nyi >= 0 && nyi < gridYSize) {
327377
neighborWaypointIndex = grid[zi][nyi][nxi];
328378
}
329-
m_WaypointList[waypointIndex].nNeighbors.push_back(neighborWaypointIndex);
379+
airg->m_WaypointList[waypointIndex].nNeighbors.push_back(neighborWaypointIndex);
330380
}
331381
}
332382
}
333383
}
334384
}
335-
std::vector<uint32_t> visibilityData(m_nNodeCount * 1001);
336-
m_pVisibilityData = visibilityData;
385+
std::vector<uint32_t> visibilityData(airg->m_nNodeCount * 1001);
386+
airg->m_pVisibilityData = visibilityData;
387+
navKit->log(RC_LOG_PROGRESS, "Done building Airg.");
388+
navKit->airg->airgLoaded = true;
337389
}

src/RecastDemo/Sample.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void Sample::resetCommonSettings()
188188
m_regionMergeSize = 30;
189189
m_edgeMaxLen = 500.0f;
190190
m_edgeMaxError = 1.4f;
191-
m_vertsPerPoly = 6.0f;
191+
m_vertsPerPoly = 3.0f;
192192
m_detailSampleDist = 1.5f;
193193
m_detailSampleMaxError = 1.4f;
194194
m_partitionType = SAMPLE_PARTITION_WATERSHED;

0 commit comments

Comments
 (0)