Skip to content

Commit

Permalink
Added multiple z layer airg generation
Browse files Browse the repository at this point in the history
  • Loading branch information
dbierek committed Sep 26, 2024
1 parent 5a9e322 commit c57c958
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 44 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ endif()

project(
NavKit
VERSION 0.8.0
VERSION 0.9.0
DESCRIPTION "An app to create NAVP and AIRG files for use with Hitman"
LANGUAGES CXX)

Expand Down
2 changes: 1 addition & 1 deletion include/NavKit/NavKitConfig.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define NavKit_VERSION_MAJOR "0"
#define NavKit_VERSION_MINOR "8"
#define NavKit_VERSION_MINOR "9"
#define NavKit_VERSION_PATCH "0"
7 changes: 7 additions & 0 deletions include/NavKit/Navp.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ class Navp {
float bBoxSizeY;
float bBoxSizeZ;

float lastBBoxPosX;
float lastBBoxPosY;
float lastBBoxPosZ;
float lastBBoxSizeX;
float lastBBoxSizeY;
float lastBBoxSizeZ;

bool stairsCheckboxValue;

void setLastLoadFileName(const char* fileName);
Expand Down
5 changes: 4 additions & 1 deletion include/NavKit/ReasoningGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <stdlib.h>
#include "..\NavWeakness\NavPower.h"
#include "..\RecastDemo\SampleInterfaces.h"
#include "..\..\extern\simdjson\simdjson.h"
#include "NavKit.h"

class NavKit;
class Vec4 {
public:
float x;
Expand Down Expand Up @@ -65,5 +68,5 @@ class ReasoningGrid {

const void writeJson(std::ostream& f);
void readJson(const char* p_AirgPath);
void build(NavPower::NavMesh* navMesh, BuildContext* ctx);
static void build(ReasoningGrid* airg, NavPower::NavMesh* navMesh, NavKit* ctx);
};
7 changes: 4 additions & 3 deletions src/Airg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@ void Airg::drawMenu() {
navKit->log(RC_LOG_PROGRESS, msg.data());
if (extension == "JSON") {
saveAirg(fileName);
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{ fileName } + ".").c_str());
}
else if (extension == "AIRG") {
std::string tempJsonFile = fileName;
tempJsonFile += ".temp.json";
saveAirg(tempJsonFile);
airgResourceGenerator->FromJsonFileToResourceFile(tempJsonFile.data(), fileName, false);
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{ fileName } + ".").c_str());
std::filesystem::remove(tempJsonFile);
}
}
Expand All @@ -106,8 +108,8 @@ void Airg::drawMenu() {
reasoningGrid = new ReasoningGrid();
std::string msg = "Building Airg from Navp";
navKit->log(RC_LOG_PROGRESS, msg.data());
reasoningGrid->build(navKit->navp->navMesh, &navKit->ctx);
airgLoaded = true;
std::thread buildAirgThread(&ReasoningGrid::build, reasoningGrid, navKit->navp->navMesh, navKit);
buildAirgThread.detach();
}
imguiEndScrollArea();
}
Expand Down Expand Up @@ -164,7 +166,6 @@ void Airg::saveAirg(std::string fileName) {
std::ofstream fileOutputStream(s_OutputFileName);
reasoningGrid->writeJson(fileOutputStream);
fileOutputStream.close();
navKit->log(RC_LOG_PROGRESS, ("Finished saving Airg to " + std::string{fileName} + ".").c_str());
}

