Fixing RecastDemo

This commit is contained in:
Mikko Mononen 2009-04-11 17:57:09 +00:00
parent b93fe6b29a
commit a2a85ede2b
4 changed files with 410 additions and 74 deletions

View File

@ -34,8 +34,8 @@
PBXFileDataSource_Target_ColumnID, PBXFileDataSource_Target_ColumnID,
); );
}; };
PBXPerProjectTemplateStateSaveDate = 260033439; PBXPerProjectTemplateStateSaveDate = 261165315;
PBXWorkspaceStateSaveDate = 260033439; PBXWorkspaceStateSaveDate = 261165315;
}; };
perUserProjectItems = { perUserProjectItems = {
6B8633370F7813A600E2684A /* PBXTextBookmark */ = 6B8633370F7813A600E2684A /* PBXTextBookmark */; 6B8633370F7813A600E2684A /* PBXTextBookmark */ = 6B8633370F7813A600E2684A /* PBXTextBookmark */;

View File

@ -280,8 +280,8 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>13</integer> <integer>2</integer>
<integer>12</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
@ -373,7 +373,9 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {864, 0}}</string> <string>{{10, 27}, {864, 176}}</string>
<key>RubberWindowFrame</key>
<string>55 112 1071 654 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>XCDetailModule</string> <string>XCDetailModule</string>
@ -428,8 +430,6 @@
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {864, 176}}</string> <string>{{10, 27}, {864, 176}}</string>
<key>RubberWindowFrame</key>
<string>55 112 1071 654 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXBuildResultsModule</string> <string>PBXBuildResultsModule</string>
@ -457,11 +457,11 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B137C980F7FCC4700459200</string> <string>6BDD9E120F91114E00904EEF</string>
<string>1CA23ED40692098700951B8B</string> <string>1CA23ED40692098700951B8B</string>
<string>6B137C990F7FCC4700459200</string> <string>6BDD9E130F91114E00904EEF</string>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<string>6B137C9A0F7FCC4700459200</string> <string>6BDD9E140F91114E00904EEF</string>
<string>1CA23EDF0692099D00951B8B</string> <string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string> <string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string> <string>1CA23EE10692099D00951B8B</string>
@ -608,14 +608,14 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B137C9B0F7FCC4700459200</string> <string>6BDD9E150F91114E00904EEF</string>
<string>1CCC7628064C1048000F2A68</string> <string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string> <string>1CCC7629064C1048000F2A68</string>
<string>6B137C9C0F7FCC4700459200</string> <string>6BDD9E160F91114E00904EEF</string>
<string>6B137C9D0F7FCC4700459200</string> <string>6BDD9E170F91114E00904EEF</string>
<string>6B137C9E0F7FCC4700459200</string> <string>6BDD9E180F91114E00904EEF</string>
<string>6B137C9F0F7FCC4700459200</string> <string>6BDD9E190F91114E00904EEF</string>
<string>6B137CA00F7FCC4700459200</string> <string>6BDD9E1A0F91114E00904EEF</string>
</array> </array>
<key>ToolbarConfiguration</key> <key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string> <string>xcode.toolbar.config.debugV3</string>

View File

