mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
NavEditor cleanup
Moved functions and structures to their own files.
This commit is contained in:
parent
8aa71d6676
commit
e5f445e9c8
174
r5dev/naveditor/GameUtils.cpp
Normal file
174
r5dev/naveditor/GameUtils.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "NavEditor/include/GameUtils.h"
|
||||
#include "NavEditor/include/FileTypes.h"
|
||||
|
||||
void coordGameSwap(float* c)
|
||||
{
|
||||
std::swap(c[1], c[2]);
|
||||
c[2] *= -1;
|
||||
}
|
||||
void coordGameUnswap(float* c)
|
||||
{
|
||||
c[2] *= -1;
|
||||
std::swap(c[1], c[2]);
|
||||
}
|
||||
void coordShortGameSwap(unsigned short* c)
|
||||
{
|
||||
std::swap(c[1], c[2]);
|
||||
c[2] = std::numeric_limits<unsigned short>::max() - c[2];
|
||||
}
|
||||
void coordShortGameUnswap(unsigned short* c)
|
||||
{
|
||||
c[2] = std::numeric_limits<unsigned short>::max() - c[2];
|
||||
std::swap(c[1], c[2]);
|
||||
}
|
||||
void patchHeaderGame(NavMeshSetHeader& h)
|
||||
{
|
||||
coordGameSwap(h.params.orig);
|
||||
}
|
||||
void unpatchHeaderGame(NavMeshSetHeader& h)
|
||||
{
|
||||
coordGameUnswap(h.params.orig);
|
||||
}
|
||||
|
||||
void patchTileGame(dtMeshTile* t)
|
||||
{
|
||||
coordGameSwap(t->header->bmin);
|
||||
coordGameSwap(t->header->bmax);
|
||||
|
||||
for (size_t i = 0; i < t->header->vertCount * 3; i += 3)
|
||||
coordGameSwap(t->verts + i);
|
||||
for (size_t i = 0; i < t->header->detailVertCount * 3; i += 3)
|
||||
coordGameSwap(t->detailVerts + i);
|
||||
for (size_t i = 0; i < t->header->polyCount; i++)
|
||||
coordGameSwap(t->polys[i].org);
|
||||
//might be wrong because of coord change might break tree layout
|
||||
for (size_t i = 0; i < t->header->bvNodeCount; i++)
|
||||
{
|
||||
coordShortGameSwap(t->bvTree[i].bmax);
|
||||
coordShortGameSwap(t->bvTree[i].bmin);
|
||||
}
|
||||
for (size_t i = 0; i < t->header->offMeshConCount; i++)
|
||||
{
|
||||
coordGameSwap(t->offMeshCons[i].pos);
|
||||
coordGameSwap(t->offMeshCons[i].pos + 3);
|
||||
coordGameSwap(t->offMeshCons[i].unk);
|
||||
}
|
||||
}
|
||||
void unpatchTileGame(dtMeshTile* t)
|
||||
{
|
||||
coordGameUnswap(t->header->bmin);
|
||||
coordGameUnswap(t->header->bmax);
|
||||
|
||||
for (size_t i = 0; i < t->header->vertCount * 3; i += 3)
|
||||
coordGameUnswap(t->verts + i);
|
||||
for (size_t i = 0; i < t->header->detailVertCount * 3; i += 3)
|
||||
coordGameUnswap(t->detailVerts + i);
|
||||
for (size_t i = 0; i < t->header->polyCount; i++)
|
||||
coordGameUnswap(t->polys[i].org);
|
||||
//might be wrong because of coord change might break tree layout
|
||||
for (size_t i = 0; i < t->header->bvNodeCount; i++)
|
||||
{
|
||||
coordShortGameUnswap(t->bvTree[i].bmax);
|
||||
coordShortGameUnswap(t->bvTree[i].bmin);
|
||||
}
|
||||
for (size_t i = 0; i < t->header->offMeshConCount; i++)
|
||||
{
|
||||
coordGameUnswap(t->offMeshCons[i].pos);
|
||||
coordGameUnswap(t->offMeshCons[i].pos + 3);
|
||||
coordGameUnswap(t->offMeshCons[i].unk);
|
||||
}
|
||||
}
|
||||
|
||||
void buildLinkTable(dtNavMesh* mesh, LinkTableData& data)
|
||||
{
|
||||
//clear all labels
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
poly.disjointSetId = -1;
|
||||
}
|
||||
}
|
||||
//first pass
|
||||
std::set<int> nlabels;
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
auto plink = poly.firstLink;
|
||||
while (plink != DT_NULL_LINK)
|
||||
{
|
||||
auto l = tile->links[plink];
|
||||
const dtMeshTile* t;
|
||||
const dtPoly* p;
|
||||
mesh->getTileAndPolyByRefUnsafe(l.ref, &t, &p);
|
||||
|
||||
if (p->disjointSetId != (unsigned short)-1)
|
||||
nlabels.insert(p->disjointSetId);
|
||||
plink = l.next;
|
||||
}
|
||||
if (nlabels.empty())
|
||||
{
|
||||
poly.disjointSetId = data.insert_new();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto l = *nlabels.begin();
|
||||
poly.disjointSetId = l;
|
||||
for (auto nl : nlabels)
|
||||
data.set_union(l, nl);
|
||||
}
|
||||
nlabels.clear();
|
||||
}
|
||||
}
|
||||
//second pass
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
auto id = data.find(poly.disjointSetId);
|
||||
poly.disjointSetId = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
void setReachable(std::vector<int>& data, int count, int id1, int id2, bool value)
|
||||
{
|
||||
int w = ((count + 31) / 32);
|
||||
auto& cell = data[id1 * w + id2 / 32];
|
||||
uint32_t value_mask = ~(1 << (id2 & 0x1f));
|
||||
if (!value)
|
||||
cell = (cell & value_mask);
|
||||
else
|
||||
cell = (cell & value_mask) | (1 << (id2 & 0x1f));
|
||||
}
|
@ -23,8 +23,10 @@
|
||||
#include "DetourCrowd/Include/DetourCrowd.h"
|
||||
#include "DebugUtils/Include/RecastDebugDraw.h"
|
||||
#include "DebugUtils/Include/DetourDebugDraw.h"
|
||||
#include "NavEditor/Include/Sample.h"
|
||||
#include "NavEditor/Include/FileTypes.h"
|
||||
#include "NavEditor/Include/GameUtils.h"
|
||||
#include "NavEditor/Include/InputGeom.h"
|
||||
#include "NavEditor/Include/Sample.h"
|
||||
|
||||
unsigned int SampleDebugDraw::areaToCol(unsigned int area)
|
||||
{
|
||||
@ -330,222 +332,8 @@ void Sample::renderOverlayToolStates(double* proj, double* model, int* view)
|
||||
}
|
||||
}
|
||||
|
||||
static const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET';
|
||||
static const int NAVMESHSET_VERSION = 8;
|
||||
|
||||
struct NavMeshSetHeader
|
||||
{
|
||||
int magic;
|
||||
int version;
|
||||
int numTiles;
|
||||
dtNavMeshParams params;
|
||||
};
|
||||
|
||||
struct NavMeshTileHeader
|
||||
{
|
||||
dtTileRef tileRef;
|
||||
int dataSize;
|
||||
};
|
||||
|
||||
void coord_tf_fix(float* c)
|
||||
{
|
||||
std::swap(c[1], c[2]);
|
||||
c[2] *= -1;
|
||||
}
|
||||
void coord_tf_unfix(float* c)
|
||||
{
|
||||
c[2] *= -1;
|
||||
std::swap(c[1], c[2]);
|
||||
}
|
||||
void coord_short_tf_fix(unsigned short* c)
|
||||
{
|
||||
std::swap(c[1], c[2]);
|
||||
c[2] = std::numeric_limits<unsigned short>::max() - c[2];
|
||||
}
|
||||
void coord_short_tf_unfix(unsigned short* c)
|
||||
{
|
||||
c[2] = std::numeric_limits<unsigned short>::max() - c[2];
|
||||
std::swap(c[1], c[2]);
|
||||
}
|
||||
void patch_headertf2(NavMeshSetHeader& h)
|
||||
{
|
||||
coord_tf_fix(h.params.orig);
|
||||
}
|
||||
void unpatch_headertf2(NavMeshSetHeader& h)
|
||||
{
|
||||
coord_tf_unfix(h.params.orig);
|
||||
}
|
||||
|
||||
void patch_tiletf2(dtMeshTile* t)
|
||||
{
|
||||
coord_tf_fix(t->header->bmin);
|
||||
coord_tf_fix(t->header->bmax);
|
||||
|
||||
for (size_t i = 0; i < t->header->vertCount * 3; i += 3)
|
||||
coord_tf_fix(t->verts + i);
|
||||
for (size_t i = 0; i < t->header->detailVertCount * 3; i += 3)
|
||||
coord_tf_fix(t->detailVerts + i);
|
||||
for (size_t i = 0; i < t->header->polyCount; i++)
|
||||
coord_tf_fix(t->polys[i].org);
|
||||
//might be wrong because of coord change might break tree layout
|
||||
for (size_t i = 0; i < t->header->bvNodeCount; i++)
|
||||
{
|
||||
coord_short_tf_fix(t->bvTree[i].bmax);
|
||||
coord_short_tf_fix(t->bvTree[i].bmin);
|
||||
}
|
||||
for (size_t i = 0; i < t->header->offMeshConCount; i++)
|
||||
{
|
||||
coord_tf_fix(t->offMeshCons[i].pos);
|
||||
coord_tf_fix(t->offMeshCons[i].pos + 3);
|
||||
coord_tf_fix(t->offMeshCons[i].unk);
|
||||
}
|
||||
}
|
||||
void unpatch_tiletf2(dtMeshTile* t)
|
||||
{
|
||||
coord_tf_unfix(t->header->bmin);
|
||||
coord_tf_unfix(t->header->bmax);
|
||||
|
||||
for (size_t i = 0; i < t->header->vertCount * 3; i += 3)
|
||||
coord_tf_unfix(t->verts + i);
|
||||
for (size_t i = 0; i < t->header->detailVertCount * 3; i += 3)
|
||||
coord_tf_unfix(t->detailVerts + i);
|
||||
for (size_t i = 0; i < t->header->polyCount; i++)
|
||||
coord_tf_unfix(t->polys[i].org);
|
||||
//might be wrong because of coord change might break tree layout
|
||||
for (size_t i = 0; i < t->header->bvNodeCount; i++)
|
||||
{
|
||||
coord_short_tf_unfix(t->bvTree[i].bmax);
|
||||
coord_short_tf_unfix(t->bvTree[i].bmin);
|
||||
}
|
||||
for (size_t i = 0; i < t->header->offMeshConCount; i++)
|
||||
{
|
||||
coord_tf_unfix(t->offMeshCons[i].pos);
|
||||
coord_tf_unfix(t->offMeshCons[i].pos+3);
|
||||
coord_tf_unfix(t->offMeshCons[i].unk);
|
||||
}
|
||||
}
|
||||
struct LinkTableData
|
||||
{
|
||||
//disjoint set algo from some crappy site because i'm too lazy to think
|
||||
int setCount = 0;
|
||||
std::vector<int> rank;
|
||||
std::vector<int> parent;
|
||||
void init(int size)
|
||||
{
|
||||
rank.resize(size);
|
||||
parent.resize(size);
|
||||
|
||||
for (int i = 0; i < parent.size(); i++)
|
||||
parent[i] = i;
|
||||
}
|
||||
int insert_new()
|
||||
{
|
||||
rank.push_back(0);
|
||||
parent.push_back(setCount);
|
||||
return setCount++;
|
||||
}
|
||||
int find(int id)
|
||||
{
|
||||
if (parent[id] != id)
|
||||
return find(parent[id]);
|
||||
return id;
|
||||
}
|
||||
void set_union(int x, int y)
|
||||
{
|
||||
int sx = find(x);
|
||||
int sy = find(y);
|
||||
if (sx == sy) //same set already
|
||||
return;
|
||||
|
||||
if (rank[sx] < rank[sy])
|
||||
parent[sx] = sy;
|
||||
else if (rank[sx] > rank[sy])
|
||||
parent[sy] = sx;
|
||||
else
|
||||
{
|
||||
parent[sy] = sx;
|
||||
rank[sx] += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
void build_link_table(dtNavMesh* mesh, LinkTableData& data)
|
||||
{
|
||||
//clear all labels
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
poly.disjointSetId = -1;
|
||||
}
|
||||
}
|
||||
//first pass
|
||||
std::set<int> nlabels;
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
auto plink = poly.firstLink;
|
||||
while (plink != DT_NULL_LINK)
|
||||
{
|
||||
auto l = tile->links[plink];
|
||||
const dtMeshTile* t;
|
||||
const dtPoly* p;
|
||||
mesh->getTileAndPolyByRefUnsafe(l.ref, &t, &p);
|
||||
|
||||
if (p->disjointSetId != (unsigned short)-1)
|
||||
nlabels.insert(p->disjointSetId);
|
||||
plink = l.next;
|
||||
}
|
||||
if (nlabels.empty())
|
||||
{
|
||||
poly.disjointSetId = data.insert_new();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto l = *nlabels.begin();
|
||||
poly.disjointSetId = l;
|
||||
for (auto nl : nlabels)
|
||||
data.set_union(l, nl);
|
||||
}
|
||||
nlabels.clear();
|
||||
}
|
||||
}
|
||||
//second pass
|
||||
for (int i = 0; i < mesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||
auto pcount = tile->header->polyCount;
|
||||
for (int j = 0; j < pcount; j++)
|
||||
{
|
||||
auto& poly = tile->polys[j];
|
||||
auto id = data.find(poly.disjointSetId);
|
||||
poly.disjointSetId = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
void set_reachable(std::vector<int>& data, int count, int id1, int id2, bool value)
|
||||
{
|
||||
int w = ((count + 31) / 32);
|
||||
auto& cell = data[id1 * w + id2 / 32];
|
||||
uint32_t value_mask = ~(1 << (id2 & 0x1f));
|
||||
if (!value)
|
||||
cell = (cell & value_mask);
|
||||
else
|
||||
cell = (cell & value_mask) | (1 << (id2 & 0x1f));
|
||||
}
|
||||
|
||||
dtNavMesh* Sample::loadAll(const char* path)
|
||||
{
|
||||
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%s_%s.nm", path, m_navmeshName);
|
||||
|
||||
@ -577,7 +365,7 @@ dtNavMesh* Sample::loadAll(const char* path)
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
if(*is_tf2) patch_headertf2(header);
|
||||
if(*is_tf2) patchHeaderGame(header);
|
||||
dtStatus status = mesh->init(&header.params);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
@ -612,7 +400,7 @@ dtNavMesh* Sample::loadAll(const char* path)
|
||||
dtTileRef result;
|
||||
mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, &result);
|
||||
auto tile = const_cast<dtMeshTile*>(mesh->getTileByRef(result));
|
||||
if (*is_tf2) patch_tiletf2(tile);
|
||||
if (*is_tf2) patchTileGame(tile);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
@ -652,13 +440,13 @@ void Sample::saveAll(std::string path, dtNavMesh* mesh)
|
||||
}
|
||||
memcpy(&header.params, mesh->getParams(), sizeof(dtNavMeshParams));
|
||||
|
||||
//LinkTableData link_data;
|
||||
//build_link_table(mesh, link_data);
|
||||
//int table_size = ((link_data.setCount + 31) / 32) * link_data.setCount * 32;
|
||||
//LinkTableData linkData;
|
||||
//buildLinkTable(mesh, linkData);
|
||||
//int tableSize = ((linkData.setCount + 31) / 32) * linkData.setCount * 32;
|
||||
|
||||
//std::vector<int> reachability(table_size, 0);
|
||||
//for (int i = 0; i < link_data.setCount; i++)
|
||||
// set_reachable(reachability, link_data.setCount, i, i, true);
|
||||
//std::vector<int> reachability(tableSize, 0);
|
||||
//for (int i = 0; i < linkData.setCount; i++)
|
||||
// setReachable(reachability, linkData.setCount, i, i, true);
|
||||
|
||||
//if (reachability.size() > 0)
|
||||
//{
|
||||
@ -667,22 +455,22 @@ void Sample::saveAll(std::string path, dtNavMesh* mesh)
|
||||
// if (reachability[i] == 0)
|
||||
// {
|
||||
// reachability.erase(reachability.begin() + i);
|
||||
// table_size--;
|
||||
// tableSize--;
|
||||
// }
|
||||
// else
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//header.params.disjointPolyGroupCount = link_data.setCount;
|
||||
//header.params.disjointPolyGroupCount = linkData.setCount;
|
||||
//header.params.reachabilityTableCount = m_reachabilityTableCount;
|
||||
//header.params.reachabilityTableSize = table_size;
|
||||
//header.params.reachabilityTableSize = tableSize;
|
||||
|
||||
header.params.disjointPolyGroupCount = 4;
|
||||
header.params.reachabilityTableCount = m_reachabilityTableCount;
|
||||
header.params.reachabilityTableSize = ((header.params.disjointPolyGroupCount + 31) / 32) * header.params.disjointPolyGroupCount * 32;
|
||||
|
||||
if (*is_tf2)unpatch_headertf2(header);
|
||||
if (*is_tf2)unpatchHeaderGame(header);
|
||||
fwrite(&header, sizeof(NavMeshSetHeader), 1, fp);
|
||||
|
||||
// Store tiles.
|
||||
@ -696,18 +484,18 @@ void Sample::saveAll(std::string path, dtNavMesh* mesh)
|
||||
tileHeader.dataSize = tile->dataSize;
|
||||
fwrite(&tileHeader, sizeof(tileHeader), 1, fp);
|
||||
|
||||
if (*is_tf2)unpatch_tiletf2(const_cast<dtMeshTile*>(tile));
|
||||
if (*is_tf2)unpatchTileGame(const_cast<dtMeshTile*>(tile));
|
||||
fwrite(tile->data, tile->dataSize, 1, fp);
|
||||
if (*is_tf2)patch_tiletf2(const_cast<dtMeshTile*>(tile));
|
||||
if (*is_tf2)patchTileGame(const_cast<dtMeshTile*>(tile));
|
||||
}
|
||||
|
||||
////still dont know what this thing is...
|
||||
//int header_sth = 0;
|
||||
//for (int i = 0; i < link_data.setCount; i++)
|
||||
//for (int i = 0; i < linkData.setCount; i++)
|
||||
// fwrite(&header_sth, sizeof(int), 1, fp);
|
||||
|
||||
//for (int i = 0; i < header.params.reachabilityTableCount; i++)
|
||||
// fwrite(reachability.data(), sizeof(int), table_size, fp);
|
||||
// fwrite(reachability.data(), sizeof(int), tableSize, fp);
|
||||
|
||||
int header_sth[4] = { 0,0,0 };
|
||||
fwrite(header_sth, sizeof(int), 4, fp);
|
||||
|
67
r5dev/naveditor/include/FileTypes.h
Normal file
67
r5dev/naveditor/include/FileTypes.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef FILETYPES_H
|
||||
#define FILETYPES_H
|
||||
#include "Detour/Include/DetourNavMesh.h"
|
||||
|
||||
static const int NAVMESHSET_MAGIC = 'M' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'MSET';
|
||||
static const int NAVMESHSET_VERSION = 8;
|
||||
|
||||
struct NavMeshSetHeader
|
||||
{
|
||||
int magic;
|
||||
int version;
|
||||
int numTiles;
|
||||
dtNavMeshParams params;
|
||||
};
|
||||
|
||||
struct NavMeshTileHeader
|
||||
{
|
||||
dtTileRef tileRef;
|
||||
int dataSize;
|
||||
};
|
||||
|
||||
struct LinkTableData
|
||||
{
|
||||
//disjoint set algo from some crappy site because i'm too lazy to think
|
||||
int setCount = 0;
|
||||
std::vector<int> rank;
|
||||
std::vector<int> parent;
|
||||
void init(int size)
|
||||
{
|
||||
rank.resize(size);
|
||||
parent.resize(size);
|
||||
|
||||
for (int i = 0; i < parent.size(); i++)
|
||||
parent[i] = i;
|
||||
}
|
||||
int insert_new()
|
||||
{
|
||||
rank.push_back(0);
|
||||
parent.push_back(setCount);
|
||||
return setCount++;
|
||||
}
|
||||
int find(int id)
|
||||
{
|
||||
if (parent[id] != id)
|
||||
return find(parent[id]);
|
||||
return id;
|
||||
}
|
||||
void set_union(int x, int y)
|
||||
{
|
||||
int sx = find(x);
|
||||
int sy = find(y);
|
||||
if (sx == sy) //same set already
|
||||
return;
|
||||
|
||||
if (rank[sx] < rank[sy])
|
||||
parent[sx] = sy;
|
||||
else if (rank[sx] > rank[sy])
|
||||
parent[sy] = sx;
|
||||
else
|
||||
{
|
||||
parent[sy] = sx;
|
||||
rank[sx] += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // FILETYPES_H
|
20
r5dev/naveditor/include/GameUtils.h
Normal file
20
r5dev/naveditor/include/GameUtils.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef GAMEUTILS_H
|
||||
#define GAMEUTILS_H
|
||||
#include "NavEditor/Include/FileTypes.h"
|
||||
|
||||
void coordGameSwap(float* c);
|
||||
void coordGameUnswap(float* c);
|
||||
|
||||
void coordShortGameSwap(unsigned short* c);
|
||||
void coordShortGameUnswap(unsigned short* c);
|
||||
|
||||
void patchHeaderGame(NavMeshSetHeader& h);
|
||||
void unpatchHeaderGame(NavMeshSetHeader& h);
|
||||
|
||||
void patchTileGame(dtMeshTile* t);
|
||||
void unpatchTileGame(dtMeshTile* t);
|
||||
|
||||
void buildLinkTable(dtNavMesh* mesh, LinkTableData& data);
|
||||
void setReachable(std::vector<int>& data, int count, int id1, int id2, bool value);
|
||||
|
||||
#endif // GAMEUTILS_H
|
@ -34,8 +34,8 @@ public:
|
||||
virtual int getTriCount() const = 0;
|
||||
virtual const std::string& getFileName() const = 0;
|
||||
|
||||
bool m_tf2_import_flip = false; // !TODO: ImGui import option.
|
||||
bool m_flip_tris = false; // !TODO: ImGui import option.
|
||||
bool m_flipAxis = false; // !TODO: ImGui import option.
|
||||
bool m_flipTris = false; // !TODO: ImGui import option.
|
||||
};
|
||||
class rcMeshLoaderObj:public IMeshLoader
|
||||
{
|
||||
@ -67,8 +67,6 @@ private:
|
||||
float* m_normals;
|
||||
int m_vertCount;
|
||||
int m_triCount;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MESHLOADER_OBJ
|
||||
|
@ -15,6 +15,8 @@
|
||||
<ClInclude Include="..\naveditor\include\ConvexVolumeTool.h" />
|
||||
<ClInclude Include="..\naveditor\include\CrowdTool.h" />
|
||||
<ClInclude Include="..\naveditor\include\Filelist.h" />
|
||||
<ClInclude Include="..\naveditor\include\FileTypes.h" />
|
||||
<ClInclude Include="..\naveditor\include\GameUtils.h" />
|
||||
<ClInclude Include="..\naveditor\include\imgui.h" />
|
||||
<ClInclude Include="..\naveditor\include\imguiRenderGL.h" />
|
||||
<ClInclude Include="..\naveditor\include\InputGeom.h" />
|
||||
@ -41,6 +43,7 @@
|
||||
<ClCompile Include="..\naveditor\ConvexVolumeTool.cpp" />
|
||||
<ClCompile Include="..\naveditor\CrowdTool.cpp" />
|
||||
<ClCompile Include="..\naveditor\Filelist.cpp" />
|
||||
<ClCompile Include="..\naveditor\GameUtils.cpp" />
|
||||
<ClCompile Include="..\naveditor\imgui.cpp" />
|
||||
<ClCompile Include="..\naveditor\imguiRenderGL.cpp" />
|
||||
<ClCompile Include="..\naveditor\InputGeom.cpp" />
|
||||
|
@ -111,6 +111,12 @@
|
||||
<ClInclude Include="..\thirdparty\recast\Pch.h">
|
||||
<Filter>core\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\naveditor\include\GameUtils.h">
|
||||
<Filter>utils\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\naveditor\include\FileTypes.h">
|
||||
<Filter>io\include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\thirdparty\fastlz\fastlz.c">
|
||||
@ -188,5 +194,8 @@
|
||||
<ClCompile Include="..\thirdparty\recast\Pch.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\naveditor\GameUtils.cpp">
|
||||
<Filter>utils</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user