mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: tilemesh editor refactor
Move common code to Editor_Common and fix solomesh. Solomesh is useful for debugging recast as it allows for generating everything in 1 tile. Also did numerous fixes for the tilecache code, though this is still broken and won't be really used for the r5sdk project, but its nice to have for a potential project outside r5sdk that uses the xyz coordination system, which avoids having to run the navmesh through a conversion pass in runtime.
This commit is contained in:
parent
59a8f12e0e
commit
f95eb13ab3
@ -4,11 +4,15 @@ add_module( "exe" "recast" "" ${FOLDER_CONTEXT} TRUE TRUE )
|
||||
start_sources()
|
||||
|
||||
add_sources( SOURCE_GROUP "Builder"
|
||||
"Editor_Common.cpp"
|
||||
"Editor_SoloMesh.cpp"
|
||||
"Editor_TileMesh.cpp"
|
||||
"InputGeom.cpp"
|
||||
)
|
||||
|
||||
add_sources( SOURCE_GROUP "Builder/Include"
|
||||
"Include/Editor_Common.h"
|
||||
"Include/Editor_SoloMesh.h"
|
||||
"include/Editor_TileMesh.h"
|
||||
"include/InputGeom.h"
|
||||
)
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "NavEditor/Include/InputGeom.h"
|
||||
#include "NavEditor/Include/Editor.h"
|
||||
|
||||
#include "game/server/ai_navmesh.h"
|
||||
#include "game/server/ai_hull.h"
|
||||
|
||||
unsigned int EditorDebugDraw::areaToCol(unsigned int area)
|
||||
{
|
||||
switch(area)
|
||||
@ -170,12 +173,11 @@ void Editor::collectSettings(BuildSettings& settings)
|
||||
|
||||
void Editor::resetCommonSettings()
|
||||
{
|
||||
selectNavMeshType(NAVMESH_SMALL);
|
||||
|
||||
m_cellSize = 16.0f;
|
||||
m_cellHeight = 5.85f;
|
||||
m_agentHeight = 2.0f;
|
||||
m_agentRadius = 0.6f;
|
||||
m_agentMaxClimb = 0.9f;
|
||||
m_agentMaxSlope = 45.0f;
|
||||
m_agentMaxSlope = 45.0f; // todo(amos) put into hull def!
|
||||
m_regionMinSize = 8;
|
||||
m_regionMergeSize = 20;
|
||||
m_edgeMaxLen = 12;
|
||||
@ -187,6 +189,19 @@ void Editor::resetCommonSettings()
|
||||
}
|
||||
void Editor::handleCommonSettings()
|
||||
{
|
||||
ImGui::Text("NavMesh Type");
|
||||
for (int i = 0; i < NAVMESH_COUNT; i++)
|
||||
{
|
||||
const NavMeshType_e navMeshType = NavMeshType_e(i);
|
||||
|
||||
if (ImGui::Button(NavMesh_GetNameForType(navMeshType), ImVec2(120, 0)))
|
||||
{
|
||||
selectNavMeshType(navMeshType);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushItemWidth(180.f);
|
||||
ImGui::Text("Rasterization");
|
||||
|
||||
@ -339,6 +354,97 @@ void Editor::renderOverlayToolStates(double* proj, double* model, int* view)
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::renderNavMeshDebugMenu()
|
||||
{
|
||||
ImGui::Text("NavMesh Render Options");
|
||||
|
||||
bool isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (ImGui::Checkbox("Off-Mesh Connections", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NODES);
|
||||
|
||||
if (ImGui::Checkbox("Query Nodes", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NODES);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_BVTREE);
|
||||
|
||||
if (ImGui::Checkbox("BVTree", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_BVTREE);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_PORTALS);
|
||||
|
||||
if (ImGui::Checkbox("Portals", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_PORTALS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
if (ImGui::Checkbox("Closed List", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
if (ImGui::Checkbox("Tile ID Colors", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
if (ImGui::Checkbox("Vertex Points", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Inner Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Outer Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
if (ImGui::Checkbox("Poly Centers", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
if (ImGui::Checkbox("Poly Group Colors", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_DEPTH_MASK);
|
||||
|
||||
if (ImGui::Checkbox("Depth Mask", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_DEPTH_MASK);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_ALPHA);
|
||||
|
||||
if (ImGui::Checkbox("Transparency", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_ALPHA);
|
||||
}
|
||||
|
||||
const hulldef hulls[NAVMESH_COUNT] = {
|
||||
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32 },
|
||||
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64 },
|
||||
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64 },
|
||||
};
|
||||
|
||||
void Editor::selectNavMeshType(const NavMeshType_e navMeshType)
|
||||
{
|
||||
const hulldef& h = hulls[navMeshType];
|
||||
|
||||
m_agentRadius = h.radius;
|
||||
m_agentMaxClimb = h.climbHeight;
|
||||
m_agentHeight = h.height;
|
||||
m_navmeshName = h.name;
|
||||
m_tileSize = h.tileSize;
|
||||
|
||||
m_selectedNavMeshType = navMeshType;
|
||||
}
|
||||
|
||||
dtNavMesh* Editor::loadAll(std::string path)
|
||||
{
|
||||
fs::path p = "..\\maps\\navmesh\\";
|
||||
@ -362,12 +468,12 @@ dtNavMesh* Editor::loadAll(std::string path)
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
if (header.magic != NAVMESHSET_MAGIC)
|
||||
if (header.magic != NAVMESHSET_MAGIC) // todo(amos) check for tool mode since tilecache uses different constants!
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
if (header.version != NAVMESHSET_VERSION)
|
||||
if (header.version != NAVMESHSET_VERSION) // todo(amos) check for tool mode since tilecache uses different constants!
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
593
src/naveditor/Editor_Common.cpp
Normal file
593
src/naveditor/Editor_Common.cpp
Normal file
@ -0,0 +1,593 @@
|
||||
//
|
||||
// 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 "Shared/Include/SharedAssert.h"
|
||||
#include "Include/Editor.h"
|
||||
#include "Include/Editor_Common.h"
|
||||
#include "DebugUtils/Include/RecastDebugDraw.h"
|
||||
#include "DebugUtils/Include/DetourDebugDraw.h"
|
||||
#include "Include/InputGeom.h"
|
||||
#include <DetourTileCache/Include/DetourTileCache.h>
|
||||
|
||||
// todo(amos): move these to common math.
|
||||
inline unsigned int nextPow2(unsigned int v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
// todo(amos): move these to common math.
|
||||
inline unsigned int ilog2(unsigned int v)
|
||||
{
|
||||
unsigned int r;
|
||||
unsigned int shift;
|
||||
r = (v > 0xffff) << 4; v >>= r;
|
||||
shift = (v > 0xff) << 3; v >>= shift; r |= shift;
|
||||
shift = (v > 0xf) << 2; v >>= shift; r |= shift;
|
||||
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
|
||||
r |= (v >> 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void EditorCommon_DrawInputGeometry(duDebugDraw* const dd, const InputGeom* const geom,
|
||||
const float maxSlope, const float textureScale)
|
||||
{
|
||||
duDebugDrawTriMeshSlope(dd, geom->getMesh()->getVerts(), geom->getMesh()->getVertCount(),
|
||||
geom->getMesh()->getTris(), geom->getMesh()->getNormals(), geom->getMesh()->getTriCount(),
|
||||
maxSlope, textureScale);
|
||||
}
|
||||
|
||||
static void EditorCommon_DrawBoundingBox(duDebugDraw* const dd, const InputGeom* const geom)
|
||||
{
|
||||
// Draw bounds
|
||||
const float* const bmin = geom->getNavMeshBoundsMin();
|
||||
const float* const bmax = geom->getNavMeshBoundsMax();
|
||||
duDebugDrawBoxWire(dd, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], duRGBA(255, 255, 255, 128), 1.0f);
|
||||
}
|
||||
|
||||
static void EditorCommon_DrawTilingGrid(duDebugDraw* const dd, const InputGeom* const geom, const int tileSize, const float cellSize)
|
||||
{
|
||||
const float* const bmin = geom->getNavMeshBoundsMin();
|
||||
const float* const bmax = geom->getNavMeshBoundsMax();
|
||||
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, cellSize, &gw, &gh);
|
||||
|
||||
const int tw = (gw + tileSize - 1) / tileSize;
|
||||
const int th = (gh + tileSize - 1) / tileSize;
|
||||
const float s = tileSize * cellSize;
|
||||
|
||||
duDebugDrawGridXY(dd, bmax[0], bmin[1], bmin[2], tw, th, s, duRGBA(0, 0, 0, 64), 1.0f);
|
||||
}
|
||||
|
||||
int EditorCommon_SetAndRenderTileProperties(const InputGeom* const geom, const int tileSize,
|
||||
const float cellSize, int& maxTiles, int& maxPolysPerTile)
|
||||
{
|
||||
int gridSize = 1;
|
||||
|
||||
if (geom)
|
||||
{
|
||||
int gw = 0, gh = 0;
|
||||
const float* bmin = geom->getNavMeshBoundsMin();
|
||||
const float* bmax = geom->getNavMeshBoundsMax();
|
||||
rcCalcGridSize(bmin, bmax, cellSize, &gw, &gh);
|
||||
const int ts = tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
|
||||
ImGui::Text("Tiles: %d x %d", tw, th);
|
||||
ImGui::Text("Tile Sizes: %g x %g (%g)", tw* cellSize, th*cellSize, tileSize*cellSize);
|
||||
|
||||
// Max tiles and max polys affect how the tile IDs are calculated.
|
||||
// There are 28 bits available for identifying a tile and a polygon.
|
||||
int tileBits = rcMin((int)ilog2(nextPow2(tw*th)), 16);
|
||||
int polyBits = 28 - tileBits;
|
||||
|
||||
maxTiles = 1 << tileBits;
|
||||
maxPolysPerTile = 1 << polyBits;
|
||||
|
||||
gridSize = tw*th;
|
||||
|
||||
ImGui::Text("Max Tiles: %d", maxTiles);
|
||||
ImGui::Text("Max Polys: %d", maxPolysPerTile);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxTiles = 0;
|
||||
maxPolysPerTile = 0;
|
||||
gridSize = 1;
|
||||
}
|
||||
|
||||
return gridSize;
|
||||
}
|
||||
|
||||
Editor_StaticTileMeshCommon::Editor_StaticTileMeshCommon()
|
||||
: m_triareas(nullptr)
|
||||
, m_solid(nullptr)
|
||||
, m_chf(nullptr)
|
||||
, m_cset(nullptr)
|
||||
, m_pmesh(nullptr)
|
||||
, m_dmesh(nullptr)
|
||||
, m_tileMeshDrawFlags(TM_DRAWFLAGS_INPUT_MESH|TM_DRAWFLAGS_NAVMESH)
|
||||
, m_tileCol(duRGBA(0, 0, 0, 32))
|
||||
, m_totalBuildTimeMs(0.0f)
|
||||
, m_drawActiveTile(false)
|
||||
, m_keepInterResults(false)
|
||||
{
|
||||
m_lastBuiltTileBmin[0] = 0.0f;
|
||||
m_lastBuiltTileBmin[1] = 0.0f;
|
||||
m_lastBuiltTileBmin[2] = 0.0f;
|
||||
|
||||
m_lastBuiltTileBmax[0] = 0.0f;
|
||||
m_lastBuiltTileBmax[1] = 0.0f;
|
||||
m_lastBuiltTileBmax[2] = 0.0f;
|
||||
|
||||
memset(&m_cfg, 0, sizeof(rcConfig));
|
||||
}
|
||||
|
||||
void Editor_StaticTileMeshCommon::cleanup()
|
||||
{
|
||||
delete[] m_triareas;
|
||||
m_triareas = 0;
|
||||
rcFreeHeightField(m_solid);
|
||||
m_solid = 0;
|
||||
rcFreeCompactHeightfield(m_chf);
|
||||
m_chf = 0;
|
||||
rcFreeContourSet(m_cset);
|
||||
m_cset = 0;
|
||||
rcFreePolyMesh(m_pmesh);
|
||||
m_pmesh = 0;
|
||||
rcFreePolyMeshDetail(m_dmesh);
|
||||
m_dmesh = 0;
|
||||
}
|
||||
|
||||
void Editor_StaticTileMeshCommon::renderTileMeshRenderOptions()
|
||||
{
|
||||
ImGui::Text("TileMesh Render Options");
|
||||
|
||||
bool isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_INPUT_MESH;
|
||||
|
||||
// This should always be available, since if we load a large mesh we want to
|
||||
// be able to toggle this off to save on performance. The renderer has to be
|
||||
// moved to its own thread to solve this issue.
|
||||
if (ImGui::Checkbox("Input Mesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_INPUT_MESH);
|
||||
|
||||
// Check which modes are valid.
|
||||
//const bool hasNavMesh =m_navMesh != 0;
|
||||
const bool hasChf = m_chf != 0;
|
||||
const bool hasCset = m_cset != 0;
|
||||
const bool hasSolid = m_solid != 0;
|
||||
const bool hasDMesh = m_dmesh != 0;
|
||||
|
||||
const bool intermediateDataUnavailable = !hasChf || !hasCset || !hasSolid || !hasDMesh;
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_NAVMESH;
|
||||
//ImGui::BeginDisabled(!hasNavMesh);
|
||||
|
||||
if (ImGui::Checkbox("NavMesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_NAVMESH);
|
||||
|
||||
//ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_VOXELS;
|
||||
ImGui::BeginDisabled(!hasSolid);
|
||||
|
||||
if (ImGui::Checkbox("Voxels", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_VOXELS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_VOXELS_WALKABLE;
|
||||
ImGui::BeginDisabled(!hasSolid);
|
||||
|
||||
if (ImGui::Checkbox("Walkable Voxels", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_VOXELS_WALKABLE);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT_DISTANCE;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact Distance", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT_DISTANCE);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT_REGIONS;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact Regions", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT_REGIONS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_REGION_CONNECTIONS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Region Connections", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_REGION_CONNECTIONS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_RAW_CONTOURS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Raw Contours", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_RAW_CONTOURS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_CONTOURS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Contours", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_CONTOURS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_POLYMESH;
|
||||
ImGui::BeginDisabled(!hasDMesh);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_POLYMESH);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_POLYMESH_DETAIL;
|
||||
ImGui::BeginDisabled(!hasDMesh);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh Detail", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_POLYMESH_DETAIL);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (intermediateDataUnavailable)
|
||||
{
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Tick 'Keep Intermediate Results'");
|
||||
ImGui::Text("rebuild some tiles to see");
|
||||
ImGui::Text("more debug mode options.");
|
||||
}
|
||||
}
|
||||
|
||||
void Editor_StaticTileMeshCommon::renderTileMeshData()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
|
||||
// Draw input mesh
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_INPUT_MESH)
|
||||
EditorCommon_DrawInputGeometry(&m_dd, m_geom, m_agentMaxSlope, texScale);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// Draw bounds
|
||||
EditorCommon_DrawBoundingBox(&m_dd, m_geom);
|
||||
|
||||
// Tiling grid.
|
||||
EditorCommon_DrawTilingGrid(&m_dd, m_geom, m_tileSize, m_cellSize);
|
||||
|
||||
if (m_drawActiveTile)
|
||||
{
|
||||
// Draw active tile
|
||||
duDebugDrawBoxWire(&m_dd, m_lastBuiltTileBmin[0], m_lastBuiltTileBmin[1], m_lastBuiltTileBmin[2],
|
||||
m_lastBuiltTileBmax[0], m_lastBuiltTileBmax[1], m_lastBuiltTileBmax[2], m_tileCol, 1.0f);
|
||||
}
|
||||
|
||||
if (m_navMesh && m_navQuery)
|
||||
{
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_NAVMESH)
|
||||
{
|
||||
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
|
||||
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, duRGBA(0, 0, 0, 128));
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (m_chf)
|
||||
{
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT)
|
||||
duDebugDrawCompactHeightfieldSolid(&m_dd, *m_chf);
|
||||
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT_DISTANCE)
|
||||
duDebugDrawCompactHeightfieldDistance(&m_dd, *m_chf);
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_COMPACT_REGIONS)
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
}
|
||||
|
||||
if (m_solid)
|
||||
{
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_VOXELS)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldSolid(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_VOXELS_WALKABLE)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldWalkable(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_cset)
|
||||
{
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_RAW_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_chf &&m_cset) &&
|
||||
(getTileMeshDrawFlags() & TM_DRAWFLAGS_REGION_CONNECTIONS))
|
||||
{
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRegionConnections(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
if (m_pmesh && (getTileMeshDrawFlags() & TM_DRAWFLAGS_POLYMESH))
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMesh(&m_dd, *m_pmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
if (m_dmesh && (getTileMeshDrawFlags() & TM_DRAWFLAGS_POLYMESH_DETAIL))
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMeshDetail(&m_dd, *m_dmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
// TODO: also add flags for this
|
||||
m_geom->drawConvexVolumes(&m_dd);
|
||||
m_geom->drawOffMeshConnections(&m_dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
void Editor_StaticTileMeshCommon::renderIntermediateTileMeshOptions()
|
||||
{
|
||||
ImGui::Indent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (ImGui::Button("Load", ImVec2(123, 0)))
|
||||
{
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = Editor::loadAll(m_modelName.c_str());
|
||||
m_navQuery->init(m_navMesh, 2048);
|
||||
|
||||
m_loadedNavMeshType = m_selectedNavMeshType;
|
||||
initToolStates(this);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Save", ImVec2(123, 0)))
|
||||
{
|
||||
Editor::saveAll(m_modelName.c_str(), m_navMesh);
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text("Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
|
||||
if (m_navMesh)
|
||||
{
|
||||
const dtNavMeshParams& params = m_navMesh->m_params;
|
||||
const float* origin = m_navMesh->m_orig;
|
||||
|
||||
ImGui::Text("Mesh Origin: \n\tX: %g \n\tY: %g \n\tZ: %g", origin[0], origin[1], origin[2]);
|
||||
ImGui::Text("Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
|
||||
ImGui::Text("Poly Group Count: %d", params.polyGroupCount);
|
||||
ImGui::Text("Traversal Table Size: %d", params.traversalTableSize);
|
||||
ImGui::Text("Traversal Table Count: %d", params.traversalTableCount);
|
||||
ImGui::Text("Max Tiles: %d", params.maxTiles);
|
||||
ImGui::Text("Max Polys: %d", params.maxPolys);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
else
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
void drawTiles(duDebugDraw* dd, dtTileCache* tc)
|
||||
{
|
||||
unsigned int fcol[6];
|
||||
float bmin[3], bmax[3];
|
||||
|
||||
for (int i = 0; i < tc->getTileCount(); ++i)
|
||||
{
|
||||
const dtCompressedTile* tile = tc->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
tc->calcTightTileBounds(tile->header, bmin, bmax);
|
||||
|
||||
const unsigned int col = duIntToCol(i, 64);
|
||||
duCalcBoxColors(fcol, col, col);
|
||||
duDebugDrawBox(dd, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], fcol);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tc->getTileCount(); ++i)
|
||||
{
|
||||
const dtCompressedTile* tile = tc->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
tc->calcTightTileBounds(tile->header, bmin, bmax);
|
||||
|
||||
const unsigned int col = duIntToCol(i, 255);
|
||||
const float pad = tc->getParams()->cs * 0.1f;
|
||||
duDebugDrawBoxWire(dd, bmin[0] - pad, bmin[1] - pad, bmin[2] - pad,
|
||||
bmax[0] + pad, bmax[1] + pad, bmax[2] + pad, col, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void drawObstacles(duDebugDraw* dd, const dtTileCache* tc)
|
||||
{
|
||||
// Draw obstacles
|
||||
for (int i = 0; i < tc->getObstacleCount(); ++i)
|
||||
{
|
||||
const dtTileCacheObstacle* ob = tc->getObstacle(i);
|
||||
if (ob->state == DT_OBSTACLE_EMPTY) continue;
|
||||
float bmin[3], bmax[3];
|
||||
tc->getObstacleBounds(ob, bmin, bmax);
|
||||
|
||||
unsigned int col = 0;
|
||||
if (ob->state == DT_OBSTACLE_PROCESSING)
|
||||
col = duRGBA(255, 255, 0, 128);
|
||||
else if (ob->state == DT_OBSTACLE_PROCESSED)
|
||||
col = duRGBA(255, 192, 0, 192);
|
||||
else if (ob->state == DT_OBSTACLE_REMOVING)
|
||||
col = duRGBA(220, 0, 0, 128);
|
||||
|
||||
duDebugDrawCylinder(dd, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], col);
|
||||
duDebugDrawCylinderWire(dd, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], duDarkenCol(col), 2);
|
||||
}
|
||||
}
|
||||
|
||||
Editor_DynamicTileMeshCommon::Editor_DynamicTileMeshCommon()
|
||||
: m_tileCache(nullptr)
|
||||
, m_talloc(nullptr)
|
||||
, m_tcomp(nullptr)
|
||||
, m_tmproc(nullptr)
|
||||
, m_cacheBuildTimeMs(0.0f)
|
||||
, m_cacheCompressedSize(0)
|
||||
, m_cacheRawSize(0)
|
||||
, m_cacheLayerCount(0)
|
||||
, m_cacheBuildMemUsage(0)
|
||||
, m_tileMeshDrawFlags(TM_DRAWFLAGS_INPUT_MESH|TM_DRAWFLAGS_NAVMESH)
|
||||
, m_keepInterResults(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Editor_DynamicTileMeshCommon::renderTileMeshRenderOptions()
|
||||
{
|
||||
ImGui::Text("TileMesh Render Options");
|
||||
|
||||
bool isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_INPUT_MESH;
|
||||
|
||||
// This should always be available, since if we load a large mesh we want to
|
||||
// be able to toggle this off to save on performance. The renderer has to be
|
||||
// moved to its own thread to solve this issue.
|
||||
if (ImGui::Checkbox("Input Mesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_INPUT_MESH);
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_NAVMESH;
|
||||
//ImGui::BeginDisabled(!hasNavMesh);
|
||||
|
||||
if (ImGui::Checkbox("NavMesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_NAVMESH);
|
||||
|
||||
//ImGui::EndDisabled();
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_TILE_CACHE_BOUNDS;
|
||||
|
||||
ImGui::BeginDisabled(!m_tileCache);
|
||||
|
||||
if (ImGui::Checkbox("Cache Bounds", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_TILE_CACHE_BOUNDS);
|
||||
|
||||
isEnabled = getTileMeshDrawFlags() & TM_DRAWFLAGS_TILE_CACHE_OBSTACLES;
|
||||
|
||||
if (ImGui::Checkbox("Temp Obstacles", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_TILE_CACHE_OBSTACLES);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void Editor_DynamicTileMeshCommon::renderTileMeshData()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
const unsigned int drawFlags = getTileMeshDrawFlags();
|
||||
|
||||
// Draw input mesh
|
||||
if (getTileMeshDrawFlags() & TM_DRAWFLAGS_INPUT_MESH)
|
||||
EditorCommon_DrawInputGeometry(&m_dd, m_geom, m_agentMaxSlope, texScale);
|
||||
|
||||
// Draw bounds
|
||||
EditorCommon_DrawBoundingBox(&m_dd, m_geom);
|
||||
|
||||
// Tiling grid.
|
||||
EditorCommon_DrawTilingGrid(&m_dd, m_geom, m_tileSize, m_cellSize);
|
||||
|
||||
if (m_tileCache && drawFlags & TM_DRAWFLAGS_TILE_CACHE_BOUNDS)
|
||||
drawTiles(&m_dd, m_tileCache);
|
||||
|
||||
if (m_tileCache && drawFlags & TM_DRAWFLAGS_TILE_CACHE_OBSTACLES)
|
||||
drawObstacles(&m_dd, m_tileCache);
|
||||
|
||||
const bool navMeshRenderingEnabled = (drawFlags & TM_DRAWFLAGS_NAVMESH) != 0;
|
||||
|
||||
if (m_navMesh && m_navQuery)
|
||||
{
|
||||
if (drawFlags & TM_DRAWFLAGS_NAVMESH)
|
||||
{
|
||||
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
|
||||
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, duRGBA(0, 0, 0, 128));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: also add flags for this
|
||||
m_geom->drawConvexVolumes(&m_dd);
|
||||
m_geom->drawOffMeshConnections(&m_dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
@ -33,16 +33,7 @@
|
||||
#include "NavEditor/Include/Editor_SoloMesh.h"
|
||||
|
||||
|
||||
Editor_SoloMesh::Editor_SoloMesh() :
|
||||
m_keepInterResults(true),
|
||||
m_totalBuildTimeMs(0),
|
||||
m_triareas(0),
|
||||
m_solid(0),
|
||||
m_chf(0),
|
||||
m_cset(0),
|
||||
m_pmesh(0),
|
||||
m_dmesh(0),
|
||||
m_drawMode(DRAWMODE_NAVMESH)
|
||||
Editor_SoloMesh::Editor_SoloMesh()
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
@ -74,264 +65,67 @@ void Editor_SoloMesh::handleSettings()
|
||||
{
|
||||
Editor::handleCommonSettings();
|
||||
|
||||
if (imguiCheck("Keep Itermediate Results", m_keepInterResults))
|
||||
m_keepInterResults = !m_keepInterResults;
|
||||
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
|
||||
ImGui::Separator();
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
imguiIndent();
|
||||
imguiIndent();
|
||||
|
||||
if (imguiButton("Save"))
|
||||
{
|
||||
Editor::saveAll("solo_navmesh.bin", m_navMesh);
|
||||
}
|
||||
|
||||
if (imguiButton("Load"))
|
||||
{
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = Editor::loadAll("solo_navmesh.bin");
|
||||
m_navQuery->init(m_navMesh, 2048);
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
imguiUnindent();
|
||||
|
||||
char msg[64];
|
||||
snprintf(msg, 64, "Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
imguiLabel(msg);
|
||||
|
||||
imguiSeparator();
|
||||
Editor_StaticTileMeshCommon::renderIntermediateTileMeshOptions();
|
||||
}
|
||||
|
||||
void Editor_SoloMesh::handleTools()
|
||||
{
|
||||
int type = !m_tool ? TOOL_NONE : m_tool->type();
|
||||
bool enabled = type == TOOL_NAVMESH_TESTER;
|
||||
|
||||
if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
|
||||
if (ImGui::Checkbox("Test NavMesh", &enabled))
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Prune Navmesh", type == TOOL_NAVMESH_PRUNE))
|
||||
|
||||
enabled = type == TOOL_NAVMESH_PRUNE;
|
||||
if (ImGui::Checkbox("Prune NavMesh", &enabled))
|
||||
{
|
||||
setTool(new NavMeshPruneTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Connections", type == TOOL_OFFMESH_CONNECTION))
|
||||
|
||||
enabled = type == TOOL_OFFMESH_CONNECTION;
|
||||
if (ImGui::Checkbox("Create Off-Mesh Connections", &enabled))
|
||||
{
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
|
||||
|
||||
enabled = type == TOOL_CONVEX_VOLUME;
|
||||
if (ImGui::Checkbox("Create Convex Volumes", &enabled))
|
||||
{
|
||||
setTool(new ConvexVolumeTool);
|
||||
}
|
||||
if (imguiCheck("Create Crowds", type == TOOL_CROWD))
|
||||
|
||||
enabled = type == TOOL_CROWD;
|
||||
if (ImGui::Checkbox("Create Crowds", &enabled))
|
||||
{
|
||||
setTool(new CrowdTool);
|
||||
}
|
||||
|
||||
imguiSeparatorLine();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleMenu();
|
||||
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
}
|
||||
|
||||
void Editor_SoloMesh::handleDebugMode()
|
||||
{
|
||||
// Check which modes are valid.
|
||||
bool valid[MAX_DRAWMODE];
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
valid[i] = false;
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
|
||||
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_MESH] = true;
|
||||
valid[DRAWMODE_VOXELS] = m_solid != 0;
|
||||
valid[DRAWMODE_VOXELS_WALKABLE] = m_solid != 0;
|
||||
valid[DRAWMODE_COMPACT] = m_chf != 0;
|
||||
valid[DRAWMODE_COMPACT_DISTANCE] = m_chf != 0;
|
||||
valid[DRAWMODE_COMPACT_REGIONS] = m_chf != 0;
|
||||
valid[DRAWMODE_REGION_CONNECTIONS] = m_cset != 0;
|
||||
valid[DRAWMODE_RAW_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_BOTH_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_POLYMESH] = m_pmesh != 0;
|
||||
valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0;
|
||||
}
|
||||
|
||||
int unavail = 0;
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
if (!valid[i]) unavail++;
|
||||
|
||||
if (unavail == MAX_DRAWMODE)
|
||||
return;
|
||||
|
||||
imguiLabel("Draw");
|
||||
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
|
||||
m_drawMode = DRAWMODE_MESH;
|
||||
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
|
||||
m_drawMode = DRAWMODE_NAVMESH;
|
||||
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_INVIS;
|
||||
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_TRANS;
|
||||
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
|
||||
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_NODES;
|
||||
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
|
||||
m_drawMode = DRAWMODE_VOXELS;
|
||||
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
|
||||
m_drawMode = DRAWMODE_VOXELS_WALKABLE;
|
||||
if (imguiCheck("Compact", m_drawMode == DRAWMODE_COMPACT, valid[DRAWMODE_COMPACT]))
|
||||
m_drawMode = DRAWMODE_COMPACT;
|
||||
if (imguiCheck("Compact Distance", m_drawMode == DRAWMODE_COMPACT_DISTANCE, valid[DRAWMODE_COMPACT_DISTANCE]))
|
||||
m_drawMode = DRAWMODE_COMPACT_DISTANCE;
|
||||
if (imguiCheck("Compact Regions", m_drawMode == DRAWMODE_COMPACT_REGIONS, valid[DRAWMODE_COMPACT_REGIONS]))
|
||||
m_drawMode = DRAWMODE_COMPACT_REGIONS;
|
||||
if (imguiCheck("Region Connections", m_drawMode == DRAWMODE_REGION_CONNECTIONS, valid[DRAWMODE_REGION_CONNECTIONS]))
|
||||
m_drawMode = DRAWMODE_REGION_CONNECTIONS;
|
||||
if (imguiCheck("Raw Contours", m_drawMode == DRAWMODE_RAW_CONTOURS, valid[DRAWMODE_RAW_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_RAW_CONTOURS;
|
||||
if (imguiCheck("Both Contours", m_drawMode == DRAWMODE_BOTH_CONTOURS, valid[DRAWMODE_BOTH_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_BOTH_CONTOURS;
|
||||
if (imguiCheck("Contours", m_drawMode == DRAWMODE_CONTOURS, valid[DRAWMODE_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_CONTOURS;
|
||||
if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH]))
|
||||
m_drawMode = DRAWMODE_POLYMESH;
|
||||
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
|
||||
m_drawMode = DRAWMODE_POLYMESH_DETAIL;
|
||||
|
||||
if (unavail)
|
||||
{
|
||||
imguiValue("Tick 'Keep Itermediate Results'");
|
||||
imguiValue("to see more debug mode options.");
|
||||
}
|
||||
Editor::renderNavMeshDebugMenu();
|
||||
ImGui::Separator();
|
||||
Editor_StaticTileMeshCommon::renderTileMeshRenderOptions();
|
||||
}
|
||||
|
||||
void Editor_SoloMesh::handleRender()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
glEnable(GL_FOG);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&m_dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope, texScale);
|
||||
m_geom->drawOffMeshConnections(&m_dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// Draw bounds
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
duDebugDrawBoxWire(&m_dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
|
||||
m_dd.begin(DU_DRAW_POINTS, 5.0f);
|
||||
m_dd.vertex(bmin[0],bmin[1],bmin[2],duRGBA(255,255,255,128));
|
||||
m_dd.end();
|
||||
|
||||
if (m_navMesh && m_navQuery &&
|
||||
(m_drawMode == DRAWMODE_NAVMESH ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
|
||||
{
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
|
||||
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&m_dd, *m_navMesh);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
|
||||
duDebugDrawNavMeshNodes(&m_dd, *m_navQuery);
|
||||
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, duRGBA(0,0,0,128));
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT)
|
||||
duDebugDrawCompactHeightfieldSolid(&m_dd, *m_chf);
|
||||
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT_DISTANCE)
|
||||
duDebugDrawCompactHeightfieldDistance(&m_dd, *m_chf);
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT_REGIONS)
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
if (m_solid && m_drawMode == DRAWMODE_VOXELS)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldSolid(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (m_solid && m_drawMode == DRAWMODE_VOXELS_WALKABLE)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldWalkable(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&m_dd, *m_cset, 0.5f);
|
||||
duDebugDrawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS)
|
||||
{
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRegionConnections(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMesh(&m_dd, *m_pmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMeshDetail(&m_dd, *m_dmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
m_geom->drawConvexVolumes(&m_dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
Editor_StaticTileMeshCommon::renderTileMeshData();
|
||||
}
|
||||
|
||||
void Editor_SoloMesh::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
@ -360,7 +154,7 @@ void Editor_SoloMesh::handleMeshChanged(class InputGeom* geom)
|
||||
|
||||
bool Editor_SoloMesh::handleBuild()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
if (!m_geom || !m_geom->getMesh() || !m_geom->getChunkyMesh())
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
|
||||
return false;
|
||||
@ -389,8 +183,8 @@ bool Editor_SoloMesh::handleBuild()
|
||||
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
|
||||
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
|
||||
m_cfg.maxSimplificationError = m_edgeMaxError;
|
||||
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
m_cfg.minRegionArea = rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
m_cfg.mergeRegionArea = rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
|
||||
m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
|
||||
m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
|
||||
@ -460,7 +254,7 @@ bool Editor_SoloMesh::handleBuild()
|
||||
// Step 3. Filter walkables surfaces.
|
||||
//
|
||||
|
||||
// Once all geoemtry is rasterized, we do initial pass of filtering to
|
||||
// Once all geometry is rasterized, we do initial pass of filtering to
|
||||
// remove unwanted overhangs caused by the conservative rasterization
|
||||
// as well as filter spans where the character cannot possibly stand.
|
||||
if (m_filterLowHangingObstacles)
|
||||
@ -639,6 +433,9 @@ bool Editor_SoloMesh::handleBuild()
|
||||
|
||||
// The GUI may allow more max points per polygon than Detour can handle.
|
||||
// Only build the detour navmesh if we do not exceed the limit.
|
||||
|
||||
const int traversalTableCount = NavMesh_GetTraversalTableCountForNavMeshType(m_selectedNavMeshType);
|
||||
|
||||
if (m_cfg.maxVertsPerPoly <= DT_VERTS_PER_POLYGON)
|
||||
{
|
||||
unsigned char* navData = 0;
|
||||
@ -706,17 +503,17 @@ bool Editor_SoloMesh::handleBuild()
|
||||
m_navMesh = dtAllocNavMesh();
|
||||
if (!m_navMesh)
|
||||
{
|
||||
dtFree(navData);
|
||||
rdFree(navData);
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not create Detour navmesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
dtStatus status;
|
||||
|
||||
status = m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA);
|
||||
status = m_navMesh->init(navData, navDataSize, traversalTableCount, DT_TILE_FREE_DATA);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
dtFree(navData);
|
||||
rdFree(navData);
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
|
||||
return false;
|
||||
}
|
||||
@ -728,6 +525,18 @@ bool Editor_SoloMesh::handleBuild()
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dtDisjointSet data;
|
||||
|
||||
if (!dtCreateDisjointPolyGroups(m_navMesh, data))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Failed to build disjoint poly groups.");
|
||||
}
|
||||
|
||||
if (!dtCreateTraversalTableData(m_navMesh, data, traversalTableCount))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Failed to build traversal table data.");
|
||||
}
|
||||
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
|
@ -17,10 +17,9 @@
|
||||
//
|
||||
|
||||
#include "Pch.h"
|
||||
#include "Shared/Include/SharedAlloc.h"
|
||||
#include "Shared/Include/SharedAssert.h"
|
||||
#include "Recast/Include/Recast.h"
|
||||
#include "Recast/Include/RecastAlloc.h"
|
||||
#include "Recast/Include/RecastAssert.h"
|
||||
#include "Detour/Include/DetourAssert.h"
|
||||
#include "Detour/Include/DetourNavMesh.h"
|
||||
#include "Detour/Include/DetourNavMeshBuilder.h"
|
||||
#include "Detour/Include/DetourCommon.h"
|
||||
@ -125,13 +124,13 @@ struct LinearAllocator : public dtTileCacheAlloc
|
||||
|
||||
~LinearAllocator()
|
||||
{
|
||||
dtFree(buffer);
|
||||
rdFree(buffer);
|
||||
}
|
||||
|
||||
void resize(const size_t cap)
|
||||
{
|
||||
if (buffer) dtFree(buffer);
|
||||
buffer = (unsigned char*)dtAlloc(cap, DT_ALLOC_PERM);
|
||||
if (buffer) rdFree(buffer);
|
||||
buffer = (unsigned char*)rdAlloc(cap, RD_ALLOC_PERM);
|
||||
capacity = cap;
|
||||
}
|
||||
|
||||
@ -241,7 +240,7 @@ struct RasterizationContext
|
||||
rcFreeCompactHeightfield(chf);
|
||||
for (int i = 0; i < MAX_LAYERS; ++i)
|
||||
{
|
||||
dtFree(tiles[i].data);
|
||||
rdFree(tiles[i].data);
|
||||
tiles[i].data = 0;
|
||||
}
|
||||
}
|
||||
@ -279,16 +278,18 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
rcConfig tcfg;
|
||||
memcpy(&tcfg, &cfg, sizeof(tcfg));
|
||||
|
||||
tcfg.bmin[0] = cfg.bmin[0] + tx*tcs;
|
||||
tcfg.bmin[1] = cfg.bmin[1];
|
||||
tcfg.bmin[2] = cfg.bmin[2] + ty*tcs;
|
||||
tcfg.bmax[0] = cfg.bmin[0] + (tx+1)*tcs;
|
||||
tcfg.bmax[1] = cfg.bmax[1];
|
||||
tcfg.bmax[2] = cfg.bmin[2] + (ty+1)*tcs;
|
||||
tcfg.bmin[0] = cfg.bmax[0] - (tx+1)*tcs;
|
||||
tcfg.bmin[1] = cfg.bmin[1] + (ty)*tcs;
|
||||
tcfg.bmin[2] = cfg.bmin[2];
|
||||
|
||||
tcfg.bmax[0] = cfg.bmax[0] - (tx)*tcs;
|
||||
tcfg.bmax[1] = cfg.bmin[1] + (ty+1)*tcs;
|
||||
tcfg.bmax[2] = cfg.bmax[2];
|
||||
|
||||
tcfg.bmin[0] -= tcfg.borderSize*tcfg.cs;
|
||||
tcfg.bmin[2] -= tcfg.borderSize*tcfg.cs;
|
||||
tcfg.bmin[1] -= tcfg.borderSize*tcfg.cs;
|
||||
tcfg.bmax[0] += tcfg.borderSize*tcfg.cs;
|
||||
tcfg.bmax[2] += tcfg.borderSize*tcfg.cs;
|
||||
tcfg.bmax[1] += tcfg.borderSize*tcfg.cs;
|
||||
|
||||
// Allocate voxel heightfield where we rasterize our input data to.
|
||||
rc.solid = rcAllocHeightfield();
|
||||
@ -315,11 +316,12 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
|
||||
float tbmin[2], tbmax[2];
|
||||
tbmin[0] = tcfg.bmin[0];
|
||||
tbmin[1] = tcfg.bmin[2];
|
||||
tbmin[1] = tcfg.bmin[1];
|
||||
tbmax[0] = tcfg.bmax[0];
|
||||
tbmax[1] = tcfg.bmax[2];
|
||||
int cid[512];// TODO: Make grow when returning too many items.
|
||||
const int ncid = rcGetChunksOverlappingRect(chunkyMesh, tbmin, tbmax, cid, 512);
|
||||
tbmax[1] = tcfg.bmax[1];
|
||||
#if 0
|
||||
int cid[1024];// TODO: Make grow when returning too many items.
|
||||
const int ncid = rcGetChunksOverlappingRect(chunkyMesh, tbmin, tbmax, cid, 1024);
|
||||
if (!ncid)
|
||||
{
|
||||
return 0; // empty
|
||||
@ -338,6 +340,29 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
if (!rcRasterizeTriangles(m_ctx, verts, nverts, tris, rc.triareas, ntris, *rc.solid, tcfg.walkableClimb))
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int cid[1024];//NOTE: we don't grow it but we reuse it (e.g. like a yieldable function or iterator or sth)
|
||||
int currentNode = 0;
|
||||
|
||||
bool done = false;
|
||||
do{
|
||||
int currentCount = 0;
|
||||
done=rcGetChunksOverlappingRect(chunkyMesh, tbmin, tbmax, cid, 1024,currentCount,currentNode);
|
||||
for (int i = 0; i < currentCount; ++i)
|
||||
{
|
||||
const rcChunkyTriMeshNode& node = chunkyMesh->nodes[cid[i]];
|
||||
const int* tris = &chunkyMesh->tris[node.i*3];
|
||||
const int ntris = node.n;
|
||||
|
||||
memset(rc.triareas, 0, ntris * sizeof(unsigned char));
|
||||
rcMarkWalkableTriangles(m_ctx, tcfg.walkableSlopeAngle,
|
||||
verts, nverts, tris, ntris, rc.triareas);
|
||||
|
||||
if (!rcRasterizeTriangles(m_ctx, verts, nverts, tris, rc.triareas, ntris, *rc.solid, tcfg.walkableClimb))
|
||||
return 0;
|
||||
}
|
||||
} while (!done);
|
||||
#endif
|
||||
|
||||
// Once all geometry is rasterized, we do initial pass of filtering to
|
||||
// remove unwanted overhangs caused by the conservative rasterization
|
||||
@ -349,7 +374,9 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
if (m_filterWalkableLowHeightSpans)
|
||||
rcFilterWalkableLowHeightSpans(m_ctx, tcfg.walkableHeight, *rc.solid);
|
||||
|
||||
|
||||
// Compact the heightfield so that it is faster to handle from now on.
|
||||
// This will result more cache coherent data as well as the neighbours
|
||||
// between walkable cells will be calculated.
|
||||
rc.chf = rcAllocCompactHeightfield();
|
||||
if (!rc.chf)
|
||||
{
|
||||
@ -386,7 +413,7 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
}
|
||||
if (!rcBuildHeightfieldLayers(m_ctx, *rc.chf, tcfg.borderSize, tcfg.walkableHeight, *rc.lset))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build heighfield layers.");
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build heightfield layers.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -426,7 +453,7 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer ownsership of tile data from build context to the caller.
|
||||
// Transfer ownership of tile data from build context to the caller.
|
||||
int n = 0;
|
||||
for (int i = 0; i < rcMin(rc.ntiles, maxTiles); ++i)
|
||||
{
|
||||
@ -438,39 +465,6 @@ int Editor_TempObstacles::rasterizeTileLayers(
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void drawTiles(duDebugDraw* dd, dtTileCache* tc)
|
||||
{
|
||||
unsigned int fcol[6];
|
||||
float bmin[3], bmax[3];
|
||||
|
||||
for (int i = 0; i < tc->getTileCount(); ++i)
|
||||
{
|
||||
const dtCompressedTile* tile = tc->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
tc->calcTightTileBounds(tile->header, bmin, bmax);
|
||||
|
||||
const unsigned int col = duIntToCol(i,64);
|
||||
duCalcBoxColors(fcol, col, col);
|
||||
duDebugDrawBox(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], fcol);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tc->getTileCount(); ++i)
|
||||
{
|
||||
const dtCompressedTile* tile = tc->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
tc->calcTightTileBounds(tile->header, bmin, bmax);
|
||||
|
||||
const unsigned int col = duIntToCol(i,255);
|
||||
const float pad = tc->getParams()->cs * 0.1f;
|
||||
duDebugDrawBoxWire(dd, bmin[0]-pad,bmin[1]-pad,bmin[2]-pad,
|
||||
bmax[0]+pad,bmax[1]+pad,bmax[2]+pad, col, 2.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum DrawDetailType
|
||||
{
|
||||
DRAWDETAIL_AREAS,
|
||||
@ -575,8 +569,7 @@ void drawDetailOverlay(const dtTileCache* tc, const int tx, const int ty, double
|
||||
return;
|
||||
|
||||
const int rawSize = calcLayerBufferSize(tc->getParams()->width, tc->getParams()->height);
|
||||
|
||||
char text[128];
|
||||
const int h = view[3];
|
||||
|
||||
for (int i = 0; i < ntiles; ++i)
|
||||
{
|
||||
@ -584,19 +577,21 @@ void drawDetailOverlay(const dtTileCache* tc, const int tx, const int ty, double
|
||||
|
||||
float pos[3];
|
||||
pos[0] = (tile->header->bmin[0]+tile->header->bmax[0])/2.0f;
|
||||
pos[1] = tile->header->bmin[1];
|
||||
pos[2] = (tile->header->bmin[2]+tile->header->bmax[2])/2.0f;
|
||||
pos[1] = (tile->header->bmin[1]+tile->header->bmax[1])/2.0f;
|
||||
pos[2] = (tile->header->bmin[2]);
|
||||
|
||||
GLdouble x, y, z;
|
||||
if (gluProject((GLdouble)pos[0], (GLdouble)pos[1], (GLdouble)pos[2],
|
||||
model, proj, view, &x, &y, &z))
|
||||
{
|
||||
snprintf(text,128,"(%d,%d)/%d", tile->header->tx,tile->header->ty,tile->header->tlayer);
|
||||
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
|
||||
snprintf(text,128,"Compressed: %.1f kB", tile->dataSize/1024.0f);
|
||||
imguiDrawText((int)x, (int)y-45, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,128));
|
||||
snprintf(text,128,"Raw:%.1fkB", rawSize/1024.0f);
|
||||
imguiDrawText((int)x, (int)y-65, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,128));
|
||||
ImGui_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-25.f)), ImVec4(0.0f, 0.0f, 0.0f, 0.8f),
|
||||
"(%d,%d)/%d", tile->header->tx, tile->header->ty, tile->header->tlayer);
|
||||
|
||||
ImGui_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-45.f)), ImVec4(0.0f, 0.0f, 0.0f, 0.8f),
|
||||
"Compressed: %.1f kB", tile->dataSize/1024.0f);
|
||||
|
||||
ImGui_RenderText(ImGuiTextAlign_e::kAlignCenter, ImVec2((float)x, h-((float)y-65.f)), ImVec4(0.0f, 0.0f, 0.0f, 0.8f),
|
||||
"Raw: %.1fkB", rawSize/1024.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -625,36 +620,13 @@ dtObstacleRef hitTestObstacle(const dtTileCache* tc, const float* sp, const floa
|
||||
}
|
||||
return tc->getObstacleRef(obmin);
|
||||
}
|
||||
|
||||
void drawObstacles(duDebugDraw* dd, const dtTileCache* tc)
|
||||
{
|
||||
// Draw obstacles
|
||||
for (int i = 0; i < tc->getObstacleCount(); ++i)
|
||||
{
|
||||
const dtTileCacheObstacle* ob = tc->getObstacle(i);
|
||||
if (ob->state == DT_OBSTACLE_EMPTY) continue;
|
||||
float bmin[3], bmax[3];
|
||||
tc->getObstacleBounds(ob, bmin,bmax);
|
||||
|
||||
unsigned int col = 0;
|
||||
if (ob->state == DT_OBSTACLE_PROCESSING)
|
||||
col = duRGBA(255,255,0,128);
|
||||
else if (ob->state == DT_OBSTACLE_PROCESSED)
|
||||
col = duRGBA(255,192,0,192);
|
||||
else if (ob->state == DT_OBSTACLE_REMOVING)
|
||||
col = duRGBA(220,0,0,128);
|
||||
|
||||
duDebugDrawCylinder(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], col);
|
||||
duDebugDrawCylinderWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duDarkenCol(col), 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class TempObstacleHilightTool : public EditorTool
|
||||
{
|
||||
Editor_TempObstacles* ;
|
||||
Editor_TempObstacles* m_editor;
|
||||
float m_hitPos[3];
|
||||
bool m_hitPosSet;
|
||||
int m_drawType;
|
||||
@ -662,7 +634,7 @@ class TempObstacleHilightTool : public EditorTool
|
||||
public:
|
||||
|
||||
TempObstacleHilightTool() :
|
||||
(0),
|
||||
m_editor(0),
|
||||
m_hitPosSet(false),
|
||||
m_drawType(DRAWDETAIL_AREAS)
|
||||
{
|
||||
@ -677,23 +649,31 @@ public:
|
||||
|
||||
virtual void init(Editor* editor)
|
||||
{
|
||||
= (Editor_TempObstacles*)editor;
|
||||
m_editor = (Editor_TempObstacles*)editor;
|
||||
}
|
||||
|
||||
virtual void reset() {}
|
||||
|
||||
virtual void handleMenu()
|
||||
{
|
||||
imguiLabel("Highlight Tile Cache");
|
||||
imguiValue("Click LMB to highlight a tile.");
|
||||
imguiSeparator();
|
||||
if (imguiCheck("Draw Areas", m_drawType == DRAWDETAIL_AREAS))
|
||||
ImGui::Text("Highlight Tile Cache");
|
||||
ImGui::Text("Click LMB to highlight a tile.");
|
||||
ImGui::Separator();
|
||||
|
||||
bool enabled = m_drawType == DRAWDETAIL_AREAS; // todo(amos): use flags instead?
|
||||
if (ImGui::Checkbox("Draw Areas", &enabled))
|
||||
m_drawType = DRAWDETAIL_AREAS;
|
||||
if (imguiCheck("Draw Regions", m_drawType == DRAWDETAIL_REGIONS))
|
||||
|
||||
enabled = m_drawType == DRAWDETAIL_REGIONS;
|
||||
if (ImGui::Checkbox("Draw Regions", &enabled))
|
||||
m_drawType = DRAWDETAIL_REGIONS;
|
||||
if (imguiCheck("Draw Contours", m_drawType == DRAWDETAIL_CONTOURS))
|
||||
|
||||
enabled = m_drawType == DRAWDETAIL_CONTOURS;
|
||||
if (ImGui::Checkbox("Draw Contours", &enabled))
|
||||
m_drawType = DRAWDETAIL_CONTOURS;
|
||||
if (imguiCheck("Draw Mesh", m_drawType == DRAWDETAIL_MESH))
|
||||
|
||||
enabled = m_drawType == DRAWDETAIL_MESH;
|
||||
if (ImGui::Checkbox("Draw Mesh", &enabled))
|
||||
m_drawType = DRAWDETAIL_MESH;
|
||||
}
|
||||
|
||||
@ -711,9 +691,9 @@ public:
|
||||
|
||||
virtual void handleRender()
|
||||
{
|
||||
if (m_hitPosSet && )
|
||||
if (m_hitPosSet && m_editor)
|
||||
{
|
||||
const float s = ->getAgentRadius();
|
||||
const float s = m_editor->getAgentRadius();
|
||||
glColor4ub(0,0,0,128);
|
||||
glLineWidth(2.0f);
|
||||
glBegin(GL_LINES);
|
||||
@ -727,8 +707,8 @@ public:
|
||||
glLineWidth(1.0f);
|
||||
|
||||
int tx=0, ty=0;
|
||||
->getTilePos(m_hitPos, tx, ty);
|
||||
->renderCachedTile(tx,ty,m_drawType);
|
||||
m_editor->getTilePos(m_hitPos, tx, ty);
|
||||
m_editor->renderCachedTile(tx,ty,m_drawType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,11 +716,11 @@ public:
|
||||
{
|
||||
if (m_hitPosSet)
|
||||
{
|
||||
if ()
|
||||
if (m_editor)
|
||||
{
|
||||
int tx=0, ty=0;
|
||||
->getTilePos(m_hitPos, tx, ty);
|
||||
->renderCachedTileOverlay(tx,ty,proj,model,view);
|
||||
m_editor->getTilePos(m_hitPos, tx, ty);
|
||||
m_editor->renderCachedTileOverlay(tx,ty,proj,model,view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -749,11 +729,11 @@ public:
|
||||
|
||||
class TempObstacleCreateTool : public EditorTool
|
||||
{
|
||||
Editor_TempObstacles* ;
|
||||
Editor_TempObstacles* m_editor;
|
||||
|
||||
public:
|
||||
|
||||
TempObstacleCreateTool() : (0)
|
||||
TempObstacleCreateTool() : m_editor(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -765,32 +745,32 @@ public:
|
||||
|
||||
virtual void init(Editor* editor)
|
||||
{
|
||||
= (Editor_TempObstacles*)editor;
|
||||
m_editor = (Editor_TempObstacles*)editor;
|
||||
}
|
||||
|
||||
virtual void reset() {}
|
||||
|
||||
virtual void handleMenu()
|
||||
{
|
||||
imguiLabel("Create Temp Obstacles");
|
||||
ImGui::Text("Create Temp Obstacles");
|
||||
|
||||
if (imguiButton("Remove All"))
|
||||
->clearAllTempObstacles();
|
||||
if (ImGui::Button("Remove All"))
|
||||
m_editor->clearAllTempObstacles();
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiValue("Click LMB to create an obstacle.");
|
||||
imguiValue("Shift+LMB to remove an obstacle.");
|
||||
ImGui::Text("Click LMB to create an obstacle.");
|
||||
ImGui::Text("Shift+LMB to remove an obstacle.");
|
||||
}
|
||||
|
||||
virtual void handleClick(const float* s, const float* p, bool shift)
|
||||
{
|
||||
if ()
|
||||
if (m_editor)
|
||||
{
|
||||
if (shift)
|
||||
->removeTempObstacle(s,p);
|
||||
m_editor->removeTempObstacle(s,p);
|
||||
else
|
||||
->addTempObstacle(p);
|
||||
m_editor->addTempObstacle(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,18 +785,9 @@ public:
|
||||
|
||||
|
||||
|
||||
Editor_TempObstacles::Editor_TempObstacles() :
|
||||
m_keepInterResults(false),
|
||||
m_tileCache(0),
|
||||
m_cacheBuildTimeMs(0),
|
||||
m_cacheCompressedSize(0),
|
||||
m_cacheRawSize(0),
|
||||
m_cacheLayerCount(0),
|
||||
m_cacheBuildMemUsage(0),
|
||||
m_drawMode(DRAWMODE_NAVMESH),
|
||||
m_maxTiles(0),
|
||||
m_maxPolysPerTile(0),
|
||||
m_tileSize(48)
|
||||
Editor_TempObstacles::Editor_TempObstacles()
|
||||
: m_maxTiles(0)
|
||||
, m_maxPolysPerTile(0)
|
||||
{
|
||||
resetCommonSettings();
|
||||
|
||||
@ -838,246 +809,125 @@ void Editor_TempObstacles::handleSettings()
|
||||
{
|
||||
Editor::handleCommonSettings();
|
||||
|
||||
if (imguiCheck("Keep Itermediate Results", m_keepInterResults))
|
||||
m_keepInterResults = !m_keepInterResults;
|
||||
ImGui::Text("Tiling");
|
||||
ImGui::SliderInt("Tile Size", &m_tileSize, 8, 1024);
|
||||
|
||||
imguiLabel("Tiling");
|
||||
imguiSlider("TileSize", &m_tileSize, 16.0f, 128.0f, 8.0f);
|
||||
|
||||
int gridSize = 1;
|
||||
if (m_geom)
|
||||
{
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
char text[64];
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int ts = (int)m_tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
snprintf(text, 64, "Tiles %d x %d", tw, th);
|
||||
imguiValue(text);
|
||||
// Max tiles and max polys affect how the tile IDs are caculated.
|
||||
// There are 22 bits available for identifying a tile and a polygon.
|
||||
int tileBits = rcMin((int)dtIlog2(dtNextPow2(tw*th*EXPECTED_LAYERS_PER_TILE)), 14);
|
||||
if (tileBits > 14) tileBits = 14;
|
||||
int polyBits = 22 - tileBits;
|
||||
m_maxTiles = 1 << tileBits;
|
||||
m_maxPolysPerTile = 1 << polyBits;
|
||||
snprintf(text, 64, "Max Tiles %d", m_maxTiles);
|
||||
imguiValue(text);
|
||||
snprintf(text, 64, "Max Polys %d", m_maxPolysPerTile);
|
||||
imguiValue(text);
|
||||
gridSize = tw*th;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maxTiles = 0;
|
||||
m_maxPolysPerTile = 0;
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
imguiLabel("Tile Cache");
|
||||
char msg[64];
|
||||
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
|
||||
|
||||
const int gridSize = EditorCommon_SetAndRenderTileProperties(m_geom, m_tileSize, m_cellSize, m_maxTiles, m_maxPolysPerTile);
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Tile Cache");
|
||||
const float compressionRatio = (float)m_cacheCompressedSize / (float)(m_cacheRawSize+1);
|
||||
|
||||
snprintf(msg, 64, "Layers %d", m_cacheLayerCount);
|
||||
imguiValue(msg);
|
||||
snprintf(msg, 64, "Layers (per tile) %.1f", (float)m_cacheLayerCount/(float)gridSize);
|
||||
imguiValue(msg);
|
||||
|
||||
snprintf(msg, 64, "Memory %.1f kB / %.1f kB (%.1f%%)", m_cacheCompressedSize/1024.0f, m_cacheRawSize/1024.0f, compressionRatio*100.0f);
|
||||
imguiValue(msg);
|
||||
snprintf(msg, 64, "Navmesh Build Time %.1f ms", m_cacheBuildTimeMs);
|
||||
imguiValue(msg);
|
||||
snprintf(msg, 64, "Build Peak Mem Usage %.1f kB", m_cacheBuildMemUsage/1024.0f);
|
||||
imguiValue(msg);
|
||||
ImGui::Text("Layers: %d", m_cacheLayerCount);
|
||||
ImGui::Text("Layers (per tile): %.1f", (float)m_cacheLayerCount/(float)gridSize);
|
||||
ImGui::Text("Memory: %.1f kB / %.1f kB (%.1f%%)", m_cacheCompressedSize/1024.0f, m_cacheRawSize/1024.0f, compressionRatio*100.0f);
|
||||
ImGui::Text("Build Peak Mem Usage: %.1f kB", m_cacheBuildMemUsage/1024.0f);
|
||||
ImGui::Text("Build Time: %.1fms", m_cacheBuildTimeMs);
|
||||
|
||||
imguiSeparator();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiIndent();
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (imguiButton("Save"))
|
||||
{
|
||||
saveAll("all_tiles_tilecache.bin");
|
||||
}
|
||||
|
||||
if (imguiButton("Load"))
|
||||
if (ImGui::Button("Load", ImVec2(123, 0)))
|
||||
{
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
dtFreeTileCache(m_tileCache);
|
||||
loadAll("all_tiles_tilecache.bin");
|
||||
m_navMesh = Editor::loadAll(m_modelName.c_str());
|
||||
m_navQuery->init(m_navMesh, 2048);
|
||||
|
||||
m_loadedNavMeshType = m_selectedNavMeshType;
|
||||
initToolStates(this);
|
||||
}
|
||||
|
||||
imguiUnindent();
|
||||
imguiUnindent();
|
||||
|
||||
imguiSeparator();
|
||||
if (ImGui::Button("Save", ImVec2(123, 0)))
|
||||
{
|
||||
Editor::saveAll(m_modelName.c_str(), m_navMesh);
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
if (m_navMesh)
|
||||
{
|
||||
const dtNavMeshParams& params = m_navMesh->m_params;
|
||||
const float* origin = m_navMesh->m_orig;
|
||||
|
||||
ImGui::Text("Mesh Origin: \n\tX: %g \n\tY: %g \n\tZ: %g", origin[0], origin[1], origin[2]);
|
||||
ImGui::Text("Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
|
||||
ImGui::Text("Poly Group Count: %d", params.polyGroupCount);
|
||||
ImGui::Text("Traversal Table Size: %d", params.traversalTableSize);
|
||||
ImGui::Text("Traversal Table Count: %d", params.traversalTableCount);
|
||||
ImGui::Text("Max Tiles: %d", params.maxTiles);
|
||||
ImGui::Text("Max Polys: %d", params.maxPolys);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
else
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
void Editor_TempObstacles::handleTools()
|
||||
{
|
||||
int type = !m_tool ? TOOL_NONE : m_tool->type();
|
||||
bool enabled = type == TOOL_NAVMESH_TESTER;
|
||||
|
||||
if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
|
||||
if (ImGui::Checkbox("Test NavMesh", &enabled))
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Highlight Tile Cache", type == TOOL_TILE_HIGHLIGHT))
|
||||
|
||||
enabled = type == TOOL_TILE_HIGHLIGHT;
|
||||
if (ImGui::Checkbox("Highlight Tile Cache", &enabled))
|
||||
{
|
||||
setTool(new TempObstacleHilightTool);
|
||||
}
|
||||
if (imguiCheck("Create Temp Obstacles", type == TOOL_TEMP_OBSTACLE))
|
||||
|
||||
enabled = type == TOOL_TEMP_OBSTACLE;
|
||||
if (ImGui::Checkbox("Create Temp Obstacles", &enabled))
|
||||
{
|
||||
setTool(new TempObstacleCreateTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
|
||||
|
||||
enabled = type == TOOL_OFFMESH_CONNECTION;
|
||||
if (ImGui::Checkbox("Create Off-Mesh Links", &enabled))
|
||||
{
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
|
||||
|
||||
enabled = type == TOOL_CONVEX_VOLUME;
|
||||
if (ImGui::Checkbox("Create Convex Volumes", &enabled))
|
||||
{
|
||||
setTool(new ConvexVolumeTool);
|
||||
}
|
||||
if (imguiCheck("Create Crowds", type == TOOL_CROWD))
|
||||
|
||||
enabled = type == TOOL_CROWD;
|
||||
if (ImGui::Checkbox("Create Crowds", &enabled))
|
||||
{
|
||||
setTool(new CrowdTool);
|
||||
}
|
||||
|
||||
imguiSeparatorLine();
|
||||
ImGui::Separator();
|
||||
|
||||
imguiIndent();
|
||||
ImGui::Indent();
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleMenu();
|
||||
|
||||
imguiUnindent();
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
void Editor_TempObstacles::handleDebugMode()
|
||||
{
|
||||
// Check which modes are valid.
|
||||
bool valid[MAX_DRAWMODE];
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
valid[i] = false;
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
|
||||
valid[DRAWMODE_NAVMESH_PORTALS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_MESH] = true;
|
||||
valid[DRAWMODE_CACHE_BOUNDS] = true;
|
||||
}
|
||||
|
||||
int unavail = 0;
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
if (!valid[i]) unavail++;
|
||||
|
||||
if (unavail == MAX_DRAWMODE)
|
||||
return;
|
||||
|
||||
imguiLabel("Draw");
|
||||
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
|
||||
m_drawMode = DRAWMODE_MESH;
|
||||
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
|
||||
m_drawMode = DRAWMODE_NAVMESH;
|
||||
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_INVIS;
|
||||
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_TRANS;
|
||||
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
|
||||
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_NODES;
|
||||
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
|
||||
if (imguiCheck("Cache Bounds", m_drawMode == DRAWMODE_CACHE_BOUNDS, valid[DRAWMODE_CACHE_BOUNDS]))
|
||||
m_drawMode = DRAWMODE_CACHE_BOUNDS;
|
||||
|
||||
if (unavail)
|
||||
{
|
||||
imguiValue("Tick 'Keep Itermediate Results'");
|
||||
imguiValue("rebuild some tiles to see");
|
||||
imguiValue("more debug mode options.");
|
||||
}
|
||||
Editor::renderNavMeshDebugMenu();
|
||||
ImGui::Separator();
|
||||
Editor_DynamicTileMeshCommon::renderTileMeshRenderOptions();
|
||||
}
|
||||
|
||||
void Editor_TempObstacles::handleRender()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
|
||||
// Draw mesh
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&m_dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope, texScale);
|
||||
m_geom->drawOffMeshConnections(&m_dd);
|
||||
}
|
||||
|
||||
if (m_tileCache && m_drawMode == DRAWMODE_CACHE_BOUNDS)
|
||||
drawTiles(&m_dd, m_tileCache);
|
||||
|
||||
if (m_tileCache)
|
||||
drawObstacles(&m_dd, m_tileCache);
|
||||
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// Draw bounds
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
duDebugDrawBoxWire(&m_dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
|
||||
|
||||
// Tiling grid.
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int tw = (gw + (int)m_tileSize-1) / (int)m_tileSize;
|
||||
const int th = (gh + (int)m_tileSize-1) / (int)m_tileSize;
|
||||
const float s = m_tileSize*m_cellSize;
|
||||
duDebugDrawGridXZ(&m_dd, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
|
||||
|
||||
if (m_navMesh && m_navQuery &&
|
||||
(m_drawMode == DRAWMODE_NAVMESH ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_PORTALS ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
|
||||
{
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
|
||||
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags/*|DU_DRAWNAVMESH_COLOR_TILES*/);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&m_dd, *m_navMesh);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_PORTALS)
|
||||
duDebugDrawNavMeshPortals(&m_dd, *m_navMesh);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
|
||||
duDebugDrawNavMeshNodes(&m_dd, *m_navQuery);
|
||||
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, duRGBA(0,0,0,128));
|
||||
}
|
||||
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
m_geom->drawConvexVolumes(&m_dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
Editor_DynamicTileMeshCommon::renderTileMeshData();
|
||||
}
|
||||
|
||||
void Editor_TempObstacles::renderCachedTile(const int tx, const int ty, const int type)
|
||||
@ -1148,7 +998,7 @@ void Editor_TempObstacles::addTempObstacle(const float* pos)
|
||||
return;
|
||||
float p[3];
|
||||
dtVcopy(p, pos);
|
||||
p[1] -= 0.5f;
|
||||
p[2] -= 0.5f;
|
||||
m_tileCache->addObstacle(p, 1.0f, 2.0f, 0);
|
||||
}
|
||||
|
||||
@ -1204,10 +1054,10 @@ bool Editor_TempObstacles::handleBuild()
|
||||
cfg.walkableRadius = (int)ceilf(m_agentRadius / cfg.cs);
|
||||
cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
|
||||
cfg.maxSimplificationError = m_edgeMaxError;
|
||||
cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
|
||||
cfg.tileSize = (int)m_tileSize;
|
||||
cfg.minRegionArea = rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
cfg.mergeRegionArea = rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
cfg.maxVertsPerPoly = m_vertsPerPoly;
|
||||
cfg.tileSize = m_tileSize;
|
||||
cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
|
||||
cfg.width = cfg.tileSize + cfg.borderSize*2;
|
||||
cfg.height = cfg.tileSize + cfg.borderSize*2;
|
||||
@ -1222,8 +1072,8 @@ bool Editor_TempObstacles::handleBuild()
|
||||
rcVcopy(tcparams.orig, bmin);
|
||||
tcparams.cs = m_cellSize;
|
||||
tcparams.ch = m_cellHeight;
|
||||
tcparams.width = (int)m_tileSize;
|
||||
tcparams.height = (int)m_tileSize;
|
||||
tcparams.width = m_tileSize;
|
||||
tcparams.height = m_tileSize;
|
||||
tcparams.walkableHeight = m_agentHeight;
|
||||
tcparams.walkableRadius = m_agentRadius;
|
||||
tcparams.walkableClimb = m_agentMaxClimb;
|
||||
@ -1266,7 +1116,7 @@ bool Editor_TempObstacles::handleBuild()
|
||||
status = m_navMesh->init(¶ms);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh.");
|
||||
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1300,7 +1150,7 @@ bool Editor_TempObstacles::handleBuild()
|
||||
status = m_tileCache->addTile(tile->data, tile->dataSize, DT_COMPRESSEDTILE_FREE_DATA, 0);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
dtFree(tile->data);
|
||||
rdFree(tile->data);
|
||||
tile->data = 0;
|
||||
continue;
|
||||
}
|
||||
@ -1361,7 +1211,7 @@ void Editor_TempObstacles::getTilePos(const float* pos, int& tx, int& ty)
|
||||
|
||||
const float ts = m_tileSize*m_cellSize;
|
||||
tx = (int)((pos[0] - bmin[0]) / ts);
|
||||
ty = (int)((pos[2] - bmin[2]) / ts);
|
||||
ty = (int)((pos[1] - bmin[1]) / ts);
|
||||
}
|
||||
|
||||
static const int TILECACHESET_MAGIC = 'T'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'TSET';
|
||||
@ -1487,14 +1337,14 @@ void Editor_TempObstacles::loadAll(const char* path)
|
||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||
break;
|
||||
|
||||
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
|
||||
unsigned char* data = (unsigned char*)rdAlloc(tileHeader.dataSize, RD_ALLOC_PERM);
|
||||
if (!data) break;
|
||||
memset(data, 0, tileHeader.dataSize);
|
||||
size_t tileDataReadReturnCode = fread(data, tileHeader.dataSize, 1, fp);
|
||||
if( tileDataReadReturnCode != 1)
|
||||
{
|
||||
// Error or early EOF
|
||||
dtFree(data);
|
||||
rdFree(data);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
@ -1503,7 +1353,7 @@ void Editor_TempObstacles::loadAll(const char* path)
|
||||
dtStatus addTileStatus = m_tileCache->addTile(data, tileHeader.dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tile);
|
||||
if (dtStatusFailed(addTileStatus))
|
||||
{
|
||||
dtFree(data);
|
||||
rdFree(data);
|
||||
}
|
||||
|
||||
if (tile)
|
||||
|
@ -37,30 +37,6 @@
|
||||
#include "game/server/ai_hull.h"
|
||||
|
||||
|
||||
inline unsigned int nextPow2(unsigned int v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline unsigned int ilog2(unsigned int v)
|
||||
{
|
||||
unsigned int r;
|
||||
unsigned int shift;
|
||||
r = (v > 0xffff) << 4; v >>= r;
|
||||
shift = (v > 0xff) << 3; v >>= shift; r |= shift;
|
||||
shift = (v > 0xf) << 2; v >>= shift; r |= shift;
|
||||
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
|
||||
r |= (v >> 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
class NavMeshTileTool : public EditorTool
|
||||
{
|
||||
Editor_TileMesh* m_editor;
|
||||
@ -165,20 +141,10 @@ public:
|
||||
|
||||
|
||||
Editor_TileMesh::Editor_TileMesh() :
|
||||
m_keepInterResults(false),
|
||||
m_buildAll(true),
|
||||
m_totalBuildTimeMs(0),
|
||||
m_triareas(0),
|
||||
m_solid(0),
|
||||
m_chf(0),
|
||||
m_cset(0),
|
||||
m_pmesh(0),
|
||||
m_dmesh(0),
|
||||
m_tileMeshDrawFlags(TM_DRAWFLAGS_INPUT_MESH|TM_DRAWFLAGS_NAVMESH),
|
||||
m_maxTiles(0),
|
||||
m_maxPolysPerTile(0),
|
||||
m_tileSize(32),
|
||||
m_tileCol(duRGBA(0,0,0,32)),
|
||||
m_tileBuildTime(0),
|
||||
m_tileMemUsage(0),
|
||||
m_tileTriCount(0)
|
||||
@ -190,6 +156,8 @@ Editor_TileMesh::Editor_TileMesh() :
|
||||
memset(m_lastBuiltTileBmax, 0, sizeof(m_lastBuiltTileBmax));
|
||||
|
||||
setTool(new NavMeshTileTool);
|
||||
|
||||
m_drawActiveTile = true;
|
||||
}
|
||||
|
||||
Editor_TileMesh::~Editor_TileMesh()
|
||||
@ -199,56 +167,8 @@ Editor_TileMesh::~Editor_TileMesh()
|
||||
m_navMesh = 0;
|
||||
}
|
||||
|
||||
void Editor_TileMesh::cleanup()
|
||||
{
|
||||
delete [] m_triareas;
|
||||
m_triareas = 0;
|
||||
rcFreeHeightField(m_solid);
|
||||
m_solid = 0;
|
||||
rcFreeCompactHeightfield(m_chf);
|
||||
m_chf = 0;
|
||||
rcFreeContourSet(m_cset);
|
||||
m_cset = 0;
|
||||
rcFreePolyMesh(m_pmesh);
|
||||
m_pmesh = 0;
|
||||
rcFreePolyMeshDetail(m_dmesh);
|
||||
m_dmesh = 0;
|
||||
}
|
||||
const hulldef hulls[NAVMESH_COUNT] = {
|
||||
{ g_navMeshNames[NAVMESH_SMALL] , NAI_Hull::Width(HULL_HUMAN) , NAI_Hull::Height(HULL_HUMAN) * NAI_Hull::Scale(HULL_HUMAN) , 45, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MED_SHORT] , NAI_Hull::Width(HULL_PROWLER), NAI_Hull::Height(HULL_PROWLER) * NAI_Hull::Scale(HULL_PROWLER), 50, 32 },
|
||||
{ g_navMeshNames[NAVMESH_MEDIUM] , NAI_Hull::Width(HULL_MEDIUM) , NAI_Hull::Height(HULL_MEDIUM) * NAI_Hull::Scale(HULL_MEDIUM) , 55, 32 },
|
||||
{ g_navMeshNames[NAVMESH_LARGE] , NAI_Hull::Width(HULL_TITAN) , NAI_Hull::Height(HULL_TITAN) * NAI_Hull::Scale(HULL_TITAN) , 60, 64 },
|
||||
{ g_navMeshNames[NAVMESH_EXTRA_LARGE], NAI_Hull::Width(HULL_GOLIATH), NAI_Hull::Height(HULL_GOLIATH) * NAI_Hull::Scale(HULL_GOLIATH), 65, 64 },
|
||||
};
|
||||
|
||||
void Editor_TileMesh::selectNavMeshType(const NavMeshType_e navMeshType)
|
||||
{
|
||||
const hulldef& h = hulls[navMeshType];
|
||||
|
||||
m_agentRadius = h.radius;
|
||||
m_agentMaxClimb = h.climbHeight;
|
||||
m_agentHeight = h.height;
|
||||
m_navmeshName = h.name;
|
||||
m_tileSize = h.tileSize;
|
||||
|
||||
m_selectedNavMeshType = navMeshType;
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleSettings()
|
||||
{
|
||||
ImGui::Text("NavMesh Type");
|
||||
for (int i = 0; i < NAVMESH_COUNT; i++)
|
||||
{
|
||||
const NavMeshType_e navMeshType = NavMeshType_e(i);
|
||||
|
||||
if (ImGui::Button(NavMesh_GetNameForType(navMeshType), ImVec2(120, 0)))
|
||||
{
|
||||
selectNavMeshType(navMeshType);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
Editor::handleCommonSettings();
|
||||
|
||||
ImGui::Text("Tiling");
|
||||
@ -257,80 +177,10 @@ void Editor_TileMesh::handleSettings()
|
||||
ImGui::Checkbox("Build All Tiles", &m_buildAll);
|
||||
ImGui::Checkbox("Keep Intermediate Results", &m_keepInterResults);
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
char text[128];
|
||||
int gw = 0, gh = 0;
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int ts = m_tileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
snprintf(text, sizeof(text), "Tiles: %d x %d", tw, th);
|
||||
ImGui::Text(text);
|
||||
snprintf(text, sizeof(text), "Tile Sizes: %g x %g (%g)", tw*m_cellSize, th*m_cellSize, m_tileSize*m_cellSize);
|
||||
ImGui::Text(text);
|
||||
// Max tiles and max polys affect how the tile IDs are calculated.
|
||||
// There are 28 bits available for identifying a tile and a polygon.
|
||||
int tileBits = rcMin((int)ilog2(nextPow2(tw*th)), 16);
|
||||
int polyBits = 28 - tileBits;
|
||||
m_maxTiles = 1 << tileBits;
|
||||
m_maxPolysPerTile = 1 << polyBits;
|
||||
snprintf(text, sizeof(text), "Max Tiles: %d", m_maxTiles);
|
||||
ImGui::Text(text);
|
||||
snprintf(text, sizeof(text), "Max Polys: %d", m_maxPolysPerTile);
|
||||
ImGui::Text(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maxTiles = 0;
|
||||
m_maxPolysPerTile = 0;
|
||||
}
|
||||
EditorCommon_SetAndRenderTileProperties(m_geom, m_tileSize, m_cellSize, m_maxTiles, m_maxPolysPerTile);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Indent();
|
||||
ImGui::Indent();
|
||||
|
||||
|
||||
if (ImGui::Button("Load", ImVec2(123, 0)))
|
||||
{
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = Editor::loadAll(m_modelName.c_str());
|
||||
m_navQuery->init(m_navMesh, 2048);
|
||||
|
||||
m_loadedNavMeshType = m_selectedNavMeshType;
|
||||
initToolStates(this);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Save", ImVec2(123, 0)))
|
||||
{
|
||||
Editor::saveAll(m_modelName.c_str(), m_navMesh);
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text("Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
|
||||
if (m_navMesh)
|
||||
{
|
||||
const dtNavMeshParams& params = m_navMesh->m_params;
|
||||
const float* origin = m_navMesh->m_orig;
|
||||
|
||||
ImGui::Text("Mesh Origin: \n\tX: %g \n\tY: %g \n\tZ: %g", origin[0], origin[1], origin[2]);
|
||||
ImGui::Text("Tile Dimensions: %g x %g", params.tileWidth, params.tileHeight);
|
||||
ImGui::Text("Poly Group Count: %d", params.polyGroupCount);
|
||||
ImGui::Text("Traversal Table Size: %d", params.traversalTableSize);
|
||||
ImGui::Text("Traversal Table Count: %d", params.traversalTableCount);
|
||||
ImGui::Text("Max Tiles: %d", params.maxTiles);
|
||||
ImGui::Text("Max Polys: %d", params.maxPolys);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
else
|
||||
ImGui::Separator();
|
||||
Editor_StaticTileMeshCommon::renderIntermediateTileMeshOptions();
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleTools()
|
||||
@ -385,313 +235,14 @@ void Editor_TileMesh::handleTools()
|
||||
|
||||
void Editor_TileMesh::handleDebugMode()
|
||||
{
|
||||
ImGui::Text("NavMesh Render Options");
|
||||
|
||||
bool isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (ImGui::Checkbox("Off-Mesh Connections", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_NODES);
|
||||
|
||||
if (ImGui::Checkbox("Query Nodes", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_NODES);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_BVTREE);
|
||||
|
||||
if (ImGui::Checkbox("BVTree", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_BVTREE);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_PORTALS);
|
||||
|
||||
if (ImGui::Checkbox("Portals", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_PORTALS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
if (ImGui::Checkbox("Closed List", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
if (ImGui::Checkbox("Tile ID Colors", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_COLOR_TILES);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
if (ImGui::Checkbox("Vertex Points", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_VERTS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Inner Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_INNERBOUND);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
if (ImGui::Checkbox("Outer Poly Boundaries", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_OUTERBOUND);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
if (ImGui::Checkbox("Poly Centers", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYCENTERS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
if (ImGui::Checkbox("Poly Group Colors", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLYGROUPS);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_DEPTH_MASK);
|
||||
|
||||
if (ImGui::Checkbox("Depth Mask", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_DEPTH_MASK);
|
||||
|
||||
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_ALPHA);
|
||||
|
||||
if (ImGui::Checkbox("Transparency", &isEnabled))
|
||||
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_ALPHA);
|
||||
|
||||
Editor::renderNavMeshDebugMenu();
|
||||
ImGui::Separator();
|
||||
ImGui::Text("TileMesh Render Options");
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_INPUT_MESH;
|
||||
|
||||
// This should always be available, since if we load a large mesh we want to
|
||||
// be able to toggle this off to save on performance. The renderer has to be
|
||||
// moved to its own thread to solve this issue.
|
||||
if (ImGui::Checkbox("Input Mesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_INPUT_MESH);
|
||||
|
||||
// Check which modes are valid.
|
||||
const bool hasNavMesh = m_navMesh != 0;
|
||||
const bool hasChf = m_chf != 0;
|
||||
const bool hasCset = m_cset != 0;
|
||||
const bool hasSolid = m_solid != 0;
|
||||
const bool hasDMesh = m_dmesh != 0;
|
||||
|
||||
const bool intermediateDataUnavailable = !hasChf||!hasCset||!hasSolid||!hasDMesh;
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_NAVMESH;
|
||||
ImGui::BeginDisabled(!hasNavMesh);
|
||||
|
||||
if (ImGui::Checkbox("NavMesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_NAVMESH);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_VOXELS;
|
||||
ImGui::BeginDisabled(!hasSolid);
|
||||
|
||||
if (ImGui::Checkbox("Voxels", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_VOXELS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_VOXELS_WALKABLE;
|
||||
ImGui::BeginDisabled(!hasSolid);
|
||||
|
||||
if (ImGui::Checkbox("Walkable Voxels", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_VOXELS_WALKABLE);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT_DISTANCE;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact Distance", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT_DISTANCE);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT_REGIONS;
|
||||
ImGui::BeginDisabled(!hasChf);
|
||||
|
||||
if (ImGui::Checkbox("Compact Regions", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_COMPACT_REGIONS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_REGION_CONNECTIONS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Region Connections", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_REGION_CONNECTIONS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_RAW_CONTOURS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Raw Contours", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_RAW_CONTOURS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_CONTOURS;
|
||||
ImGui::BeginDisabled(!hasCset);
|
||||
|
||||
if (ImGui::Checkbox("Contours", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_CONTOURS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_POLYMESH;
|
||||
ImGui::BeginDisabled(!hasDMesh);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_POLYMESH);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
isEnabled = m_tileMeshDrawFlags & TM_DRAWFLAGS_POLYMESH_DETAIL;
|
||||
ImGui::BeginDisabled(!hasDMesh);
|
||||
|
||||
if (ImGui::Checkbox("Poly Mesh Detail", &isEnabled))
|
||||
toggleTileMeshDrawFlag(TM_DRAWFLAGS_POLYMESH_DETAIL);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (intermediateDataUnavailable)
|
||||
{
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Tick 'Keep Intermediate Results'");
|
||||
ImGui::Text("rebuild some tiles to see");
|
||||
ImGui::Text("more debug mode options.");
|
||||
}
|
||||
Editor_StaticTileMeshCommon::renderTileMeshRenderOptions();
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleRender()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
|
||||
// Draw input mesh
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_INPUT_MESH)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&m_dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope, texScale);
|
||||
}
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// Draw bounds
|
||||
const float* bmin = m_geom->getNavMeshBoundsMin();
|
||||
const float* bmax = m_geom->getNavMeshBoundsMax();
|
||||
duDebugDrawBoxWire(&m_dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
|
||||
|
||||
// Tiling grid.
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
|
||||
const int tw = (gw + m_tileSize-1) / m_tileSize;
|
||||
const int th = (gh + m_tileSize-1) / m_tileSize;
|
||||
const float s = m_tileSize*m_cellSize;
|
||||
duDebugDrawGridXY(&m_dd, bmax[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
|
||||
|
||||
// Draw active tile
|
||||
duDebugDrawBoxWire(&m_dd, m_lastBuiltTileBmin[0],m_lastBuiltTileBmin[1],m_lastBuiltTileBmin[2],
|
||||
m_lastBuiltTileBmax[0],m_lastBuiltTileBmax[1],m_lastBuiltTileBmax[2], m_tileCol, 1.0f);
|
||||
|
||||
if (m_navMesh && m_navQuery)
|
||||
{
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_NAVMESH)
|
||||
{
|
||||
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
|
||||
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, duRGBA(0, 0, 0, 128));
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (m_chf)
|
||||
{
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT)
|
||||
duDebugDrawCompactHeightfieldSolid(&m_dd, *m_chf);
|
||||
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT_DISTANCE)
|
||||
duDebugDrawCompactHeightfieldDistance(&m_dd, *m_chf);
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_COMPACT_REGIONS)
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
}
|
||||
|
||||
if (m_solid)
|
||||
{
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_VOXELS)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldSolid(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_VOXELS_WALKABLE)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldWalkable(&m_dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_cset)
|
||||
{
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_RAW_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawContours(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_chf && m_cset) && (m_tileMeshDrawFlags & TM_DRAWFLAGS_REGION_CONNECTIONS))
|
||||
{
|
||||
duDebugDrawCompactHeightfieldRegions(&m_dd, *m_chf);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRegionConnections(&m_dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
if (m_pmesh && (m_tileMeshDrawFlags & TM_DRAWFLAGS_POLYMESH))
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMesh(&m_dd, *m_pmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
if (m_dmesh && (m_tileMeshDrawFlags & TM_DRAWFLAGS_POLYMESH_DETAIL))
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMeshDetail(&m_dd, *m_dmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
// TODO: also add flags for this
|
||||
m_geom->drawConvexVolumes(&m_dd);
|
||||
m_geom->drawOffMeshConnections(&m_dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
Editor_StaticTileMeshCommon::renderTileMeshData();
|
||||
}
|
||||
|
||||
void Editor_TileMesh::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
|
@ -120,6 +120,7 @@ protected:
|
||||
bool m_filterLedgeSpans;
|
||||
bool m_filterWalkableLowHeightSpans;
|
||||
|
||||
int m_tileSize;
|
||||
float m_cellSize;
|
||||
float m_cellHeight;
|
||||
float m_agentHeight;
|
||||
@ -198,6 +199,11 @@ public:
|
||||
void renderToolStates();
|
||||
void renderOverlayToolStates(double* proj, double* model, int* view);
|
||||
|
||||
void renderNavMeshDebugMenu();
|
||||
void renderIntermediateTileMeshOptions();
|
||||
|
||||
void selectNavMeshType(const NavMeshType_e navMeshType);
|
||||
|
||||
void resetCommonSettings();
|
||||
void handleCommonSettings();
|
||||
|
||||
|
113
src/naveditor/include/Editor_Common.h
Normal file
113
src/naveditor/include/Editor_Common.h
Normal file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef RECASTEDITORCOMMON_H
|
||||
#define RECASTEDITORCOMMON_H
|
||||
#include "Recast/Include/Recast.h"
|
||||
#include "NavEditor/Include/ChunkyTriMesh.h"
|
||||
|
||||
enum DrawTileMeshFlags
|
||||
{
|
||||
TM_DRAWFLAGS_INPUT_MESH = (1<<0),
|
||||
TM_DRAWFLAGS_NAVMESH = (1<<1),
|
||||
TM_DRAWFLAGS_VOXELS = (1<<2),
|
||||
TM_DRAWFLAGS_VOXELS_WALKABLE = (1<<3),
|
||||
TM_DRAWFLAGS_COMPACT = (1<<4),
|
||||
TM_DRAWFLAGS_COMPACT_DISTANCE = (1<<5),
|
||||
TM_DRAWFLAGS_COMPACT_REGIONS = (1<<6),
|
||||
TM_DRAWFLAGS_REGION_CONNECTIONS = (1<<7),
|
||||
TM_DRAWFLAGS_RAW_CONTOURS = (1<<8),
|
||||
TM_DRAWFLAGS_CONTOURS = (1<<9),
|
||||
TM_DRAWFLAGS_POLYMESH = (1<<10),
|
||||
TM_DRAWFLAGS_POLYMESH_DETAIL = (1<<11),
|
||||
TM_DRAWFLAGS_TILE_CACHE_BOUNDS = (1<<12),
|
||||
TM_DRAWFLAGS_TILE_CACHE_OBSTACLES = (1<<13),
|
||||
};
|
||||
|
||||
class Editor_StaticTileMeshCommon : public Editor
|
||||
{
|
||||
public:
|
||||
Editor_StaticTileMeshCommon();
|
||||
void cleanup();
|
||||
|
||||
void renderTileMeshRenderOptions();
|
||||
void renderTileMeshData();
|
||||
|
||||
void renderIntermediateTileMeshOptions();
|
||||
|
||||
inline unsigned int getTileMeshDrawFlags() const { return m_tileMeshDrawFlags; }
|
||||
inline void setTileMeshDrawFlags(unsigned int flags) { m_tileMeshDrawFlags = flags; }
|
||||
|
||||
inline void toggleTileMeshDrawFlag(unsigned int flag) { m_tileMeshDrawFlags ^= flag; }
|
||||
|
||||
protected:
|
||||
unsigned char* m_triareas;
|
||||
|
||||
rcHeightfield* m_solid;
|
||||
rcCompactHeightfield* m_chf;
|
||||
rcContourSet* m_cset;
|
||||
rcPolyMesh* m_pmesh;
|
||||
rcPolyMeshDetail* m_dmesh;
|
||||
rcConfig m_cfg;
|
||||
|
||||
unsigned int m_tileMeshDrawFlags;
|
||||
unsigned int m_tileCol;
|
||||
|
||||
float m_lastBuiltTileBmin[3];
|
||||
float m_lastBuiltTileBmax[3];
|
||||
|
||||
float m_totalBuildTimeMs;
|
||||
|
||||
bool m_drawActiveTile;
|
||||
bool m_keepInterResults;
|
||||
};
|
||||
|
||||
class Editor_DynamicTileMeshCommon : public Editor
|
||||
{
|
||||
public:
|
||||
Editor_DynamicTileMeshCommon();
|
||||
|
||||
void renderTileMeshRenderOptions();
|
||||
void renderTileMeshData();
|
||||
|
||||
inline unsigned int getTileMeshDrawFlags() const { return m_tileMeshDrawFlags; }
|
||||
inline void setTileMeshDrawFlags(unsigned int flags) { m_tileMeshDrawFlags = flags; }
|
||||
|
||||
inline void toggleTileMeshDrawFlag(unsigned int flag) { m_tileMeshDrawFlags ^= flag; }
|
||||
|
||||
protected:
|
||||
class dtTileCache* m_tileCache;
|
||||
struct LinearAllocator* m_talloc;
|
||||
struct FastLZCompressor* m_tcomp;
|
||||
struct MeshProcess* m_tmproc;
|
||||
|
||||
float m_cacheBuildTimeMs;
|
||||
int m_cacheCompressedSize;
|
||||
int m_cacheRawSize;
|
||||
int m_cacheLayerCount;
|
||||
|
||||
unsigned int m_cacheBuildMemUsage;
|
||||
unsigned int m_tileMeshDrawFlags;
|
||||
|
||||
bool m_keepInterResults;
|
||||
};
|
||||
|
||||
int EditorCommon_SetAndRenderTileProperties(const InputGeom* const geom, const int tileSize,
|
||||
const float cellSize, int& maxTiles, int& maxPolysPerTile);
|
||||
|
||||
#endif // RECASTEDITORCOMMON_H
|
@ -16,51 +16,17 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTSAMPLESOLOMESH_H
|
||||
#define RECASTSAMPLESOLOMESH_H
|
||||
#ifndef RECASTEDITORSOLOMESH_H
|
||||
#define RECASTEDITORSOLOMESH_H
|
||||
|
||||
#include "Recast/Include/Recast.h"
|
||||
#include "Detour/Include/DetourNavMesh.h"
|
||||
#include "NavEditor/Include/Sample.h"
|
||||
#include "NavEditor/Include/Editor.h"
|
||||
#include "NavEditor/Include/Editor_Common.h"
|
||||
|
||||
class Editor_SoloMesh : public Sample
|
||||
class Editor_SoloMesh : public Editor_StaticTileMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool m_keepInterResults;
|
||||
float m_totalBuildTimeMs;
|
||||
|
||||
unsigned char* m_triareas;
|
||||
rcHeightfield* m_solid;
|
||||
rcCompactHeightfield* m_chf;
|
||||
rcContourSet* m_cset;
|
||||
rcPolyMesh* m_pmesh;
|
||||
rcConfig m_cfg;
|
||||
rcPolyMeshDetail* m_dmesh;
|
||||
|
||||
enum DrawMode
|
||||
{
|
||||
DRAWMODE_NAVMESH,
|
||||
DRAWMODE_NAVMESH_TRANS,
|
||||
DRAWMODE_NAVMESH_BVTREE,
|
||||
DRAWMODE_NAVMESH_NODES,
|
||||
DRAWMODE_NAVMESH_INVIS,
|
||||
DRAWMODE_MESH,
|
||||
DRAWMODE_VOXELS,
|
||||
DRAWMODE_VOXELS_WALKABLE,
|
||||
DRAWMODE_COMPACT,
|
||||
DRAWMODE_COMPACT_DISTANCE,
|
||||
DRAWMODE_COMPACT_REGIONS,
|
||||
DRAWMODE_REGION_CONNECTIONS,
|
||||
DRAWMODE_RAW_CONTOURS,
|
||||
DRAWMODE_BOTH_CONTOURS,
|
||||
DRAWMODE_CONTOURS,
|
||||
DRAWMODE_POLYMESH,
|
||||
DRAWMODE_POLYMESH_DETAIL,
|
||||
MAX_DRAWMODE
|
||||
};
|
||||
|
||||
DrawMode m_drawMode;
|
||||
|
||||
void cleanup();
|
||||
|
||||
public:
|
||||
@ -83,4 +49,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // RECASTSAMPLESOLOMESHSIMPLE_H
|
||||
#endif // RECASTEDITORSOLOMESH_H
|
||||
|
@ -16,50 +16,21 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTSAMPLETEMPOBSTACLE_H
|
||||
#define RECASTSAMPLETEMPOBSTACLE_H
|
||||
#ifndef RECASTEDITORTEMPOBSTACLE_H
|
||||
#define RECASTEDITORTEMPOBSTACLE_H
|
||||
|
||||
#include "Recast/Include/Recast.h"
|
||||
#include "Detour/Include/DetourNavMesh.h"
|
||||
#include "NavEditor/Include/ChunkyTriMesh.h"
|
||||
#include "NavEditor/Include/Sample.h"
|
||||
#include "NavEditor/Include/Editor.h"
|
||||
#include "NavEditor/Include/Editor_Common.h"
|
||||
|
||||
|
||||
class Editor_TempObstacles : public Sample
|
||||
class Editor_TempObstacles : public Editor_DynamicTileMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool m_keepInterResults;
|
||||
|
||||
struct LinearAllocator* m_talloc;
|
||||
struct FastLZCompressor* m_tcomp;
|
||||
struct MeshProcess* m_tmproc;
|
||||
|
||||
class dtTileCache* m_tileCache;
|
||||
|
||||
float m_cacheBuildTimeMs;
|
||||
int m_cacheCompressedSize;
|
||||
int m_cacheRawSize;
|
||||
int m_cacheLayerCount;
|
||||
unsigned int m_cacheBuildMemUsage;
|
||||
|
||||
enum DrawMode
|
||||
{
|
||||
DRAWMODE_NAVMESH,
|
||||
DRAWMODE_NAVMESH_TRANS,
|
||||
DRAWMODE_NAVMESH_BVTREE,
|
||||
DRAWMODE_NAVMESH_NODES,
|
||||
DRAWMODE_NAVMESH_PORTALS,
|
||||
DRAWMODE_NAVMESH_INVIS,
|
||||
DRAWMODE_MESH,
|
||||
DRAWMODE_CACHE_BOUNDS,
|
||||
MAX_DRAWMODE
|
||||
};
|
||||
|
||||
DrawMode m_drawMode;
|
||||
|
||||
int m_maxTiles;
|
||||
int m_maxPolysPerTile;
|
||||
float m_tileSize;
|
||||
|
||||
public:
|
||||
Editor_TempObstacles();
|
||||
@ -95,4 +66,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // RECASTSAMPLETEMPOBSTACLE_H
|
||||
#endif // RECASTEDITORTEMPOBSTACLE_H
|
||||
|
@ -16,62 +16,30 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTSAMPLETILEMESH_H
|
||||
#define RECASTSAMPLETILEMESH_H
|
||||
#ifndef RECASTEDITORTILEMESH_H
|
||||
#define RECASTEDITORTILEMESH_H
|
||||
|
||||
#include "Recast/Include/Recast.h"
|
||||
#include "Detour/Include/DetourNavMesh.h"
|
||||
#include "NavEditor/Include/ChunkyTriMesh.h"
|
||||
#include "NavEditor/Include/Editor.h"
|
||||
#include "NavEditor/Include/Editor_Common.h"
|
||||
|
||||
class Editor_TileMesh : public Editor
|
||||
class Editor_TileMesh : public Editor_StaticTileMeshCommon
|
||||
{
|
||||
protected:
|
||||
bool m_keepInterResults;
|
||||
bool m_buildAll;
|
||||
float m_totalBuildTimeMs;
|
||||
|
||||
unsigned char* m_triareas;
|
||||
rcHeightfield* m_solid;
|
||||
rcCompactHeightfield* m_chf;
|
||||
rcContourSet* m_cset;
|
||||
rcPolyMesh* m_pmesh;
|
||||
rcPolyMeshDetail* m_dmesh;
|
||||
rcConfig m_cfg;
|
||||
|
||||
enum DrawTileMeshFlags
|
||||
{
|
||||
TM_DRAWFLAGS_INPUT_MESH = (1<<0),
|
||||
TM_DRAWFLAGS_NAVMESH = (1<<1),
|
||||
TM_DRAWFLAGS_VOXELS = (1<<2),
|
||||
TM_DRAWFLAGS_VOXELS_WALKABLE = (1<<3),
|
||||
TM_DRAWFLAGS_COMPACT = (1<<4),
|
||||
TM_DRAWFLAGS_COMPACT_DISTANCE = (1<<5),
|
||||
TM_DRAWFLAGS_COMPACT_REGIONS = (1<<6),
|
||||
TM_DRAWFLAGS_REGION_CONNECTIONS = (1<<7),
|
||||
TM_DRAWFLAGS_RAW_CONTOURS = (1<<8),
|
||||
TM_DRAWFLAGS_CONTOURS = (1<<9),
|
||||
TM_DRAWFLAGS_POLYMESH = (1<<10),
|
||||
TM_DRAWFLAGS_POLYMESH_DETAIL = (1<<11),
|
||||
};
|
||||
|
||||
unsigned int m_tileMeshDrawFlags;
|
||||
|
||||
int m_maxTiles;
|
||||
int m_maxPolysPerTile;
|
||||
int m_tileSize;
|
||||
|
||||
unsigned int m_tileCol;
|
||||
float m_lastBuiltTileBmin[3];
|
||||
float m_lastBuiltTileBmax[3];
|
||||
float m_tileBuildTime;
|
||||
float m_tileMemUsage;
|
||||
int m_tileTriCount;
|
||||
|
||||
unsigned char* buildTileMesh(const int tx, const int ty, const float* bmin, const float* bmax, int& dataSize);
|
||||
|
||||
void cleanup();
|
||||
|
||||
void saveAll(const char* path, const dtNavMesh* mesh);
|
||||
dtNavMesh* loadAll(const char* path);
|
||||
|
||||
@ -87,13 +55,6 @@ public:
|
||||
virtual void handleMeshChanged(class InputGeom* geom);
|
||||
virtual bool handleBuild();
|
||||
virtual void collectSettings(struct BuildSettings& settings);
|
||||
|
||||
void selectNavMeshType(const NavMeshType_e navMeshType);
|
||||
|
||||
inline unsigned int getTileMeshDrawFlags() const { return m_tileMeshDrawFlags; }
|
||||
inline void setTileMeshDrawFlags(unsigned int flags) { m_tileMeshDrawFlags = flags; }
|
||||
|
||||
inline void toggleTileMeshDrawFlag(unsigned int flag) { m_tileMeshDrawFlags ^= flag; }
|
||||
|
||||
void getTilePos(const float* pos, int& tx, int& ty);
|
||||
void getTileExtents(int tx, int ty, float* bmin, float* bmax);
|
||||
@ -111,4 +72,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // RECASTSAMPLETILEMESH_H
|
||||
#endif // RECASTEDITORTILEMESH_H
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "NavEditor/Include/InputGeom.h"
|
||||
#include "NavEditor/Include/TestCase.h"
|
||||
#include "NavEditor/Include/Filelist.h"
|
||||
#include "NavEditor/Include/Editor_SoloMesh.h"
|
||||
#include "NavEditor/Include/Editor_TileMesh.h"
|
||||
#include "NavEditor/Include/Editor_Debug.h"
|
||||
#include "NavEditor/include/DroidSans.h"
|
||||
@ -36,6 +37,7 @@ struct SampleItem
|
||||
Editor* (*create)();
|
||||
const string name;
|
||||
};
|
||||
Editor* createSolo() { return new Editor_SoloMesh(); }
|
||||
Editor* createTile() { return new Editor_TileMesh(); }
|
||||
Editor* createDebug() { return new Editor_Debug(); }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user