@ -24,6 +24,9 @@
6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */; }; 6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */; };
6B8632DA0F78122C00E2684A /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632D90F78122C00E2684A /* SDL.framework */; }; 6B8632DA0F78122C00E2684A /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632D90F78122C00E2684A /* SDL.framework */; };
6B8632DC0F78123E00E2684A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632DB0F78123E00E2684A /* OpenGL.framework */; }; 6B8632DC0F78123E00E2684A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632DB0F78123E00E2684A /* OpenGL.framework */; };
6BDD9E0A0F91113800904EEF /* DetourDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; };
6BDD9E0B0F91113800904EEF /* DetourStatNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; };
6BDD9E0C0F91113800904EEF /* DetourStatNavMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; };
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -60,6 +63,12 @@
6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastTimer.cpp; path = ../../../Recast/Source/RecastTimer.cpp; sourceTree = SOURCE_ROOT; }; 6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastTimer.cpp; path = ../../../Recast/Source/RecastTimer.cpp; sourceTree = SOURCE_ROOT; };
6B8632D90F78122C00E2684A /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = Library/Frameworks/SDL.framework; sourceTree = SDKROOT; }; 6B8632D90F78122C00E2684A /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = Library/Frameworks/SDL.framework; sourceTree = SDKROOT; };
6B8632DB0F78123E00E2684A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 6B8632DB0F78123E00E2684A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
6BDD9E040F91112200904EEF /* DetourDebugDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourDebugDraw.h; path = ../../../Detour/Include/DetourDebugDraw.h; sourceTree = SOURCE_ROOT; };
6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourStatNavMesh.h; path = ../../../Detour/Include/DetourStatNavMesh.h; sourceTree = SOURCE_ROOT; };
6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourStatNavMeshBuilder.h; path = ../../../Detour/Include/DetourStatNavMeshBuilder.h; sourceTree = SOURCE_ROOT; };
6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DetourDebugDraw.cpp; path = ../../../Detour/Source/DetourDebugDraw.cpp; sourceTree = SOURCE_ROOT; };
6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DetourStatNavMesh.cpp; path = ../../../Detour/Source/DetourStatNavMesh.cpp; sourceTree = SOURCE_ROOT; };
6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DetourStatNavMeshBuilder.cpp; path = ../../../Detour/Source/DetourStatNavMeshBuilder.cpp; sourceTree = SOURCE_ROOT; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* Recast.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recast.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107320486CEB800E47090 /* Recast.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recast.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -81,6 +90,7 @@
080E96DDFE201D6D7F000001 /* Classes */ = { 080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6BDD9E030F91110C00904EEF /* Detour */,
6B137C7D0F7FCBE800459200 /* Recast */, 6B137C7D0F7FCBE800459200 /* Recast */,
6B137C790F7FCBE400459200 /* glfont.h */, 6B137C790F7FCBE400459200 /* glfont.h */,
6B137C7A0F7FCBE400459200 /* imgui.h */, 6B137C7A0F7FCBE400459200 /* imgui.h */,
@ -182,6 +192,19 @@
name = Recast; name = Recast;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6BDD9E030F91110C00904EEF /* Detour */ = {
isa = PBXGroup;
children = (
6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */,
6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */,
6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */,
6BDD9E040F91112200904EEF /* DetourDebugDraw.h */,
6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */,
6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */,
);
name = Detour;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -251,6 +274,9 @@
6B137C910F7FCC1100459200 /* RecastRasterization.cpp in Sources */, 6B137C910F7FCC1100459200 /* RecastRasterization.cpp in Sources */,
6B137C920F7FCC1100459200 /* RecastRegion.cpp in Sources */, 6B137C920F7FCC1100459200 /* RecastRegion.cpp in Sources */,
6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */, 6B137C930F7FCC1100459200 /* RecastTimer.cpp in Sources */,
6BDD9E0A0F91113800904EEF /* DetourDebugDraw.cpp in Sources */,
6BDD9E0B0F91113800904EEF /* DetourStatNavMesh.cpp in Sources */,
6BDD9E0C0F91113800904EEF /* DetourStatNavMeshBuilder.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -35,6 +35,10 @@
#include "RecastLog.h" #include "RecastLog.h"
#include "RecastDebugDraw.h" #include "RecastDebugDraw.h"
#include "imgui.h" #include "imgui.h"
#include "DetourStatNavMesh.h"
#include "DetourStatNavMeshBuilder.h"
#include "DetourDebugDraw.h"
#ifdef WIN32 #ifdef WIN32
# define snprintf _snprintf # define snprintf _snprintf
@ -148,21 +152,21 @@ void scanDirectory(const char* path, const char* ext, FileList& list)
list.clear(); list.clear();
#ifdef WIN32 #ifdef WIN32
_finddata_t dir; _finddata_t dir;
char pathWithExt[MAX_PATH]; char pathWithExt[MAX_PATH];
long fh; long fh;
strcpy(pathWithExt, path); strcpy(pathWithExt, path);
strcat(pathWithExt, "/*"); strcat(pathWithExt, "/*");
strcat(pathWithExt, ext); strcat(pathWithExt, ext);
fh = _findfirst(pathWithExt, &dir); fh = _findfirst(pathWithExt, &dir);
if (fh == -1L) if (fh == -1L)
return; return;
do do
{ {
list.add(dir.name); list.add(dir.name);
} }
while (_findnext(fh, &dir) == 0); while (_findnext(fh, &dir) == 0);
_findclose(fh); _findclose(fh);
#else #else
dirent* current = 0; dirent* current = 0;
DIR* dp = opendir(path); DIR* dp = opendir(path);
@ -184,8 +188,9 @@ void scanDirectory(const char* path, const char* ext, FileList& list)
enum DrawMode enum DrawMode
{ {
DRAWMODE_POLYMESH, DRAWMODE_NAVMESH,
DRAWMODE_POLYMESH_TRANS, DRAWMODE_NAVMESH_TRANS,
DRAWMODE_NAVMESH_BVTREE,
DRAWMODE_MESH, DRAWMODE_MESH,
DRAWMODE_VOXELS, DRAWMODE_VOXELS,
DRAWMODE_VOXELS_WALKABLE, DRAWMODE_VOXELS_WALKABLE,
@ -194,7 +199,14 @@ enum DrawMode
DRAWMODE_COMPACT_REGIONS, DRAWMODE_COMPACT_REGIONS,
DRAWMODE_RAW_CONTOURS, DRAWMODE_RAW_CONTOURS,
DRAWMODE_CONTOURS, DRAWMODE_CONTOURS,
MAX_DRAWMODE, };
enum ToolMode
{
TOOLMODE_PATHFIND,
TOOLMODE_RAYCAST,
TOOLMODE_DISTANCE_TO_WALL,
TOOLMODE_FIND_POLYS_AROUND,
}; };
@ -215,9 +227,11 @@ rcHeightfield* g_solid = 0;
rcCompactHeightfield* g_chf = 0; rcCompactHeightfield* g_chf = 0;
rcContourSet* g_cset = 0; rcContourSet* g_cset = 0;
rcPolyMesh* g_polyMesh = 0; rcPolyMesh* g_polyMesh = 0;
dtStatNavMesh* g_navMesh = 0;
rcConfig g_cfg; rcConfig g_cfg;
rcLog g_log; rcLog g_log;
static bool buildNavigation() static bool buildNavigation()
{ {
delete g_solid; delete g_solid;
@ -225,11 +239,13 @@ static bool buildNavigation()
delete g_cset; delete g_cset;
delete g_polyMesh; delete g_polyMesh;
delete [] g_triangleFlags; delete [] g_triangleFlags;
delete g_navMesh;
g_solid = 0; g_solid = 0;
g_chf = 0; g_chf = 0;
g_cset = 0; g_cset = 0;
g_polyMesh = 0; g_polyMesh = 0;
g_triangleFlags = 0; g_triangleFlags = 0;
g_navMesh = 0;
g_log.clear(); g_log.clear();
rcSetLog(&g_log); rcSetLog(&g_log);
@ -241,6 +257,10 @@ static bool buildNavigation()
} }
// TODO: Handle better.
g_cfg.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
rcCalcBounds(g_mesh->getVerts(), g_mesh->getVertCount(), g_cfg.bmin, g_cfg.bmax); rcCalcBounds(g_mesh->getVerts(), g_mesh->getVertCount(), g_cfg.bmin, g_cfg.bmax);
@ -277,6 +297,29 @@ static bool buildNavigation()
g_polyMesh->npolys*g_polyMesh->nvp*2*sizeof(unsigned short); g_polyMesh->npolys*g_polyMesh->nvp*2*sizeof(unsigned short);
g_log.log(RC_LOG_PROGRESS, " - Approx data size %.1f kB", (float)navMeshDataSize/1024.f); g_log.log(RC_LOG_PROGRESS, " - Approx data size %.1f kB", (float)navMeshDataSize/1024.f);
unsigned char* navData = 0;
int navDataSize = 0;
if (!dtCreateNavMeshData(g_polyMesh->verts, g_polyMesh->nverts,
g_polyMesh->polys, g_polyMesh->npolys, g_polyMesh->nvp,
g_cfg.bmin, g_cfg.bmax, g_cfg.cs, g_cfg.ch, &navData, &navDataSize))
{
g_log.log(RC_LOG_ERROR, "Could not build Detour navmesh.");
return false;
}
g_navMesh = new dtStatNavMesh;
if (!g_navMesh)
{
g_log.log(RC_LOG_ERROR, "Out of memory 'g_navMesh'");
return false;
}
if (!g_navMesh->init(navData, navDataSize, true))
{
g_log.log(RC_LOG_ERROR, "Could not init Detour navmesh");
return false;
}
for (int i = 0; i < g_log.getMessageCount(); ++i) for (int i = 0; i < g_log.getMessageCount(); ++i)
{ {
printf("%s\n", g_log.getMessageText(i)); printf("%s\n", g_log.getMessageText(i));
@ -316,7 +359,7 @@ int main(int argc, char *argv[])
if(!g_font.create("font.cfnt")) if(!g_font.create("font.cfnt"))
{ {
printf("Could not load font\n"); printf("Could not load font.\n");
SDL_Quit(); SDL_Quit();
return -1; return -1;
} }
@ -332,13 +375,24 @@ int main(int argc, char *argv[])
float edgeMaxLen = 12.0f; float edgeMaxLen = 12.0f;
float edgeMaxError = 1.5f; float edgeMaxError = 1.5f;
float vertsPerPoly = 6.0f; float vertsPerPoly = 6.0f;
int drawMode = DRAWMODE_POLYMESH; int drawMode = DRAWMODE_NAVMESH;
int toolMode = TOOLMODE_PATHFIND;
bool showLevels = false; bool showLevels = false;
bool showLog = false; bool showLog = false;
char curLevel[256] = "Choose Level..."; char curLevel[256] = "Choose Level...";
bool mouseOverMenu = false; bool mouseOverMenu = false;
FileList fileList; FileList fileList;
dtPolyRef startRef = 0, endRef = 0;
const float polyPickExt[3] = {2,4,2};
static const int MAX_POLYS = 256;
dtPolyRef polys[MAX_POLYS];
int npolys = 0;
float straightPath[MAX_POLYS*3];
int nstraightPath = 0;
float t = 0.0f; float t = 0.0f;
Uint32 lastTime = SDL_GetTicks(); Uint32 lastTime = SDL_GetTicks();
int mx = 0, my = 0; int mx = 0, my = 0;
@ -351,6 +405,14 @@ int main(int argc, char *argv[])
bool rotate = false; bool rotate = false;
float rays[3], raye[3]; float rays[3], raye[3];
float spos[3] = {0,0,0}; float spos[3] = {0,0,0};
float epos[3] = {0,0,0};
float hitPos[3] = {0,0,0};
float hitNormal[3] = {0,0,0};
float distanceToWall = 0;
bool sposSet = false, eposSet = false;
static const float startCol[4] = { 0.6f, 0.1f, 0.1f, 0.75f };
static const float endCol[4] = { 0.1f, 0.6f, 0.1f, 0.75f };
bool recalcTool = false;
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@ -382,7 +444,7 @@ int main(int argc, char *argv[])
// Handle mouse clicks here. // Handle mouse clicks here.
if (!mouseOverMenu) if (!mouseOverMenu)
{ {
if (event.button.button == SDL_BUTTON_LEFT) if (event.button.button == SDL_BUTTON_RIGHT)
{ {
// Rotate view // Rotate view
rotate = true; rotate = true;
@ -391,7 +453,7 @@ int main(int argc, char *argv[])
origrx = rx; origrx = rx;
origry = ry; origry = ry;
} }
else if (event.button.button == SDL_BUTTON_RIGHT) else if (event.button.button == SDL_BUTTON_LEFT)
{ {
// Hit test mesh. // Hit test mesh.
if (g_mesh) if (g_mesh)
@ -399,9 +461,24 @@ int main(int argc, char *argv[])
float t; float t;
if (raycast(*g_mesh, rays, raye, t)) if (raycast(*g_mesh, rays, raye, t))
{ {
spos[0] = rays[0] + (raye[0] - rays[0])*t; if (SDL_GetModState() & KMOD_SHIFT)
spos[1] = rays[1] + (raye[1] - rays[1])*t; {
spos[2] = rays[2] + (raye[2] - rays[2])*t; sposSet = true;
spos[0] = rays[0] + (raye[0] - rays[0])*t;
spos[1] = rays[1] + (raye[1] - rays[1])*t;
spos[2] = rays[2] + (raye[2] - rays[2])*t;
startRef = g_navMesh->findNearestPoly(spos, polyPickExt);
recalcTool = true;
}
else
{
eposSet = true;
epos[0] = rays[0] + (raye[0] - rays[0])*t;
epos[1] = rays[1] + (raye[1] - rays[1])*t;
epos[2] = rays[2] + (raye[2] - rays[2])*t;
endRef = g_navMesh->findNearestPoly(epos, polyPickExt);
recalcTool = true;
}
} }
} }
} }
@ -410,7 +487,7 @@ int main(int argc, char *argv[])
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
// Handle mouse clicks here. // Handle mouse clicks here.
if(event.button.button == SDL_BUTTON_LEFT) if(event.button.button == SDL_BUTTON_RIGHT)
{ {
rotate = false; rotate = false;
} }
@ -505,18 +582,152 @@ int main(int argc, char *argv[])
if (g_mesh) if (g_mesh)
rcDebugDrawMesh(*g_mesh, g_triangleFlags); rcDebugDrawMesh(*g_mesh, g_triangleFlags);
} }
else if (drawMode != DRAWMODE_POLYMESH_TRANS) else if (drawMode != DRAWMODE_NAVMESH_TRANS)
{ {
if (g_mesh) if (g_mesh)
rcDebugDrawMesh(*g_mesh, 0); rcDebugDrawMesh(*g_mesh, 0);
} }
if (g_mesh)
{
// Agent dimensions.
const float r = agentRadius;
const float h = agentHeight;
float col[4];
for (int i = 0; i < 2; ++i)
{
const float* pos = 0;
const float* c = 0;
if (i == 0 && sposSet)
{
pos = spos;
c = startCol;
}
else if (i == 1 && eposSet)
{
pos = epos;
c = endCol;
}
if (!pos)
continue;
glLineWidth(2.0f);
rcDebugDrawCylinderWire(pos[0]-r, pos[1]+0.02f, pos[2]-r, pos[0]+r, pos[1]+h, pos[2]+r, c);
glLineWidth(1.0f);
glColor4ub(0,0,0,196);
glBegin(GL_LINES);
glVertex3f(pos[0], pos[1]-agentMaxClimb, pos[2]);
glVertex3f(pos[0], pos[1]+agentMaxClimb, pos[2]);
glVertex3f(pos[0]-r/2, pos[1]+0.02f, pos[2]);
glVertex3f(pos[0]+r/2, pos[1]+0.02f, pos[2]);
glVertex3f(pos[0], pos[1]+0.02f, pos[2]-r/2);
glVertex3f(pos[0], pos[1]+0.02f, pos[2]+r/2);
glEnd();
}
// Mesh bbox.
col[0] = 1.0f; col[1] = 1.0f; col[2] = 1.0f; col[3] = 0.25f;
rcDebugDrawBoxWire(g_cfg.bmin[0], g_cfg.bmin[1], g_cfg.bmin[2],
g_cfg.bmax[0], g_cfg.bmax[1], g_cfg.bmax[2], col);
}
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
if (drawMode == DRAWMODE_POLYMESH || drawMode == DRAWMODE_POLYMESH_TRANS) if (drawMode == DRAWMODE_NAVMESH || drawMode == DRAWMODE_NAVMESH_TRANS || drawMode == DRAWMODE_NAVMESH_BVTREE)
{ {
if (g_polyMesh) if (g_navMesh)
rcDebugDrawPolyMesh(*g_polyMesh, g_cfg.bmin, g_cfg.cs, g_cfg.ch); {
dtDebugDrawStatNavMesh(g_navMesh);
if (toolMode == TOOLMODE_PATHFIND)
{
dtDebugDrawStatNavMeshPoly(g_navMesh, startRef, startCol);
dtDebugDrawStatNavMeshPoly(g_navMesh, endRef, endCol);
if (npolys)
{
const float pathCol[4] = {1,0.75f,0,0.25f};
for (int i = 1; i < npolys-1; ++i)
dtDebugDrawStatNavMeshPoly(g_navMesh, polys[i], pathCol);
}
if (nstraightPath)
{
glColor4ub(220,16,0,220);
glLineWidth(3.0f);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < nstraightPath; ++i)
glVertex3f(straightPath[i*3], straightPath[i*3+1]+0.4f, straightPath[i*3+2]);
glEnd();
glLineWidth(1.0f);
glPointSize(4.0f);
glBegin(GL_POINTS);
for (int i = 0; i < nstraightPath; ++i)
glVertex3f(straightPath[i*3], straightPath[i*3+1]+0.4f, straightPath[i*3+2]);
glEnd();
glPointSize(1.0f);
}
}
else if (toolMode == TOOLMODE_RAYCAST)
{
dtDebugDrawStatNavMeshPoly(g_navMesh, startRef, startCol);
if (nstraightPath)
{
const float pathCol[4] = {1,0.75f,0,0.25f};
dtDebugDrawStatNavMeshPoly(g_navMesh, polys[0], pathCol);
glColor4ub(220,16,0,220);
glLineWidth(3.0f);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < nstraightPath; ++i)
glVertex3f(straightPath[i*3], straightPath[i*3+1]+0.4f, straightPath[i*3+2]);
glEnd();
glLineWidth(1.0f);
glPointSize(4.0f);
glBegin(GL_POINTS);
for (int i = 0; i < nstraightPath; ++i)
glVertex3f(straightPath[i*3], straightPath[i*3+1]+0.4f, straightPath[i*3+2]);
glEnd();
glPointSize(1.0f);
}
}
else if (toolMode == TOOLMODE_DISTANCE_TO_WALL)
{
dtDebugDrawStatNavMeshPoly(g_navMesh, startRef, startCol);
const float col[4] = {1,1,1,0.5f};
rcDebugDrawCylinderWire(spos[0]-distanceToWall, spos[1]+0.02f, spos[2]-distanceToWall,
spos[0]+distanceToWall, spos[1]+agentHeight, spos[2]+distanceToWall, col);
glLineWidth(3.0f);
glColor4fv(col);
glBegin(GL_LINES);
glVertex3f(hitPos[0], hitPos[1] + 0.02f, hitPos[2]);
glVertex3f(hitPos[0], hitPos[1] + agentHeight, hitPos[2]);
glEnd();
glLineWidth(1.0f);
}
else if (toolMode == TOOLMODE_FIND_POLYS_AROUND)
{
const float pathCol[4] = {1,0.75f,0,0.25f};
for (int i = 0; i < npolys; ++i)
dtDebugDrawStatNavMeshPoly(g_navMesh, polys[i], pathCol);
const float dx = epos[0] - spos[0];
const float dz = epos[2] - spos[2];
float dist = sqrtf(dx*dx + dz*dz);
const float col[4] = {1,1,1,0.5f};
rcDebugDrawCylinderWire(spos[0]-dist, spos[1]+0.02f, spos[2]-dist,
spos[0]+dist, spos[1]+agentHeight, spos[2]+dist, col);
}
}
}
if (drawMode == DRAWMODE_NAVMESH_BVTREE)
{
if (g_navMesh)
dtDebugDrawStatNavMeshBVTree(g_navMesh);
} }
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
@ -559,30 +770,6 @@ int main(int argc, char *argv[])
glDisable(GL_FOG); glDisable(GL_FOG);
if (g_mesh)
{
// Agent dimensions.
const float r = agentRadius;
const float h = agentHeight;
float col[4];
col[0] = 0.6f; col[1] = 0.1f; col[2] = 0.1f; col[3] = 0.75f;
rcDebugDrawCylinderWire(spos[0]-r, spos[1]+0.02f, spos[2]-r, spos[0]+r, spos[1]+h, spos[2]+r, col);
glColor4ub(0,0,0,196);
glBegin(GL_LINES);
glVertex3f(spos[0], spos[1]-agentMaxClimb, spos[2]);
glVertex3f(spos[0], spos[1]+agentMaxClimb, spos[2]);
glVertex3f(spos[0]-r/2, spos[1]+0.02f, spos[2]);
glVertex3f(spos[0]+r/2, spos[1]+0.02f, spos[2]);
glVertex3f(spos[0], spos[1]+0.02f, spos[2]-r/2);
glVertex3f(spos[0], spos[1]+0.02f, spos[2]+r/2);
glEnd();
// Mesh bbox.
col[0] = 1.0f; col[1] = 1.0f; col[2] = 1.0f; col[3] = 0.25f;
rcDebugDrawBoxWire(g_cfg.bmin[0], g_cfg.bmin[1], g_cfg.bmin[2],
g_cfg.bmax[0], g_cfg.bmax[1], g_cfg.bmax[2], col);
}
// Render GUI // Render GUI
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@ -671,10 +858,12 @@ int main(int argc, char *argv[])
imguiLabel(GENID, "Draw"); imguiLabel(GENID, "Draw");
if (imguiCheck(GENID, "Input Mesh", drawMode == DRAWMODE_MESH)) if (imguiCheck(GENID, "Input Mesh", drawMode == DRAWMODE_MESH))
drawMode = DRAWMODE_MESH; drawMode = DRAWMODE_MESH;
if (imguiCheck(GENID, "Navmesh", drawMode == DRAWMODE_POLYMESH)) if (imguiCheck(GENID, "Navmesh", drawMode == DRAWMODE_NAVMESH))
drawMode = DRAWMODE_POLYMESH; drawMode = DRAWMODE_NAVMESH;
if (imguiCheck(GENID, "Navmesh Trans", drawMode == DRAWMODE_POLYMESH_TRANS)) if (imguiCheck(GENID, "Navmesh BVTree", drawMode == DRAWMODE_NAVMESH_BVTREE))
drawMode = DRAWMODE_POLYMESH_TRANS; drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck(GENID, "Navmesh Trans", drawMode == DRAWMODE_NAVMESH_TRANS))
drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck(GENID, "Voxels", drawMode == DRAWMODE_VOXELS)) if (imguiCheck(GENID, "Voxels", drawMode == DRAWMODE_VOXELS))
drawMode = DRAWMODE_VOXELS; drawMode = DRAWMODE_VOXELS;
if (imguiCheck(GENID, "Walkable Voxels", drawMode == DRAWMODE_VOXELS_WALKABLE)) if (imguiCheck(GENID, "Walkable Voxels", drawMode == DRAWMODE_VOXELS_WALKABLE))
@ -691,6 +880,101 @@ int main(int argc, char *argv[])
drawMode = DRAWMODE_CONTOURS; drawMode = DRAWMODE_CONTOURS;
imguiEndScrollArea(); imguiEndScrollArea();
// Tools
bool showTools = true;
if (showTools)
{
static int toolsScroll = 0;
if (imguiBeginScrollArea(GENID, "Tools", 10, 450, 150, 200, &toolsScroll))
mouseOverMenu = true;
if (imguiCheck(GENID, "Pathfind", toolMode == TOOLMODE_PATHFIND))
{
toolMode = TOOLMODE_PATHFIND;
recalcTool = true;
}
if (imguiCheck(GENID, "Distance to Wall", toolMode == TOOLMODE_DISTANCE_TO_WALL))
{
toolMode = TOOLMODE_DISTANCE_TO_WALL;
recalcTool = true;
}
if (imguiCheck(GENID, "Raycast", toolMode == TOOLMODE_RAYCAST))
{
toolMode = TOOLMODE_RAYCAST;
recalcTool = true;
}
if (imguiCheck(GENID, "Find Polys Around", toolMode == TOOLMODE_FIND_POLYS_AROUND))
{
toolMode = TOOLMODE_FIND_POLYS_AROUND;
recalcTool = true;
}
imguiEndScrollArea();
}
if (g_navMesh && recalcTool)
{
recalcTool = false;
if (toolMode == TOOLMODE_PATHFIND)
{
if (!startRef || !endRef)
{
npolys = 0;
nstraightPath = 0;
}
else
{
npolys = g_navMesh->findPath(startRef, endRef, polys, MAX_POLYS);
if (npolys)
nstraightPath = g_navMesh->findStraightPath(spos, epos, polys, npolys, straightPath, MAX_POLYS);
}
}
else if (toolMode == TOOLMODE_RAYCAST)
{
nstraightPath = 0;
if (sposSet && eposSet && startRef)
{
float t = 0;
npolys = 0;
nstraightPath = 2;
straightPath[0] = spos[0];
straightPath[1] = spos[1];
straightPath[2] = spos[2];
if (g_navMesh->raycast(startRef, spos, epos, t, polys[0]))
{
npolys = 1;
straightPath[3] = spos[0] + (epos[0] - spos[0]) * t;
straightPath[4] = spos[1] + (epos[1] - spos[1]) * t;
straightPath[5] = spos[2] + (epos[2] - spos[2]) * t;
}
else
{
straightPath[3] = epos[0];
straightPath[4] = epos[1];
straightPath[5] = epos[2];
}
}
}
else if (toolMode == TOOLMODE_DISTANCE_TO_WALL)
{
distanceToWall = 0;
if (sposSet && startRef)
distanceToWall = g_navMesh->findDistanceToWall(startRef, spos, 100.0f, hitPos, hitNormal);
}
else if (toolMode == TOOLMODE_FIND_POLYS_AROUND)
{
distanceToWall = 0;
if (sposSet && startRef && eposSet)
{
const float dx = epos[0] - spos[0];
const float dz = epos[2] - spos[2];
float dist = sqrtf(dx*dx + dz*dz);
npolys = g_navMesh->findPolysAround(startRef, spos, dist, polys, 0, 0, 0, MAX_POLYS);
}
}
}
// Log // Log
if (showLog) if (showLog)
@ -729,13 +1013,23 @@ int main(int argc, char *argv[])
delete g_cset; delete g_cset;
delete g_polyMesh; delete g_polyMesh;
delete [] g_triangleFlags; delete [] g_triangleFlags;
delete g_navMesh;
g_mesh = 0; g_mesh = 0;
g_solid = 0; g_solid = 0;
g_chf = 0; g_chf = 0;
g_cset = 0; g_cset = 0;
g_polyMesh = 0; g_polyMesh = 0;
g_triangleFlags = 0; g_triangleFlags = 0;
g_navMesh = 0;
npolys = 0;
nstraightPath = 0;
sposSet = false;
eposSet = false;
startRef = 0;
endRef = 0;
distanceToWall = 0;
g_mesh = new rcMeshLoaderObj; g_mesh = new rcMeshLoaderObj;
char path[256]; char path[256];
@ -777,7 +1071,22 @@ int main(int argc, char *argv[])
imguiEndFrame(); imguiEndFrame();
imguiRender(&drawText); imguiRender(&drawText);
g_font.drawText(10.0f, (float)height-20.0f, "W/S/A/D: Move LMB: Rotate RMB: Place character", GLFont::RGBA(255,255,255,128)); g_font.drawText(10.0f, (float)height-20.0f, "W/S/A/D: Move RMB: Rotate LMB: Place Start LMB+SHIFT: Place End", GLFont::RGBA(255,255,255,128));
// Draw start and end point labels
if (sposSet && gluProject((GLdouble)spos[0], (GLdouble)spos[1], (GLdouble)spos[2],
model, proj, view, &x, &y, &z))
{
const float len = g_font.getTextLength("Start");
g_font.drawText((float)x - len/2, (float)y-g_font.getLineHeight(), "Start", GLFont::RGBA(0,0,0,220));
}
if (eposSet && gluProject((GLdouble)epos[0], (GLdouble)epos[1], (GLdouble)epos[2],
model, proj, view, &x, &y, &z))
{
const float len = g_font.getTextLength("End");
g_font.drawText((float)x-len/2, (float)y-g_font.getLineHeight(), "End", GLFont::RGBA(0,0,0,220));
}
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
@ -791,6 +1100,7 @@ int main(int argc, char *argv[])
delete g_cset; delete g_cset;
delete g_polyMesh; delete g_polyMesh;
delete [] g_triangleFlags; delete [] g_triangleFlags;
delete g_navMesh;
return 0; return 0;
} }