void Airg::loadAirg(Airg* airg, char* fileName, bool isFromJson) {
Expand Down
48 changes: 42 additions & 6 deletions src/Navp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Navp::Navp(NavKit* navKit): navKit(navKit) {
bBoxSizeX = 100.0;
bBoxSizeY = 100.0;
bBoxSizeZ = 100.0;
lastBBoxPosX = 0.0;
lastBBoxPosY = 0.0;
lastBBoxPosZ = 0.0;
lastBBoxSizeX = 100.0;
lastBBoxSizeY = 100.0;
lastBBoxSizeZ = 100.0;

stairsCheckboxValue = false;
loading = false;
Expand Down Expand Up @@ -267,12 +273,42 @@ void Navp::drawMenu() {
navKit->sample->handleCommonSettings();

bool bboxChanged = false;
bboxChanged |= imguiSlider("Bounding Box Origin X", &bBoxPosX, -300.0f, 300.0f, 1.0f);
bboxChanged |= imguiSlider("Bounding Box Origin Y", &bBoxPosY, -300.0f, 300.0f, 1.0f);
bboxChanged |= imguiSlider("Bounding Box Origin Z", &bBoxPosZ, -300.0f, 300.0f, 1.0f);
bboxChanged |= imguiSlider("Bounding Box Size X", &bBoxSizeX, 1.0f, 600.0f, 1.0f);
bboxChanged |= imguiSlider("Bounding Box Size Y", &bBoxSizeY, 1.0f, 600.0f, 1.0f);
bboxChanged |= imguiSlider("Bounding Box Size Z", &bBoxSizeZ, 1.0f, 600.0f, 1.0f);
if (imguiSlider("Bounding Box Origin X", &bBoxPosX, -300.0f, 300.0f, 1.0f)) {
if (lastBBoxPosX != bBoxPosX) {
bboxChanged = true;
lastBBoxPosX = bBoxPosX;
}
}
if (imguiSlider("Bounding Box Origin Y", &bBoxPosY, -300.0f, 300.0f, 1.0f)) {
if (lastBBoxPosY != bBoxPosY) {
bboxChanged = true;
lastBBoxPosY = bBoxPosY;
}
}
if (imguiSlider("Bounding Box Origin Z", &bBoxPosZ, -300.0f, 300.0f, 1.0f)) {
if (lastBBoxPosZ != bBoxPosZ) {
bboxChanged = true;
lastBBoxPosZ = bBoxPosZ;
}
}
if (imguiSlider("Bounding Box Size X", &bBoxSizeX, 1.0f, 600.0f, 1.0f)) {
if (lastBBoxSizeX != bBoxSizeX) {
bboxChanged = true;
lastBBoxSizeX = bBoxSizeX;
}
}
if (imguiSlider("Bounding Box Size Y", &bBoxSizeY, 1.0f, 600.0f, 1.0f)) {
if (lastBBoxSizeY != bBoxSizeY) {
bboxChanged = true;
lastBBoxSizeY = bBoxSizeY;
}
}
if (imguiSlider("Bounding Box Size Z", &bBoxSizeZ, 1.0f, 600.0f, 1.0f)) {
if (lastBBoxSizeZ != bBoxSizeZ) {
bboxChanged = true;
lastBBoxSizeZ = bBoxSizeZ;
}
}

if (bboxChanged)
{
Expand Down
114 changes: 83 additions & 31 deletions src/ReasoningGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,20 @@ int pnpoly(int nvert, float* vertx, float* verty, float testx, float testy)
return c;
}

void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
ctx->log(RC_LOG_PROGRESS, "Started building Airg.");
float calcZ(Vec3 p1, Vec3 p2, Vec3 p3, float x, float y) {
float dx1 = x - p1.X;
float dy1 = y - p1.Y;
float dx2 = p2.X - p1.X;
float dy2 = p2.Y - p1.Y;
float dx3 = p3.X - p1.X;
float dy3 = p3.Y - p1.Y;
return p1.Z + ((dy1 * dx3 - dx1 * dy3) * (p2.Z - p1.Z) + (dx1 * dy2 - dy1 * dx2) * (p3.Z - p1.Z)) / (dx3 * dy2 - dx2 * dy3);
}

void ReasoningGrid::build(ReasoningGrid* airg, NavPower::NavMesh* navMesh, NavKit* navKit) {
navKit->log(RC_LOG_PROGRESS, "Started building Airg.");
double spacing = 2;
double zSpacing = 1;
// grid is set up in this order: Z[Y[X[]]]
std::vector<std::vector<std::vector<int>>> grid;
Vec3 min = navMesh->m_graphHdr->m_bbox.m_min;
Expand All @@ -247,39 +258,78 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
Vec3 max = navMesh->m_graphHdr->m_bbox.m_max;
int gridXSize = std::ceil((max.X - min.X) / spacing);
int gridYSize = std::ceil((max.Y - min.Y) / spacing);
int gridZSize = 1;
m_Properties.fGridSpacing = spacing;
m_Properties.nGridWidth = gridYSize;
m_Properties.vMin.x = min.X;
m_Properties.vMin.y = min.Y;
m_Properties.vMin.z = min.Z;
m_Properties.vMin.w = 1;
m_Properties.vMax.x = max.X;
m_Properties.vMax.y = max.Y;
m_Properties.vMax.z = max.Z;
m_Properties.vMax.w = 1;
int gridZSize = std::ceil((max.Z - min.Z) / zSpacing);
gridZSize = gridZSize > 0 ? gridZSize : 1;
airg->m_Properties.fGridSpacing = spacing;
airg->m_Properties.nGridWidth = gridYSize;
airg->m_Properties.vMin.x = min.X;
airg->m_Properties.vMin.y = min.Y;
airg->m_Properties.vMin.z = min.Z;
airg->m_Properties.vMin.w = 1;
airg->m_Properties.vMax.x = max.X;
airg->m_Properties.vMax.y = max.Y;
airg->m_Properties.vMax.z = max.Z;
airg->m_Properties.vMax.w = 1;

std::vector<double> areaZMins;
std::vector<double> areaZMaxes;

for (auto area : navMesh->m_areas) {
const int areaPointCount = area.m_edges.size();
double areaMinZ = 1000;
double areaMaxZ = -1000;
double pointZ = 0;
for (int i = 0; i < areaPointCount; i++) {
pointZ = area.m_edges[i]->m_pos.Z;
areaMinZ = areaMinZ < pointZ ? areaMinZ : pointZ;
areaMaxZ = areaMaxZ > pointZ ? areaMaxZ : pointZ;
}
areaZMins.push_back(areaMinZ);
areaZMaxes.push_back(areaMaxZ);
}
std::vector<std::vector<int>> areasByZLevel;
for (int zi = 0; zi < gridZSize; zi++) {
std::vector<int> areasForZLevel;
for (int areaIndex = 0; areaIndex < navMesh->m_areas.size(); areaIndex++) {
double minZ = min.Z + zi * zSpacing;
double maxZ = min.Z + (zi + 1) * zSpacing;
if ((areaZMins[areaIndex] >= minZ && areaZMins[areaIndex] <= maxZ) ||
(areaZMaxes[areaIndex] >= minZ && areaZMaxes[areaIndex] <= maxZ) ||
(areaZMins[areaIndex] <= minZ && areaZMaxes[areaIndex] >= maxZ)) {
areasForZLevel.push_back(areaIndex);
}
}
areasByZLevel.push_back(areasForZLevel);
}

int wayPointIndex = 0;
for (int zi = 0; zi < gridZSize; zi++) {
std::vector<std::vector<int>> yRow;
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());
double minZ = min.Z + zi * zSpacing;
double maxZ = min.Z + (zi + 1) * zSpacing;
for (int yi = 0; yi < gridYSize; yi++) {
std::vector<int> xRow;
for (int xi = 0; xi < gridXSize; xi++) {
bool pointInArea = false;
double x = min.X + xi * spacing;
double y = min.Y + yi * spacing;
double z = min.Z + zi * spacing;
for (auto area : navMesh->m_areas) {
double z = min.Z + zi * zSpacing;
bool pointInArea = false;
for (int areaIndex : areasByZLevel[zi]) {
auto area = navMesh->m_areas[areaIndex];
const int areaPointCount = area.m_edges.size();
float areaXCoords[10];
float areaYCoords[10];
for (int i = 0; i < areaPointCount; i++) {
areaXCoords[i] = area.m_edges[i]->m_pos.X;
areaYCoords[i] = area.m_edges[i]->m_pos.Y;
}
pointInArea = pnpoly(areaPointCount, areaXCoords, areaYCoords, x, y);
if (pointInArea) {
break;
z = calcZ(area.m_edges[0]->m_pos, area.m_edges[1]->m_pos, area.m_edges[2]->m_pos, x, y) + 0.1;
if (z > (minZ - zSpacing * .8) && z < (maxZ + zSpacing * .8)) {
float areaXCoords[10];
float areaYCoords[10];
for (int i = 0; i < areaPointCount; i++) {
areaXCoords[i] = area.m_edges[i]->m_pos.X;
areaYCoords[i] = area.m_edges[i]->m_pos.Y;
}
pointInArea = pnpoly(areaPointCount, areaXCoords, areaYCoords, x, y);
if (pointInArea) {
break;
}
}
}
xRow.push_back(pointInArea ? wayPointIndex++ : 65535);
Expand All @@ -291,16 +341,16 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
waypoint.vPos.w = 1.0;
waypoint.nVisionDataOffset = 0;
waypoint.nLayerIndex = 0;
m_WaypointList.push_back(waypoint);
airg->m_WaypointList.push_back(waypoint);
}
}
yRow.push_back(xRow);
}
grid.push_back(yRow);
}

m_nNodeCount = m_WaypointList.size();
m_deadEndData.m_nSize = m_nNodeCount;
airg->m_nNodeCount = airg->m_WaypointList.size();
airg->m_deadEndData.m_nSize = airg->m_nNodeCount;
// Neighbors: South is 0, increases CCW
std::pair<int, int> gridIndexDiff[8]{
std::pair(0, -1),
Expand All @@ -326,12 +376,14 @@ void ReasoningGrid::build(NavPower::NavMesh* navMesh, BuildContext* ctx) {
nyi >= 0 && nyi < gridYSize) {
neighborWaypointIndex = grid[zi][nyi][nxi];
}
m_WaypointList[waypointIndex].nNeighbors.push_back(neighborWaypointIndex);
airg->m_WaypointList[waypointIndex].nNeighbors.push_back(neighborWaypointIndex);
}
}
}
}
}
std::vector<uint32_t> visibilityData(m_nNodeCount * 1001);
m_pVisibilityData = visibilityData;
std::vector<uint32_t> visibilityData(airg->m_nNodeCount * 1001);
airg->m_pVisibilityData = visibilityData;
navKit->log(RC_LOG_PROGRESS, "Done building Airg.");
navKit->airg->airgLoaded = true;
}
2 changes: 1 addition & 1 deletion src/RecastDemo/Sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void Sample::resetCommonSettings()
m_regionMergeSize = 30;
m_edgeMaxLen = 500.0f;
m_edgeMaxError = 1.4f;
m_vertsPerPoly = 6.0f;
m_vertsPerPoly = 3.0f;
m_detailSampleDist = 1.5f;
m_detailSampleMaxError = 1.4f;
m_partitionType = SAMPLE_PARTITION_WATERSHED;
Expand Down

0 comments on commit c57c958

Please sign in to comment.