diff --git a/RecastDemo/Include/CrowdTool.h b/RecastDemo/Include/CrowdTool.h index f7fadcfb..7e08cb85 100644 --- a/RecastDemo/Include/CrowdTool.h +++ b/RecastDemo/Include/CrowdTool.h @@ -16,65 +16,65 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef CROWDTOOL_H -#define CROWDTOOL_H +#pragma once -#include "Sample.h" +#include "DetourCrowd.h" #include "DetourNavMesh.h" #include "DetourObstacleAvoidance.h" +#include "Sample.h" #include "ValueHistory.h" -#include "DetourCrowd.h" -// Tool to create crowds. +#include struct CrowdToolParams { - bool m_expandSelectedDebugDraw; - bool m_showCorners; - bool m_showCollisionSegments; - bool m_showPath; - bool m_showVO; - bool m_showOpt; - bool m_showNeis; - - bool m_expandDebugDraw; - bool m_showLabels; - bool m_showGrid; - bool m_showNodes; - bool m_showPerfGraph; - bool m_showDetailAll; - - bool m_expandOptions; - bool m_anticipateTurns; - bool m_optimizeVis; - bool m_optimizeTopo; - bool m_obstacleAvoidance; - float m_obstacleAvoidanceType; - bool m_separation; - float m_separationWeight; + bool m_expandSelectedDebugDraw = true; + bool m_showCorners = false; + bool m_showCollisionSegments = false; + bool m_showPath = false; + bool m_showVO = false; + bool m_showOpt = false; + bool m_showNeis = false; + + bool m_expandDebugDraw = false; + bool m_showLabels = false; + bool m_showGrid = false; + bool m_showNodes = false; + bool m_showPerfGraph = false; + bool m_showDetailAll = false; + + bool m_expandOptions = true; + bool m_anticipateTurns = true; + bool m_optimizeVis = true; + bool m_optimizeTopo = true; + bool m_obstacleAvoidance = true; + float m_obstacleAvoidanceType = 3.0f; + bool m_separation = false; + float m_separationWeight = 2.0f; }; +/// Tool to create crowds. class CrowdToolState : public SampleToolState { Sample* m_sample; dtNavMesh* m_nav; dtCrowd* m_crowd; - + float m_targetPos[3]; dtPolyRef m_targetRef; dtCrowdAgentDebugInfo m_agentDebug; dtObstacleAvoidanceDebugData* m_vod; - + static const int AGENT_MAX_TRAIL = 64; static const int MAX_AGENTS = 128; struct AgentTrail { - float trail[AGENT_MAX_TRAIL*3]; + float trail[AGENT_MAX_TRAIL * 3]; int htrail; }; AgentTrail m_trails[MAX_AGENTS]; - + ValueHistory m_crowdTotalTime; ValueHistory m_crowdSampleCount; @@ -84,17 +84,21 @@ class CrowdToolState : public SampleToolState public: CrowdToolState(); - virtual ~CrowdToolState(); - - virtual void init(class Sample* sample); - virtual void reset(); - virtual void handleRender(); - virtual void handleRenderOverlay(double* proj, double* model, int* view); - virtual void handleUpdate(const float dt); + CrowdToolState(const CrowdToolState&) = delete; + CrowdToolState(const CrowdToolState&&) = delete; + CrowdToolState& operator=(const CrowdToolState&) = delete; + CrowdToolState& operator=(const CrowdToolState&&) = delete; + ~CrowdToolState() override; + + void init(class Sample* sample) override; + void reset() override; + void handleRender() override; + void handleRenderOverlay(double* proj, double* model, int* view) override; + void handleUpdate(const float dt) override; inline bool isRunning() const { return m_run; } inline void setRunning(const bool s) { m_run = s; } - + void addAgent(const float* pos); void removeAgent(const int idx); void hilightAgent(const int idx); @@ -104,41 +108,31 @@ public: void updateTick(const float dt); inline CrowdToolParams* getToolParams() { return &m_toolParams; } - -private: - // Explicitly disabled copy constructor and copy assignment operator. - CrowdToolState(const CrowdToolState&); - CrowdToolState& operator=(const CrowdToolState&); }; - class CrowdTool : public SampleTool { - Sample* m_sample; - CrowdToolState* m_state; - - enum ToolMode - { - TOOLMODE_CREATE, - TOOLMODE_MOVE_TARGET, - TOOLMODE_SELECT, - TOOLMODE_TOGGLE_POLYS - }; - ToolMode m_mode; - -public: - CrowdTool(); - - virtual SampleToolType type() { return SampleToolType::CROWD; } - virtual void init(Sample* sample); - virtual void reset(); - virtual void handleMenu(); - virtual void handleClick(const float* s, const float* p, bool shift); - virtual void handleToggle(); - virtual void handleStep(); - virtual void handleUpdate(const float dt); - virtual void handleRender(); - virtual void handleRenderOverlay(double* proj, double* model, int* view); -}; + Sample* m_sample = nullptr; + CrowdToolState* m_state = nullptr; -#endif // CROWDTOOL_H + enum class ToolMode : uint8_t + { + CREATE, + MOVE_TARGET, + SELECT, + TOGGLE_POLYS + }; + ToolMode m_mode = ToolMode::CREATE; + +public: + SampleToolType type() override { return SampleToolType::CROWD; } + void init(Sample* sample) override; + void reset() override; + void handleMenu() override; + void handleClick(const float* s, const float* p, bool shift) override; + void handleToggle() override; + void handleStep() override; + void handleUpdate(const float dt) override; + void handleRender() override; + void handleRenderOverlay(double* proj, double* model, int* view) override; +}; diff --git a/RecastDemo/Include/Filelist.h b/RecastDemo/Include/Filelist.h index 3bf91c72..bded444c 100644 --- a/RecastDemo/Include/Filelist.h +++ b/RecastDemo/Include/Filelist.h @@ -18,9 +18,8 @@ #pragma once -#include #include +#include void scanDirectoryAppend(const std::string& path, const std::string& ext, std::vector& fileList); void scanDirectory(const std::string& path, const std::string& ext, std::vector& fileList); - diff --git a/RecastDemo/Include/NavMeshPruneTool.h b/RecastDemo/Include/NavMeshPruneTool.h index ce1674fc..e7830887 100644 --- a/RecastDemo/Include/NavMeshPruneTool.h +++ b/RecastDemo/Include/NavMeshPruneTool.h @@ -24,7 +24,7 @@ class NavmeshFlags; /** * Prune navmesh to accessible locations from a point. -*/ + */ class NavMeshPruneTool : public SampleTool { Sample* m_sample = nullptr; @@ -51,4 +51,3 @@ public: void handleRender() override; void handleRenderOverlay(double* proj, double* model, int* view) override; }; - diff --git a/RecastDemo/Include/NavMeshTesterTool.h b/RecastDemo/Include/NavMeshTesterTool.h index 8866f7ac..73231e07 100644 --- a/RecastDemo/Include/NavMeshTesterTool.h +++ b/RecastDemo/Include/NavMeshTesterTool.h @@ -16,23 +16,22 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef NAVMESHTESTERTOOL_H -#define NAVMESHTESTERTOOL_H +#pragma once -#include "Sample.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" +#include "Sample.h" class NavMeshTesterTool : public SampleTool { - Sample* m_sample; - - dtNavMesh* m_navMesh; - dtNavMeshQuery* m_navQuery; + Sample* m_sample = nullptr; + + dtNavMesh* m_navMesh = nullptr; + dtNavMeshQuery* m_navQuery = nullptr; dtQueryFilter m_filter; - dtStatus m_pathFindStatus; + dtStatus m_pathFindStatus = DT_FAILURE; enum ToolMode { @@ -45,70 +44,66 @@ class NavMeshTesterTool : public SampleTool TOOLMODE_FIND_POLYS_IN_SHAPE, TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD }; - - ToolMode m_toolMode; + ToolMode m_toolMode = TOOLMODE_PATHFIND_FOLLOW; + + int m_straightPathOptions = 0; - int m_straightPathOptions; - static const int MAX_POLYS = 256; static const int MAX_SMOOTH = 2048; - - dtPolyRef m_startRef; - dtPolyRef m_endRef; + + dtPolyRef m_startRef = 0; + dtPolyRef m_endRef = 0; dtPolyRef m_polys[MAX_POLYS]; dtPolyRef m_parent[MAX_POLYS]; - int m_npolys; - float m_straightPath[MAX_POLYS*3]; + int m_npolys = 0; + float m_straightPath[MAX_POLYS * 3]; unsigned char m_straightPathFlags[MAX_POLYS]; dtPolyRef m_straightPathPolys[MAX_POLYS]; - int m_nstraightPath; - float m_polyPickExt[3]; - float m_smoothPath[MAX_SMOOTH*3]; - int m_nsmoothPath; - float m_queryPoly[4*3]; + int m_nstraightPath = 0; + float m_polyPickExt[3] = {2, 4, 2}; + float m_smoothPath[MAX_SMOOTH * 3]; + int m_nsmoothPath = 0; + float m_queryPoly[4 * 3]; static const int MAX_RAND_POINTS = 64; - float m_randPoints[MAX_RAND_POINTS*3]; - int m_nrandPoints; - bool m_randPointsInCircle; - + float m_randPoints[MAX_RAND_POINTS * 3]; + int m_nrandPoints = 0; + bool m_randPointsInCircle = false; + float m_spos[3]; float m_epos[3]; float m_hitPos[3]; float m_hitNormal[3]; - bool m_hitResult; - float m_distanceToWall; - float m_neighbourhoodRadius; - float m_randomRadius; - bool m_sposSet; - bool m_eposSet; + bool m_hitResult = false; + float m_distanceToWall = 0; + float m_neighbourhoodRadius = 2.5f; + float m_randomRadius = 5.0f; + bool m_sposSet = false; + bool m_eposSet = false; - int m_pathIterNum; - dtPolyRef m_pathIterPolys[MAX_POLYS]; - int m_pathIterPolyCount; + int m_pathIterNum = 0; + dtPolyRef m_pathIterPolys[MAX_POLYS]; + int m_pathIterPolyCount = 0; float m_prevIterPos[3], m_iterPos[3], m_steerPos[3], m_targetPos[3]; - + static const int MAX_STEER_POINTS = 10; - float m_steerPoints[MAX_STEER_POINTS*3]; - int m_steerPointCount; - + float m_steerPoints[MAX_STEER_POINTS * 3]; + int m_steerPointCount = 0; + public: NavMeshTesterTool(); - virtual SampleToolType type() { return SampleToolType::NAVMESH_TESTER; } - virtual void init(Sample* sample); - virtual void reset(); - virtual void handleMenu(); - virtual void handleClick(const float* s, const float* p, bool shift); - virtual void handleToggle(); - virtual void handleStep(); - virtual void handleUpdate(const float dt); - virtual void handleRender(); - virtual void handleRenderOverlay(double* proj, double* model, int* view); + SampleToolType type() override { return SampleToolType::NAVMESH_TESTER; } + void init(Sample* sample) override; + void reset() override; + void handleMenu() override; + void handleClick(const float* s, const float* p, bool shift) override; + void handleToggle() override; + void handleStep() override; + void handleUpdate(const float dt) override; + void handleRender() override; + void handleRenderOverlay(double* proj, double* model, int* view) override; void recalc(); void drawAgent(const float* pos, float r, float h, float c, const unsigned int col); }; - -#endif // NAVMESHTESTERTOOL_H - diff --git a/RecastDemo/Include/OffMeshConnectionTool.h b/RecastDemo/Include/OffMeshConnectionTool.h index 43cca042..dd4930b9 100644 --- a/RecastDemo/Include/OffMeshConnectionTool.h +++ b/RecastDemo/Include/OffMeshConnectionTool.h @@ -16,25 +16,29 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef OFFMESHCONNECTIONTOOL_H -#define OFFMESHCONNECTIONTOOL_H +#pragma once #include "Sample.h" -// Tool to create off-mesh connection for InputGeom - +/// Tool to create off-mesh connection for InputGeom class OffMeshConnectionTool : public SampleTool { - Sample* m_sample; + Sample* m_sample = nullptr; float m_hitPos[3]; - bool m_hitPosSet; - bool m_bidir; - unsigned char m_oldFlags; - + bool m_hitPosSet = 0; + bool m_bidir = true; + unsigned char m_oldFlags = 0; + public: - OffMeshConnectionTool(); - ~OffMeshConnectionTool(); - + OffMeshConnectionTool() = default; + ~OffMeshConnectionTool() + { + if (m_sample) + { + m_sample->setNavMeshDrawFlags(m_oldFlags); + } + } + virtual SampleToolType type() { return SampleToolType::OFFMESH_CONNECTION; } virtual void init(Sample* sample); virtual void reset(); @@ -46,5 +50,3 @@ public: virtual void handleRender(); virtual void handleRenderOverlay(double* proj, double* model, int* view); }; - -#endif // OFFMESHCONNECTIONTOOL_H diff --git a/RecastDemo/Include/PerfTimer.h b/RecastDemo/Include/PerfTimer.h index ce0f296f..36cf96f5 100644 --- a/RecastDemo/Include/PerfTimer.h +++ b/RecastDemo/Include/PerfTimer.h @@ -16,18 +16,10 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef PERFTIMER_H -#define PERFTIMER_H +#pragma once -#ifdef __GNUC__ #include typedef int64_t TimeVal; -#else -typedef __int64 TimeVal; -#endif TimeVal getPerfTime(); int getPerfTimeUsec(const TimeVal duration); - -#endif // PERFTIMER_H - diff --git a/RecastDemo/Include/SampleInterfaces.h b/RecastDemo/Include/SampleInterfaces.h index 8d707696..d9c9a13b 100644 --- a/RecastDemo/Include/SampleInterfaces.h +++ b/RecastDemo/Include/SampleInterfaces.h @@ -16,10 +16,10 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef SAMPLEINTERFACES_H -#define SAMPLEINTERFACES_H +#pragma once #include +#include #include "DebugDraw.h" #include "PerfTimer.h" @@ -31,28 +31,28 @@ /// Recast build context. class BuildContext : public rcContext { - TimeVal m_startTime[RC_MAX_TIMERS]; - TimeVal m_accTime[RC_MAX_TIMERS]; + std::array m_startTime; + std::array m_accTime; static const int MAX_MESSAGES = 1000; const char* m_messages[MAX_MESSAGES]; - int m_messageCount; + int m_messageCount = 0; static const int TEXT_POOL_SIZE = 8000; char m_textPool[TEXT_POOL_SIZE]; - int m_textPoolSize; - + int m_textPoolSize = 0; + public: BuildContext(); - + /// Dumps the log to stdout. void dumpLog(const char* format, ...); /// Returns number of log messages. int getLogCount() const; /// Returns log message text. const char* getLogText(const int i) const; - -protected: + +protected: /// Virtual functions for custom implementations. ///@{ virtual void doResetLog(); @@ -72,8 +72,8 @@ public: virtual void texture(bool state); virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f); virtual void vertex(const float* pos, unsigned int color); - virtual void vertex(float x, float y, float z, unsigned int color); virtual void vertex(const float* pos, unsigned int color, const float* uv); + virtual void vertex(float x, float y, float z, unsigned int color); virtual void vertex(float x, float y, float z, unsigned int color, float u, float v); virtual void end(); }; @@ -81,22 +81,22 @@ public: /// stdio file implementation. class FileIO : public duFileIO { - FILE* m_fp; - int m_mode; public: - FileIO(); + FileIO() = default; + FileIO(const FileIO&) = delete; + FileIO& operator=(const FileIO&) = delete; + FileIO(FileIO&&) = delete; + FileIO& operator=(FileIO&&) = delete; virtual ~FileIO(); + bool openForWrite(const char* path); bool openForRead(const char* path); virtual bool isWriting() const; virtual bool isReading() const; virtual bool write(const void* ptr, const size_t size); virtual bool read(void* ptr, const size_t size); + private: - // Explicitly disabled copy constructor and copy assignment operator. - FileIO(const FileIO&); - FileIO& operator=(const FileIO&); + FILE* m_fp = nullptr; + int m_mode = -1; }; - -#endif // SAMPLEINTERFACES_H - diff --git a/RecastDemo/Include/TestCase.h b/RecastDemo/Include/TestCase.h index 8991e576..b7fab2cc 100644 --- a/RecastDemo/Include/TestCase.h +++ b/RecastDemo/Include/TestCase.h @@ -16,11 +16,11 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef TESTCASE_H -#define TESTCASE_H +#pragma once + +#include "DetourNavMesh.h" #include -#include "DetourNavMesh.h" class TestCase { @@ -29,86 +29,66 @@ class TestCase TEST_PATHFIND, TEST_RAYCAST }; - + struct Test { - Test() : - type(), - spos(), - epos(), - nspos(), - nepos(), - radius(0), - includeFlags(0), - excludeFlags(0), - expand(false), - straight(0), - nstraight(0), - polys(0), - npolys(0), - findNearestPolyTime(0), - findPathTime(0), - findStraightPathTime(0), - next(0) - { - } - + Test() = default; + Test(const Test&) = delete; + Test(Test&&) = delete; + Test& operator=(const Test&) = delete; + Test& operator=(Test&&) = delete; ~Test() { - delete [] straight; - delete [] polys; + delete[] straight; + delete[] polys; } - - TestType type; - float spos[3]; - float epos[3]; - float nspos[3]; - float nepos[3]; - float radius; - unsigned short includeFlags; - unsigned short excludeFlags; - bool expand; - - float* straight; - int nstraight; - dtPolyRef* polys; - int npolys; - - int findNearestPolyTime; - int findPathTime; - int findStraightPathTime; - - Test* next; - private: - // Explicitly disabled copy constructor and copy assignment operator. - Test(const Test&); - Test& operator=(const Test&); + + TestType type{}; + float spos[3]{}; + float epos[3]{}; + float nspos[3]{}; + float nepos[3]{}; + float radius = 0; + unsigned short includeFlags = 0; + unsigned short excludeFlags = 0; + bool expand = false; + + float* straight = nullptr; + int nstraight = 0; + dtPolyRef* polys = nullptr; + int npolys = 0; + + int findNearestPolyTime = 0; + int findPathTime = 0; + int findStraightPathTime = 0; + + Test* next = nullptr; }; std::string m_sampleName; std::string m_geomFileName; - Test* m_tests; - + Test* m_tests = nullptr; + void resetTimes(); - + public: - TestCase(); + TestCase() = default; + TestCase(const TestCase&) = delete; + TestCase(TestCase&&) = delete; + TestCase& operator=(const TestCase&) = delete; + TestCase& operator=(TestCase&&) = delete; ~TestCase(); bool load(const std::string& filePath); - + const std::string& getSampleName() const { return m_sampleName; } const std::string& getGeomFileName() const { return m_geomFileName; } - + void doTests(class dtNavMesh* navmesh, class dtNavMeshQuery* navquery); - + void handleRender(); bool handleRenderOverlay(double* proj, double* model, int* view); private: // Explicitly disabled copy constructor and copy assignment operator. - TestCase(const TestCase&); - TestCase& operator=(const TestCase&); }; - -#endif // TESTCASE_H diff --git a/RecastDemo/Include/imgui.h b/RecastDemo/Include/imgui.h index 3d7346ef..9e616bc2 100644 --- a/RecastDemo/Include/imgui.h +++ b/RecastDemo/Include/imgui.h @@ -16,12 +16,11 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef IMGUI_H -#define IMGUI_H +#pragma once enum imguiMouseButton { - IMGUI_MBUT_LEFT = 0x01, + IMGUI_MBUT_LEFT = 0x01, IMGUI_MBUT_RIGHT = 0x02 }; @@ -32,7 +31,7 @@ enum imguiTextAlign IMGUI_ALIGN_RIGHT }; -inline unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a=255) +inline unsigned int imguiRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) { return (r) | (g << 8) | (b << 16) | (a << 24); } @@ -73,18 +72,28 @@ enum imguiGfxCmdType struct imguiGfxRect { - short x,y,w,h,r; + short x; + short y; + short w; + short h; + short r; }; struct imguiGfxText { - short x,y,align; + short x; + short y; + short align; const char* text; }; struct imguiGfxLine { - short x0,y0,x1,y1,r; + short x0; + short y0; + short x1; + short y1; + short r; }; struct imguiGfxCmd @@ -104,5 +113,3 @@ struct imguiGfxCmd const imguiGfxCmd* imguiGetRenderQueue(); int imguiGetRenderQueueSize(); - -#endif // IMGUI_H diff --git a/RecastDemo/Include/imguiRenderGL.h b/RecastDemo/Include/imguiRenderGL.h index 33cd017c..aeed2399 100644 --- a/RecastDemo/Include/imguiRenderGL.h +++ b/RecastDemo/Include/imguiRenderGL.h @@ -16,12 +16,9 @@ // 3. This notice may not be removed or altered from any source distribution. // -#ifndef IMGUI_RENDER_GL_H -#define IMGUI_RENDER_GL_H +#pragma once bool imguiRenderGLInit(const char* fontpath); void imguiRenderGLDestroy(); void imguiRenderGLDraw(); -#endif // IMGUI_RENDER_GL_H - diff --git a/RecastDemo/Source/CrowdTool.cpp b/RecastDemo/Source/CrowdTool.cpp index 0fb64ee2..7ad82a7e 100644 --- a/RecastDemo/Source/CrowdTool.cpp +++ b/RecastDemo/Source/CrowdTool.cpp @@ -16,51 +16,49 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include "SDL.h" +#include "SDL_opengl.h" + +#include #include #include #include -#include -#include "SDL.h" -#include "SDL_opengl.h" #ifdef __APPLE__ # include #else # include #endif -#include "imgui.h" #include "CrowdTool.h" -#include "InputGeom.h" -#include "Sample.h" +#include "DetourCommon.h" #include "DetourCrowd.h" #include "DetourDebugDraw.h" -#include "DetourObstacleAvoidance.h" -#include "DetourCommon.h" #include "DetourNode.h" +#include "DetourObstacleAvoidance.h" +#include "InputGeom.h" +#include "Sample.h" #include "SampleInterfaces.h" +#include "imgui.h" #ifdef WIN32 # define snprintf _snprintf #endif -static bool isectSegAABB(const float* sp, const float* sq, - const float* amin, const float* amax, - float& tmin, float& tmax) +static bool isectSegAABB(const float* sp, const float* sq, const float* amin, const float* amax, float& tmin, float& tmax) { static const float EPS = 1e-6f; - + float d[3]; dtVsub(d, sq, sp); - tmin = 0; // set to -FLT_MAX to get first hit on line - tmax = FLT_MAX; // set to max distance ray can travel (for segment) - + tmin = 0; // set to -FLT_MAX to get first hit on line + tmax = FLT_MAX; // set to max distance ray can travel (for segment) + // For all three slabs for (int i = 0; i < 3; i++) { if (fabsf(d[i]) < EPS) { // Ray is parallel to slab. No hit if origin not within slab - if (sp[i] < amin[i] || sp[i] > amax[i]) - return false; + if (sp[i] < amin[i] || sp[i] > amax[i]) { return false; } } else { @@ -69,15 +67,15 @@ static bool isectSegAABB(const float* sp, const float* sq, float t1 = (amin[i] - sp[i]) * ood; float t2 = (amax[i] - sp[i]) * ood; // Make t1 be intersection with near plane, t2 with far plane - if (t1 > t2) dtSwap(t1, t2); + if (t1 > t2) { dtSwap(t1, t2); } // Compute the intersection of slab intersections intervals - if (t1 > tmin) tmin = t1; - if (t2 < tmax) tmax = t2; + if (t1 > tmin) { tmin = t1; } + if (t2 < tmax) { tmax = t2; } // Exit with no collision as soon as slab intersection becomes empty - if (tmin > tmax) return false; + if (tmin > tmax) { return false; } } } - + return true; } @@ -94,40 +92,13 @@ static void getAgentBounds(const dtCrowdAgent* ag, float* bmin, float* bmax) bmax[2] = p[2] + r; } -CrowdToolState::CrowdToolState() : - m_sample(0), - m_nav(0), - m_crowd(0), - m_targetRef(0), - m_run(true) +CrowdToolState::CrowdToolState() : m_sample(0), m_nav(0), m_crowd(0), m_targetRef(0), m_run(true) { - m_toolParams.m_expandSelectedDebugDraw = true; - m_toolParams.m_showCorners = false; - m_toolParams.m_showCollisionSegments = false; - m_toolParams.m_showPath = false; - m_toolParams.m_showVO = false; - m_toolParams.m_showOpt = false; - m_toolParams.m_showNeis = false; - m_toolParams.m_expandDebugDraw = false; - m_toolParams.m_showLabels = false; - m_toolParams.m_showGrid = false; - m_toolParams.m_showNodes = false; - m_toolParams.m_showPerfGraph = false; - m_toolParams.m_showDetailAll = false; - m_toolParams.m_expandOptions = true; - m_toolParams.m_anticipateTurns = true; - m_toolParams.m_optimizeVis = true; - m_toolParams.m_optimizeTopo = true; - m_toolParams.m_obstacleAvoidance = true; - m_toolParams.m_obstacleAvoidanceType = 3.0f; - m_toolParams.m_separation = false; - m_toolParams.m_separationWeight = 2.0f; - memset(m_trails, 0, sizeof(m_trails)); - + m_vod = dtAllocObstacleAvoidanceDebugData(); m_vod->init(2048); - + memset(&m_agentDebug, 0, sizeof(m_agentDebug)); m_agentDebug.idx = -1; m_agentDebug.vod = m_vod; @@ -140,103 +111,95 @@ CrowdToolState::~CrowdToolState() void CrowdToolState::init(class Sample* sample) { - if (m_sample != sample) - { - m_sample = sample; - } - + if (m_sample != sample) { m_sample = sample; } + dtNavMesh* nav = m_sample->getNavMesh(); dtCrowd* crowd = m_sample->getCrowd(); - + if (nav && crowd && (m_nav != nav || m_crowd != crowd)) { m_nav = nav; m_crowd = crowd; - + crowd->init(MAX_AGENTS, m_sample->getAgentRadius(), nav); - + // Make polygons with 'disabled' flag invalid. crowd->getEditableFilter(0)->setExcludeFlags(SAMPLE_POLYFLAGS_DISABLED); - + // Setup local avoidance params to different qualities. dtObstacleAvoidanceParams params; // Use mostly default settings, copy from dtCrowd. memcpy(¶ms, crowd->getObstacleAvoidanceParams(0), sizeof(dtObstacleAvoidanceParams)); - + // Low (11) params.velBias = 0.5f; params.adaptiveDivs = 5; params.adaptiveRings = 2; params.adaptiveDepth = 1; crowd->setObstacleAvoidanceParams(0, ¶ms); - + // Medium (22) params.velBias = 0.5f; - params.adaptiveDivs = 5; + params.adaptiveDivs = 5; params.adaptiveRings = 2; params.adaptiveDepth = 2; crowd->setObstacleAvoidanceParams(1, ¶ms); - + // Good (45) params.velBias = 0.5f; params.adaptiveDivs = 7; params.adaptiveRings = 2; params.adaptiveDepth = 3; crowd->setObstacleAvoidanceParams(2, ¶ms); - + // High (66) params.velBias = 0.5f; params.adaptiveDivs = 7; params.adaptiveRings = 3; params.adaptiveDepth = 3; - + crowd->setObstacleAvoidanceParams(3, ¶ms); } } -void CrowdToolState::reset() -{ -} +void CrowdToolState::reset() {} void CrowdToolState::handleRender() { duDebugDraw& dd = m_sample->getDebugDraw(); const float rad = m_sample->getAgentRadius(); - + dtNavMesh* nav = m_sample->getNavMesh(); dtCrowd* crowd = m_sample->getCrowd(); - if (!nav || !crowd) - return; - + if (!nav || !crowd) { return; } + if (m_toolParams.m_showNodes && crowd->getPathQueue()) { const dtNavMeshQuery* navquery = crowd->getPathQueue()->getNavQuery(); - if (navquery) - duDebugDrawNavMeshNodes(&dd, *navquery); + if (navquery) { duDebugDrawNavMeshNodes(&dd, *navquery); } } dd.depthMask(false); - + // Draw paths if (m_toolParams.m_showPath) { for (int i = 0; i < crowd->getAgentCount(); i++) { - if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) - continue; - const dtCrowdAgent* ag =crowd->getAgent(i); - if (!ag->active) - continue; + if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) { continue; } + const dtCrowdAgent* ag = crowd->getAgent(i); + if (!ag->active) { continue; } const dtPolyRef* path = ag->corridor.getPath(); - const int npath = ag->corridor.getPathCount(); - for (int j = 0; j < npath; ++j) - duDebugDrawNavMeshPoly(&dd, *nav, path[j], duRGBA(255,255,255,24)); + const int npath = ag->corridor.getPathCount(); + for (int j = 0; j < npath; ++j) { duDebugDrawNavMeshPoly(&dd, *nav, path[j], duRGBA(255, 255, 255, 24)); } } } - + if (m_targetRef) - duDebugDrawCross(&dd, m_targetPos[0],m_targetPos[1]+0.1f,m_targetPos[2], rad, duRGBA(255,255,255,192), 2.0f); - + { + duDebugDrawCross(&dd, m_targetPos[0], m_targetPos[1] + 0.1f, m_targetPos[2], rad, duRGBA(255, 255, 255, 192), 2.0f); + } + // Occupancy grid. if (m_toolParams.m_showGrid) { @@ -244,12 +207,12 @@ void CrowdToolState::handleRender() for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } const float* pos = ag->corridor.getPos(); gridy = dtMax(gridy, pos[1]); } gridy += 1.0f; - + dd.begin(DU_DRAW_QUADS); const dtProximityGrid* grid = crowd->getGrid(); const int* bounds = grid->getBounds(); @@ -258,56 +221,53 @@ void CrowdToolState::handleRender() { for (int x = bounds[0]; x <= bounds[2]; ++x) { - const int count = grid->getItemCountAt(x,y); - if (!count) continue; - unsigned int col = duRGBA(128,0,0,dtMin(count*40,255)); - dd.vertex(x*cs, gridy, y*cs, col); - dd.vertex(x*cs, gridy, y*cs+cs, col); - dd.vertex(x*cs+cs, gridy, y*cs+cs, col); - dd.vertex(x*cs+cs, gridy, y*cs, col); + const int count = grid->getItemCountAt(x, y); + if (!count) { continue; } + unsigned int col = duRGBA(128, 0, 0, dtMin(count * 40, 255)); + dd.vertex(x * cs, gridy, y * cs, col); + dd.vertex(x * cs, gridy, y * cs + cs, col); + dd.vertex(x * cs + cs, gridy, y * cs + cs, col); + dd.vertex(x * cs + cs, gridy, y * cs, col); } } dd.end(); } - + // Trail for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; - + if (!ag->active) { continue; } + const AgentTrail* trail = &m_trails[i]; const float* pos = ag->npos; - - dd.begin(DU_DRAW_LINES,3.0f); + + dd.begin(DU_DRAW_LINES, 3.0f); float prev[3], preva = 1; dtVcopy(prev, pos); - for (int j = 0; j < AGENT_MAX_TRAIL-1; ++j) + for (int j = 0; j < AGENT_MAX_TRAIL - 1; ++j) { - const int idx = (trail->htrail + AGENT_MAX_TRAIL-j) % AGENT_MAX_TRAIL; - const float* v = &trail->trail[idx*3]; - float a = 1 - j/(float)AGENT_MAX_TRAIL; - dd.vertex(prev[0],prev[1]+0.1f,prev[2], duRGBA(0,0,0,(int)(128*preva))); - dd.vertex(v[0],v[1]+0.1f,v[2], duRGBA(0,0,0,(int)(128*a))); + const int idx = (trail->htrail + AGENT_MAX_TRAIL - j) % AGENT_MAX_TRAIL; + const float* v = &trail->trail[idx * 3]; + float a = 1 - j / (float)AGENT_MAX_TRAIL; + dd.vertex(prev[0], prev[1] + 0.1f, prev[2], duRGBA(0, 0, 0, (int)(128 * preva))); + dd.vertex(v[0], v[1] + 0.1f, v[2], duRGBA(0, 0, 0, (int)(128 * a))); preva = a; dtVcopy(prev, v); } dd.end(); - } - + // Corners & co for (int i = 0; i < crowd->getAgentCount(); i++) { - if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) - continue; - const dtCrowdAgent* ag =crowd->getAgent(i); - if (!ag->active) - continue; - + if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) { continue; } + const dtCrowdAgent* ag = crowd->getAgent(i); + if (!ag->active) { continue; } + const float radius = ag->params.radius; const float* pos = ag->npos; - + if (m_toolParams.m_showCorners) { if (ag->ncorners) @@ -315,21 +275,20 @@ void CrowdToolState::handleRender() dd.begin(DU_DRAW_LINES, 2.0f); for (int j = 0; j < ag->ncorners; ++j) { - const float* va = j == 0 ? pos : &ag->cornerVerts[(j-1)*3]; - const float* vb = &ag->cornerVerts[j*3]; - dd.vertex(va[0],va[1]+radius,va[2], duRGBA(128,0,0,192)); - dd.vertex(vb[0],vb[1]+radius,vb[2], duRGBA(128,0,0,192)); + const float* va = j == 0 ? pos : &ag->cornerVerts[(j - 1) * 3]; + const float* vb = &ag->cornerVerts[j * 3]; + dd.vertex(va[0], va[1] + radius, va[2], duRGBA(128, 0, 0, 192)); + dd.vertex(vb[0], vb[1] + radius, vb[2], duRGBA(128, 0, 0, 192)); } - if (ag->ncorners && ag->cornerFlags[ag->ncorners-1] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) + if (ag->ncorners && ag->cornerFlags[ag->ncorners - 1] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) { - const float* v = &ag->cornerVerts[(ag->ncorners-1)*3]; - dd.vertex(v[0],v[1],v[2], duRGBA(192,0,0,192)); - dd.vertex(v[0],v[1]+radius*2,v[2], duRGBA(192,0,0,192)); + const float* v = &ag->cornerVerts[(ag->ncorners - 1) * 3]; + dd.vertex(v[0], v[1], v[2], duRGBA(192, 0, 0, 192)); + dd.vertex(v[0], v[1] + radius * 2, v[2], duRGBA(192, 0, 0, 192)); } - + dd.end(); - - + if (m_toolParams.m_anticipateTurns) { /* float dvel[3], pos[3]; @@ -337,49 +296,48 @@ void CrowdToolState::handleRender() pos[0] = ag->pos[0] + dvel[0]; pos[1] = ag->pos[1] + dvel[1]; pos[2] = ag->pos[2] + dvel[2]; - + const float off = ag->radius+0.1f; const float* tgt = &ag->cornerVerts[0]; const float y = ag->pos[1]+off; - + dd.begin(DU_DRAW_LINES, 2.0f); - + dd.vertex(ag->pos[0],y,ag->pos[2], duRGBA(255,0,0,192)); dd.vertex(pos[0],y,pos[2], duRGBA(255,0,0,192)); - + dd.vertex(pos[0],y,pos[2], duRGBA(255,0,0,192)); dd.vertex(tgt[0],y,tgt[2], duRGBA(255,0,0,192)); - + dd.end();*/ } } } - + if (m_toolParams.m_showCollisionSegments) { const float* center = ag->boundary.getCenter(); - duDebugDrawCross(&dd, center[0],center[1]+radius,center[2], 0.2f, duRGBA(192,0,128,255), 2.0f); - duDebugDrawCircle(&dd, center[0],center[1]+radius,center[2], ag->params.collisionQueryRange, - duRGBA(192,0,128,128), 2.0f); - + duDebugDrawCross(&dd, center[0], center[1] + radius, center[2], 0.2f, duRGBA(192, 0, 128, 255), 2.0f); + duDebugDrawCircle( + &dd, center[0], center[1] + radius, center[2], ag->params.collisionQueryRange, duRGBA(192, 0, 128, 128), 2.0f); + dd.begin(DU_DRAW_LINES, 3.0f); for (int j = 0; j < ag->boundary.getSegmentCount(); ++j) { const float* s = ag->boundary.getSegment(j); - unsigned int col = duRGBA(192,0,128,192); - if (dtTriArea2D(pos, s, s+3) < 0.0f) - col = duDarkenCol(col); - - duAppendArrow(&dd, s[0],s[1]+0.2f,s[2], s[3],s[4]+0.2f,s[5], 0.0f, 0.3f, col); + unsigned int col = duRGBA(192, 0, 128, 192); + if (dtTriArea2D(pos, s, s + 3) < 0.0f) { col = duDarkenCol(col); } + + duAppendArrow(&dd, s[0], s[1] + 0.2f, s[2], s[3], s[4] + 0.2f, s[5], 0.0f, 0.3f, col); } dd.end(); } - + if (m_toolParams.m_showNeis) { - duDebugDrawCircle(&dd, pos[0],pos[1]+radius,pos[2], ag->params.collisionQueryRange, - duRGBA(0,192,128,128), 2.0f); - + duDebugDrawCircle( + &dd, pos[0], pos[1] + radius, pos[2], ag->params.collisionQueryRange, duRGBA(0, 192, 128, 128), 2.0f); + dd.begin(DU_DRAW_LINES, 2.0f); for (int j = 0; j < ag->nneis; ++j) { @@ -388,81 +346,86 @@ void CrowdToolState::handleRender() const dtCrowdAgent* nei = crowd->getAgent(ag->neis[j].idx); if (nei) { - dd.vertex(pos[0],pos[1]+radius,pos[2], duRGBA(0,192,128,128)); - dd.vertex(nei->npos[0],nei->npos[1]+radius,nei->npos[2], duRGBA(0,192,128,128)); + dd.vertex(pos[0], pos[1] + radius, pos[2], duRGBA(0, 192, 128, 128)); + dd.vertex(nei->npos[0], nei->npos[1] + radius, nei->npos[2], duRGBA(0, 192, 128, 128)); } } dd.end(); } - + if (m_toolParams.m_showOpt) { dd.begin(DU_DRAW_LINES, 2.0f); - dd.vertex(m_agentDebug.optStart[0],m_agentDebug.optStart[1]+0.3f,m_agentDebug.optStart[2], duRGBA(0,128,0,192)); - dd.vertex(m_agentDebug.optEnd[0],m_agentDebug.optEnd[1]+0.3f,m_agentDebug.optEnd[2], duRGBA(0,128,0,192)); + dd.vertex( + m_agentDebug.optStart[0], m_agentDebug.optStart[1] + 0.3f, m_agentDebug.optStart[2], duRGBA(0, 128, 0, 192)); + dd.vertex(m_agentDebug.optEnd[0], m_agentDebug.optEnd[1] + 0.3f, m_agentDebug.optEnd[2], duRGBA(0, 128, 0, 192)); dd.end(); } } - + // Agent cylinders. for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; - + if (!ag->active) { continue; } + const float radius = ag->params.radius; const float* pos = ag->npos; - - unsigned int col = duRGBA(0,0,0,32); - if (m_agentDebug.idx == i) - col = duRGBA(255,0,0,128); - + + unsigned int col = duRGBA(0, 0, 0, 32); + if (m_agentDebug.idx == i) { col = duRGBA(255, 0, 0, 128); } + duDebugDrawCircle(&dd, pos[0], pos[1], pos[2], radius, col, 2.0f); } - + for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; - + if (!ag->active) { continue; } + const float height = ag->params.height; const float radius = ag->params.radius; const float* pos = ag->npos; - - unsigned int col = duRGBA(220,220,220,128); + + unsigned int col = duRGBA(220, 220, 220, 128); if (ag->targetState == DT_CROWDAGENT_TARGET_REQUESTING || ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE) - col = duLerpCol(col, duRGBA(128,0,255,128), 32); + { + col = duLerpCol(col, duRGBA(128, 0, 255, 128), 32); + } else if (ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_PATH) - col = duLerpCol(col, duRGBA(128,0,255,128), 128); - else if (ag->targetState == DT_CROWDAGENT_TARGET_FAILED) - col = duRGBA(255,32,16,128); - else if (ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) - col = duLerpCol(col, duRGBA(64,255,0,128), 128); - - duDebugDrawCylinder(&dd, pos[0]-radius, pos[1]+radius*0.1f, pos[2]-radius, - pos[0]+radius, pos[1]+height, pos[2]+radius, col); + { + col = duLerpCol(col, duRGBA(128, 0, 255, 128), 128); + } + else if (ag->targetState == DT_CROWDAGENT_TARGET_FAILED) { col = duRGBA(255, 32, 16, 128); } + else if (ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) { col = duLerpCol(col, duRGBA(64, 255, 0, 128), 128); } + + duDebugDrawCylinder(&dd, + pos[0] - radius, + pos[1] + radius * 0.1f, + pos[2] - radius, + pos[0] + radius, + pos[1] + height, + pos[2] + radius, + col); } - - + if (m_toolParams.m_showVO) { for (int i = 0; i < crowd->getAgentCount(); i++) { - if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) - continue; - const dtCrowdAgent* ag =crowd->getAgent(i); - if (!ag->active) - continue; - + if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) { continue; } + const dtCrowdAgent* ag = crowd->getAgent(i); + if (!ag->active) { continue; } + // Draw detail about agent sela const dtObstacleAvoidanceDebugData* vod = m_agentDebug.vod; - + const float dx = ag->npos[0]; - const float dy = ag->npos[1]+ag->params.height; + const float dy = ag->npos[1] + ag->params.height; const float dz = ag->npos[2]; - - duDebugDrawCircle(&dd, dx,dy,dz, ag->params.maxSpeed, duRGBA(255,255,255,64), 2.0f); - + + duDebugDrawCircle(&dd, dx, dy, dz, ag->params.maxSpeed, duRGBA(255, 255, 255, 64), 2.0f); + dd.begin(DU_DRAW_QUADS); for (int j = 0; j < vod->getSampleCount(); ++j) { @@ -470,67 +433,84 @@ void CrowdToolState::handleRender() const float sr = vod->getSampleSize(j); const float pen = vod->getSamplePenalty(j); const float pen2 = vod->getSamplePreferredSidePenalty(j); - unsigned int col = duLerpCol(duRGBA(255,255,255,220), duRGBA(128,96,0,220), (int)(pen*255)); - col = duLerpCol(col, duRGBA(128,0,0,220), (int)(pen2*128)); - dd.vertex(dx+p[0]-sr, dy, dz+p[2]-sr, col); - dd.vertex(dx+p[0]-sr, dy, dz+p[2]+sr, col); - dd.vertex(dx+p[0]+sr, dy, dz+p[2]+sr, col); - dd.vertex(dx+p[0]+sr, dy, dz+p[2]-sr, col); + unsigned int col = duLerpCol(duRGBA(255, 255, 255, 220), duRGBA(128, 96, 0, 220), (int)(pen * 255)); + col = duLerpCol(col, duRGBA(128, 0, 0, 220), (int)(pen2 * 128)); + dd.vertex(dx + p[0] - sr, dy, dz + p[2] - sr, col); + dd.vertex(dx + p[0] - sr, dy, dz + p[2] + sr, col); + dd.vertex(dx + p[0] + sr, dy, dz + p[2] + sr, col); + dd.vertex(dx + p[0] + sr, dy, dz + p[2] - sr, col); } dd.end(); } } - + // Velocity stuff. for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; - + if (!ag->active) { continue; } + const float radius = ag->params.radius; const float height = ag->params.height; const float* pos = ag->npos; const float* vel = ag->vel; const float* dvel = ag->dvel; - - unsigned int col = duRGBA(220,220,220,192); + + unsigned int col = duRGBA(220, 220, 220, 192); if (ag->targetState == DT_CROWDAGENT_TARGET_REQUESTING || ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE) - col = duLerpCol(col, duRGBA(128,0,255,192), 32); + { + col = duLerpCol(col, duRGBA(128, 0, 255, 192), 32); + } else if (ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_PATH) - col = duLerpCol(col, duRGBA(128,0,255,192), 128); - else if (ag->targetState == DT_CROWDAGENT_TARGET_FAILED) - col = duRGBA(255,32,16,192); - else if (ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) - col = duLerpCol(col, duRGBA(64,255,0,192), 128); - - duDebugDrawCircle(&dd, pos[0], pos[1]+height, pos[2], radius, col, 2.0f); - - duDebugDrawArrow(&dd, pos[0],pos[1]+height,pos[2], - pos[0]+dvel[0],pos[1]+height+dvel[1],pos[2]+dvel[2], - 0.0f, 0.4f, duRGBA(0,192,255,192), (m_agentDebug.idx == i) ? 2.0f : 1.0f); - - duDebugDrawArrow(&dd, pos[0],pos[1]+height,pos[2], - pos[0]+vel[0],pos[1]+height+vel[1],pos[2]+vel[2], - 0.0f, 0.4f, duRGBA(0,0,0,160), 2.0f); + { + col = duLerpCol(col, duRGBA(128, 0, 255, 192), 128); + } + else if (ag->targetState == DT_CROWDAGENT_TARGET_FAILED) { col = duRGBA(255, 32, 16, 192); } + else if (ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) { col = duLerpCol(col, duRGBA(64, 255, 0, 192), 128); } + + duDebugDrawCircle(&dd, pos[0], pos[1] + height, pos[2], radius, col, 2.0f); + + duDebugDrawArrow(&dd, + pos[0], + pos[1] + height, + pos[2], + pos[0] + dvel[0], + pos[1] + height + dvel[1], + pos[2] + dvel[2], + 0.0f, + 0.4f, + duRGBA(0, 192, 255, 192), + (m_agentDebug.idx == i) ? 2.0f : 1.0f); + + duDebugDrawArrow(&dd, + pos[0], + pos[1] + height, + pos[2], + pos[0] + vel[0], + pos[1] + height + vel[1], + pos[2] + vel[2], + 0.0f, + 0.4f, + duRGBA(0, 0, 0, 160), + 2.0f); } - + dd.depthMask(true); } - void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view) { GLdouble x, y, z; - + // Draw start and end point labels - if (m_targetRef && gluProject((GLdouble)m_targetPos[0], (GLdouble)m_targetPos[1], (GLdouble)m_targetPos[2], - model, proj, view, &x, &y, &z)) + if (m_targetRef && + gluProject((GLdouble)m_targetPos[0], (GLdouble)m_targetPos[1], (GLdouble)m_targetPos[2], model, proj, view, &x, &y, &z)) { - imguiDrawText((int)x, (int)(y+25), IMGUI_ALIGN_CENTER, "TARGET", imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)(y + 25), IMGUI_ALIGN_CENTER, "TARGET", imguiRGBA(0, 0, 0, 220)); } - + char label[32]; - + if (m_toolParams.m_showNodes) { dtCrowd* crowd = m_sample->getCrowd(); @@ -545,22 +525,29 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view) { for (dtNodeIndex j = pool->getFirst(i); j != DT_NULL_IDX; j = pool->getNext(j)) { - const dtNode* node = pool->getNodeAtIdx(j+1); - if (!node) continue; + const dtNode* node = pool->getNodeAtIdx(j + 1); + if (!node) { continue; } - if (gluProject((GLdouble)node->pos[0],(GLdouble)node->pos[1]+off,(GLdouble)node->pos[2], - model, proj, view, &x, &y, &z)) + if (gluProject((GLdouble)node->pos[0], + (GLdouble)node->pos[1] + off, + (GLdouble)node->pos[2], + model, + proj, + view, + &x, + &y, + &z)) { - const float heuristic = node->total;// - node->cost; + const float heuristic = node->total; // - node->cost; snprintf(label, 32, "%.2f", heuristic); - imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)y + 15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0, 0, 0, 220)); } } } } } } - + if (m_toolParams.m_showLabels) { dtCrowd* crowd = m_sample->getCrowd(); @@ -569,78 +556,79 @@ void CrowdToolState::handleRenderOverlay(double* proj, double* model, int* view) for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } const float* pos = ag->npos; const float h = ag->params.height; - if (gluProject((GLdouble)pos[0], (GLdouble)pos[1]+h, (GLdouble)pos[2], - model, proj, view, &x, &y, &z)) + if (gluProject((GLdouble)pos[0], (GLdouble)pos[1] + h, (GLdouble)pos[2], model, proj, view, &x, &y, &z)) { snprintf(label, 32, "%d", i); - imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)y + 15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0, 0, 0, 220)); } - } + } } } if (m_agentDebug.idx != -1) { dtCrowd* crowd = m_sample->getCrowd(); - if (crowd) + if (crowd) { for (int i = 0; i < crowd->getAgentCount(); i++) { - if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) - continue; - const dtCrowdAgent* ag =crowd->getAgent(i); - if (!ag->active) - continue; + if (m_toolParams.m_showDetailAll == false && i != m_agentDebug.idx) { continue; } + const dtCrowdAgent* ag = crowd->getAgent(i); + if (!ag->active) { continue; } const float radius = ag->params.radius; if (m_toolParams.m_showNeis) { for (int j = 0; j < ag->nneis; ++j) { const dtCrowdAgent* nei = crowd->getAgent(ag->neis[j].idx); - if (!nei->active) continue; - - if (gluProject((GLdouble)nei->npos[0], (GLdouble)nei->npos[1]+radius, (GLdouble)nei->npos[2], - model, proj, view, &x, &y, &z)) + if (!nei->active) { continue; } + + if (gluProject((GLdouble)nei->npos[0], + (GLdouble)nei->npos[1] + radius, + (GLdouble)nei->npos[2], + model, + proj, + view, + &x, + &y, + &z)) { snprintf(label, 32, "%.3f", ag->neis[j].dist); - imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(255,255,255,220)); + imguiDrawText((int)x, (int)y + 15, IMGUI_ALIGN_CENTER, label, imguiRGBA(255, 255, 255, 220)); } } } } } } - - + if (m_toolParams.m_showPerfGraph) { GraphParams gp; gp.setRect(300, 10, 500, 200, 8); gp.setValueRange(0.0f, 2.0f, 4, "ms"); - + drawGraphBackground(&gp); - drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255,128,0,255)); - + drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(255, 128, 0, 255)); + gp.setRect(300, 10, 500, 50, 8); gp.setValueRange(0.0f, 2000.0f, 1, ""); - drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128)); + drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(96, 96, 96, 128)); } - } void CrowdToolState::handleUpdate(const float dt) { - if (m_run) - updateTick(dt); + if (m_run) { updateTick(dt); } } void CrowdToolState::addAgent(const float* p) { - if (!m_sample) return; + if (!m_sample) { return; } dtCrowd* crowd = m_sample->getCrowd(); - + dtCrowdAgentParams ap; memset(&ap, 0, sizeof(ap)); ap.radius = m_sample->getAgentRadius(); @@ -649,49 +637,38 @@ void CrowdToolState::addAgent(const float* p) ap.maxSpeed = 3.5f; ap.collisionQueryRange = ap.radius * 12.0f; ap.pathOptimizationRange = ap.radius * 30.0f; - ap.updateFlags = 0; - if (m_toolParams.m_anticipateTurns) - ap.updateFlags |= DT_CROWD_ANTICIPATE_TURNS; - if (m_toolParams.m_optimizeVis) - ap.updateFlags |= DT_CROWD_OPTIMIZE_VIS; - if (m_toolParams.m_optimizeTopo) - ap.updateFlags |= DT_CROWD_OPTIMIZE_TOPO; - if (m_toolParams.m_obstacleAvoidance) - ap.updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; - if (m_toolParams.m_separation) - ap.updateFlags |= DT_CROWD_SEPARATION; + ap.updateFlags = 0; + if (m_toolParams.m_anticipateTurns) { ap.updateFlags |= DT_CROWD_ANTICIPATE_TURNS; } + if (m_toolParams.m_optimizeVis) { ap.updateFlags |= DT_CROWD_OPTIMIZE_VIS; } + if (m_toolParams.m_optimizeTopo) { ap.updateFlags |= DT_CROWD_OPTIMIZE_TOPO; } + if (m_toolParams.m_obstacleAvoidance) { ap.updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; } + if (m_toolParams.m_separation) { ap.updateFlags |= DT_CROWD_SEPARATION; } ap.obstacleAvoidanceType = (unsigned char)m_toolParams.m_obstacleAvoidanceType; ap.separationWeight = m_toolParams.m_separationWeight; - + int idx = crowd->addAgent(p, &ap); if (idx != -1) { - if (m_targetRef) - crowd->requestMoveTarget(idx, m_targetRef, m_targetPos); - + if (m_targetRef) { crowd->requestMoveTarget(idx, m_targetRef, m_targetPos); } + // Init trail AgentTrail* trail = &m_trails[idx]; - for (int i = 0; i < AGENT_MAX_TRAIL; ++i) - dtVcopy(&trail->trail[i*3], p); + for (int i = 0; i < AGENT_MAX_TRAIL; ++i) { dtVcopy(&trail->trail[i * 3], p); } trail->htrail = 0; } } void CrowdToolState::removeAgent(const int idx) { - if (!m_sample) return; + if (!m_sample) { return; } dtCrowd* crowd = m_sample->getCrowd(); crowd->removeAgent(idx); - - if (idx == m_agentDebug.idx) - m_agentDebug.idx = -1; + + if (idx == m_agentDebug.idx) { m_agentDebug.idx = -1; } } -void CrowdToolState::hilightAgent(const int idx) -{ - m_agentDebug.idx = idx; -} +void CrowdToolState::hilightAgent(const int idx) { m_agentDebug.idx = idx; } static void calcVel(float* vel, const float* pos, const float* tgt, const float speed) { @@ -703,8 +680,8 @@ static void calcVel(float* vel, const float* pos, const float* tgt, const float void CrowdToolState::setMoveTarget(const float* p, bool adjust) { - if (!m_sample) return; - + if (!m_sample) { return; } + // Find nearest point on navmesh and set move request to that location. dtNavMeshQuery* navquery = m_sample->getNavMeshQuery(); dtCrowd* crowd = m_sample->getCrowd(); @@ -729,7 +706,7 @@ void CrowdToolState::setMoveTarget(const float* p, bool adjust) for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } calcVel(vel, ag->npos, p, ag->params.maxSpeed); crowd->requestMoveVelocity(i, vel); } @@ -738,19 +715,18 @@ void CrowdToolState::setMoveTarget(const float* p, bool adjust) else { navquery->findNearestPoly(p, halfExtents, filter, &m_targetRef, m_targetPos); - + if (m_agentDebug.idx != -1) { const dtCrowdAgent* ag = crowd->getAgent(m_agentDebug.idx); - if (ag && ag->active) - crowd->requestMoveTarget(m_agentDebug.idx, m_targetRef, m_targetPos); + if (ag && ag->active) { crowd->requestMoveTarget(m_agentDebug.idx, m_targetRef, m_targetPos); } } else { for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } crowd->requestMoveTarget(i, m_targetRef, m_targetPos); } } @@ -759,26 +735,26 @@ void CrowdToolState::setMoveTarget(const float* p, bool adjust) int CrowdToolState::hitTestAgents(const float* s, const float* p) { - if (!m_sample) return -1; + if (!m_sample) { return -1; } dtCrowd* crowd = m_sample->getCrowd(); - + int isel = -1; float tsel = FLT_MAX; for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } float bmin[3], bmax[3]; getAgentBounds(ag, bmin, bmax); float tmin, tmax; - if (isectSegAABB(s, p, bmin,bmax, tmin, tmax)) + if (isectSegAABB(s, p, bmin, bmax, tmin, tmax)) { if (tmin > 0 && tmin < tsel) { isel = i; tsel = tmin; - } + } } } @@ -787,93 +763,72 @@ int CrowdToolState::hitTestAgents(const float* s, const float* p) void CrowdToolState::updateAgentParams() { - if (!m_sample) return; + if (!m_sample) { return; } dtCrowd* crowd = m_sample->getCrowd(); - if (!crowd) return; - + if (!crowd) { return; } + unsigned char updateFlags = 0; unsigned char obstacleAvoidanceType = 0; - - if (m_toolParams.m_anticipateTurns) - updateFlags |= DT_CROWD_ANTICIPATE_TURNS; - if (m_toolParams.m_optimizeVis) - updateFlags |= DT_CROWD_OPTIMIZE_VIS; - if (m_toolParams.m_optimizeTopo) - updateFlags |= DT_CROWD_OPTIMIZE_TOPO; - if (m_toolParams.m_obstacleAvoidance) - updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; - if (m_toolParams.m_obstacleAvoidance) - updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; - if (m_toolParams.m_separation) - updateFlags |= DT_CROWD_SEPARATION; - + + if (m_toolParams.m_anticipateTurns) { updateFlags |= DT_CROWD_ANTICIPATE_TURNS; } + if (m_toolParams.m_optimizeVis) { updateFlags |= DT_CROWD_OPTIMIZE_VIS; } + if (m_toolParams.m_optimizeTopo) { updateFlags |= DT_CROWD_OPTIMIZE_TOPO; } + if (m_toolParams.m_obstacleAvoidance) { updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; } + if (m_toolParams.m_obstacleAvoidance) { updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; } + if (m_toolParams.m_separation) { updateFlags |= DT_CROWD_SEPARATION; } + obstacleAvoidanceType = (unsigned char)m_toolParams.m_obstacleAvoidanceType; - + dtCrowdAgentParams params; - + for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); - if (!ag->active) continue; + if (!ag->active) { continue; } memcpy(¶ms, &ag->params, sizeof(dtCrowdAgentParams)); params.updateFlags = updateFlags; params.obstacleAvoidanceType = obstacleAvoidanceType; params.separationWeight = m_toolParams.m_separationWeight; crowd->updateAgentParameters(i, ¶ms); - } + } } void CrowdToolState::updateTick(const float dt) { - if (!m_sample) return; + if (!m_sample) { return; } dtNavMesh* nav = m_sample->getNavMesh(); dtCrowd* crowd = m_sample->getCrowd(); - if (!nav || !crowd) return; - + if (!nav || !crowd) { return; } + TimeVal startTime = getPerfTime(); - + crowd->update(dt, &m_agentDebug); - + TimeVal endTime = getPerfTime(); - + // Update agent trails for (int i = 0; i < crowd->getAgentCount(); ++i) { const dtCrowdAgent* ag = crowd->getAgent(i); AgentTrail* trail = &m_trails[i]; - if (!ag->active) - continue; + if (!ag->active) { continue; } // Update agent movement trail. trail->htrail = (trail->htrail + 1) % AGENT_MAX_TRAIL; - dtVcopy(&trail->trail[trail->htrail*3], ag->npos); + dtVcopy(&trail->trail[trail->htrail * 3], ag->npos); } - + m_agentDebug.vod->normalizeSamples(); - + m_crowdSampleCount.addSample((float)crowd->getVelocitySampleCount()); m_crowdTotalTime.addSample(getPerfTimeUsec(endTime - startTime) / 1000.0f); } - - - -CrowdTool::CrowdTool() : - m_sample(0), - m_state(0), - m_mode(TOOLMODE_CREATE) -{ -} - void CrowdTool::init(Sample* sample) { - if (m_sample != sample) - { - m_sample = sample; - } - - if (!sample) - return; - + if (m_sample != sample) { m_sample = sample; } + + if (!sample) { return; } + m_state = (CrowdToolState*)sample->getToolState(static_cast(type())); if (!m_state) { @@ -883,30 +838,22 @@ void CrowdTool::init(Sample* sample) m_state->init(sample); } -void CrowdTool::reset() -{ -} +void CrowdTool::reset() {} void CrowdTool::handleMenu() { - if (!m_state) - return; + if (!m_state) { return; } CrowdToolParams* params = m_state->getToolParams(); - if (imguiCheck("Create Agents", m_mode == TOOLMODE_CREATE)) - m_mode = TOOLMODE_CREATE; - if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET)) - m_mode = TOOLMODE_MOVE_TARGET; - if (imguiCheck("Select Agent", m_mode == TOOLMODE_SELECT)) - m_mode = TOOLMODE_SELECT; - if (imguiCheck("Toggle Polys", m_mode == TOOLMODE_TOGGLE_POLYS)) - m_mode = TOOLMODE_TOGGLE_POLYS; - + if (imguiCheck("Create Agents", m_mode == ToolMode::CREATE)) { m_mode = ToolMode::CREATE; } + if (imguiCheck("Move Target", m_mode == ToolMode::MOVE_TARGET)) { m_mode = ToolMode::MOVE_TARGET; } + if (imguiCheck("Select Agent", m_mode == ToolMode::SELECT)) { m_mode = ToolMode::SELECT; } + if (imguiCheck("Toggle Polys", m_mode == ToolMode::TOGGLE_POLYS)) { m_mode = ToolMode::TOGGLE_POLYS; } + imguiSeparatorLine(); - - if (imguiCollapse("Options", 0, params->m_expandOptions)) - params->m_expandOptions = !params->m_expandOptions; - + + if (imguiCollapse("Options", 0, params->m_expandOptions)) { params->m_expandOptions = !params->m_expandOptions; } + if (params->m_expandOptions) { imguiIndent(); @@ -939,72 +886,61 @@ void CrowdTool::handleMenu() params->m_separation = !params->m_separation; m_state->updateAgentParams(); } - if (imguiSlider("Separation Weight", ¶ms->m_separationWeight, 0.0f, 20.0f, 0.01f)) - { - m_state->updateAgentParams(); - } - + if (imguiSlider("Separation Weight", ¶ms->m_separationWeight, 0.0f, 20.0f, 0.01f)) { m_state->updateAgentParams(); } + imguiUnindent(); } if (imguiCollapse("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw)) + { params->m_expandSelectedDebugDraw = !params->m_expandSelectedDebugDraw; - + } + if (params->m_expandSelectedDebugDraw) { imguiIndent(); - if (imguiCheck("Show Corners", params->m_showCorners)) - params->m_showCorners = !params->m_showCorners; + if (imguiCheck("Show Corners", params->m_showCorners)) { params->m_showCorners = !params->m_showCorners; } if (imguiCheck("Show Collision Segs", params->m_showCollisionSegments)) + { params->m_showCollisionSegments = !params->m_showCollisionSegments; - if (imguiCheck("Show Path", params->m_showPath)) - params->m_showPath = !params->m_showPath; - if (imguiCheck("Show VO", params->m_showVO)) - params->m_showVO = !params->m_showVO; - if (imguiCheck("Show Path Optimization", params->m_showOpt)) - params->m_showOpt = !params->m_showOpt; - if (imguiCheck("Show Neighbours", params->m_showNeis)) - params->m_showNeis = !params->m_showNeis; + } + if (imguiCheck("Show Path", params->m_showPath)) { params->m_showPath = !params->m_showPath; } + if (imguiCheck("Show VO", params->m_showVO)) { params->m_showVO = !params->m_showVO; } + if (imguiCheck("Show Path Optimization", params->m_showOpt)) { params->m_showOpt = !params->m_showOpt; } + if (imguiCheck("Show Neighbours", params->m_showNeis)) { params->m_showNeis = !params->m_showNeis; } imguiUnindent(); } - - if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw)) - params->m_expandDebugDraw = !params->m_expandDebugDraw; - + + if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw)) { params->m_expandDebugDraw = !params->m_expandDebugDraw; } + if (params->m_expandDebugDraw) { imguiIndent(); - if (imguiCheck("Show Labels", params->m_showLabels)) - params->m_showLabels = !params->m_showLabels; - if (imguiCheck("Show Prox Grid", params->m_showGrid)) - params->m_showGrid = !params->m_showGrid; - if (imguiCheck("Show Nodes", params->m_showNodes)) - params->m_showNodes = !params->m_showNodes; - if (imguiCheck("Show Perf Graph", params->m_showPerfGraph)) - params->m_showPerfGraph = !params->m_showPerfGraph; - if (imguiCheck("Show Detail All", params->m_showDetailAll)) - params->m_showDetailAll = !params->m_showDetailAll; + if (imguiCheck("Show Labels", params->m_showLabels)) { params->m_showLabels = !params->m_showLabels; } + if (imguiCheck("Show Prox Grid", params->m_showGrid)) { params->m_showGrid = !params->m_showGrid; } + if (imguiCheck("Show Nodes", params->m_showNodes)) { params->m_showNodes = !params->m_showNodes; } + if (imguiCheck("Show Perf Graph", params->m_showPerfGraph)) { params->m_showPerfGraph = !params->m_showPerfGraph; } + if (imguiCheck("Show Detail All", params->m_showDetailAll)) { params->m_showDetailAll = !params->m_showDetailAll; } imguiUnindent(); } } void CrowdTool::handleClick(const float* s, const float* p, bool shift) { - if (!m_sample) return; - if (!m_state) return; + if (!m_sample) { return; } + if (!m_state) { return; } InputGeom* geom = m_sample->getInputGeom(); - if (!geom) return; + if (!geom) { return; } dtCrowd* crowd = m_sample->getCrowd(); - if (!crowd) return; + if (!crowd) { return; } - if (m_mode == TOOLMODE_CREATE) + if (m_mode == ToolMode::CREATE) { if (shift) { // Delete - int ahit = m_state->hitTestAgents(s,p); - if (ahit != -1) - m_state->removeAgent(ahit); + int ahit = m_state->hitTestAgents(s, p); + if (ahit != -1) { m_state->removeAgent(ahit); } } else { @@ -1012,17 +948,14 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift) m_state->addAgent(p); } } - else if (m_mode == TOOLMODE_MOVE_TARGET) - { - m_state->setMoveTarget(p, shift); - } - else if (m_mode == TOOLMODE_SELECT) + else if (m_mode == ToolMode::MOVE_TARGET) { m_state->setMoveTarget(p, shift); } + else if (m_mode == ToolMode::SELECT) { // Highlight - int ahit = m_state->hitTestAgents(s,p); + int ahit = m_state->hitTestAgents(s, p); m_state->hilightAgent(ahit); } - else if (m_mode == TOOLMODE_TOGGLE_POLYS) + else if (m_mode == ToolMode::TOGGLE_POLYS) { dtNavMesh* nav = m_sample->getNavMesh(); dtNavMeshQuery* navquery = m_sample->getNavMeshQuery(); @@ -1044,14 +977,13 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift) } } } - } void CrowdTool::handleStep() { - if (!m_state) return; - - const float dt = 1.0f/20.0f; + if (!m_state) { return; } + + const float dt = 1.0f / 20.0f; m_state->updateTick(dt); m_state->setRunning(false); @@ -1059,18 +991,13 @@ void CrowdTool::handleStep() void CrowdTool::handleToggle() { - if (!m_state) return; + if (!m_state) { return; } m_state->setRunning(!m_state->isRunning()); } -void CrowdTool::handleUpdate(const float dt) -{ - rcIgnoreUnused(dt); -} +void CrowdTool::handleUpdate(const float dt) { rcIgnoreUnused(dt); } -void CrowdTool::handleRender() -{ -} +void CrowdTool::handleRender() {} void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view) { @@ -1079,28 +1006,35 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view) // Tool help const int h = view[3]; - int ty = h-40; - - if (m_mode == TOOLMODE_CREATE) + int ty = h - 40; + + if (m_mode == ToolMode::CREATE) { - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: add agent. Shift+LMB: remove agent.", imguiRGBA(255,255,255,192)); + imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: add agent. Shift+LMB: remove agent.", imguiRGBA(255, 255, 255, 192)); } - else if (m_mode == TOOLMODE_MOVE_TARGET) + else if (m_mode == ToolMode::MOVE_TARGET) { - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: set move target. Shift+LMB: adjust set velocity.", imguiRGBA(255,255,255,192)); + imguiDrawText( + 280, ty, IMGUI_ALIGN_LEFT, "LMB: set move target. Shift+LMB: adjust set velocity.", imguiRGBA(255, 255, 255, 192)); ty -= 20; - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "Setting velocity will move the agents without pathfinder.", imguiRGBA(255,255,255,192)); + imguiDrawText(280, + ty, + IMGUI_ALIGN_LEFT, + "Setting velocity will move the agents without pathfinder.", + imguiRGBA(255, 255, 255, 192)); } - else if (m_mode == TOOLMODE_SELECT) + else if (m_mode == ToolMode::SELECT) { - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: select agent.", imguiRGBA(255,255,255,192)); + imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "LMB: select agent.", imguiRGBA(255, 255, 255, 192)); } ty -= 20; - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "SPACE: Run/Pause simulation. 1: Step simulation.", imguiRGBA(255,255,255,192)); + imguiDrawText( + 280, ty, IMGUI_ALIGN_LEFT, "SPACE: Run/Pause simulation. 1: Step simulation.", imguiRGBA(255, 255, 255, 192)); ty -= 20; if (m_state && m_state->isRunning()) - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- RUNNING -", imguiRGBA(255,32,16,255)); - else - imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- PAUSED -", imguiRGBA(255,255,255,128)); + { + imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- RUNNING -", imguiRGBA(255, 32, 16, 255)); + } + else { imguiDrawText(280, ty, IMGUI_ALIGN_LEFT, "- PAUSED -", imguiRGBA(255, 255, 255, 128)); } } diff --git a/RecastDemo/Source/Filelist.cpp b/RecastDemo/Source/Filelist.cpp index 6d02ae5f..7492e1fe 100644 --- a/RecastDemo/Source/Filelist.cpp +++ b/RecastDemo/Source/Filelist.cpp @@ -33,10 +33,7 @@ void scanDirectoryAppend(const std::string& path, const std::string& ext, std::v _finddata_t dir; intptr_t fh = _findfirst(pathWithExt.c_str(), &dir); - if (fh == -1L) - { - return; - } + if (fh == -1L) { return; } do { diff --git a/RecastDemo/Source/NavMeshPruneTool.cpp b/RecastDemo/Source/NavMeshPruneTool.cpp index e1941f7f..08019167 100644 --- a/RecastDemo/Source/NavMeshPruneTool.cpp +++ b/RecastDemo/Source/NavMeshPruneTool.cpp @@ -16,21 +16,24 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include "NavMeshPruneTool.h" + +#include "DetourAssert.h" +#include "DetourCommon.h" +#include "DetourDebugDraw.h" +#include "DetourNavMesh.h" +#include "InputGeom.h" +#include "SDL.h" +#include "SDL_opengl.h" +#include "Sample.h" +#include "imgui.h" + +#include #include #include #include -#include + #include -#include "SDL.h" -#include "SDL_opengl.h" -#include "imgui.h" -#include "NavMeshPruneTool.h" -#include "InputGeom.h" -#include "Sample.h" -#include "DetourNavMesh.h" -#include "DetourCommon.h" -#include "DetourAssert.h" -#include "DetourDebugDraw.h" #ifdef WIN32 # define snprintf _snprintf @@ -46,13 +49,11 @@ class NavmeshFlags dtPolyRef base; }; - const dtNavMesh* m_nav; - TileFlags* m_tiles; - int m_ntiles; + const dtNavMesh* m_nav = nullptr; + TileFlags* m_tiles = nullptr; + int m_ntiles = 0; public: - NavmeshFlags() : m_nav(0), m_tiles(0), m_ntiles(0) { } - ~NavmeshFlags() { for (int i = 0; i < m_ntiles; ++i) @@ -67,9 +68,9 @@ public: m_ntiles = nav->getMaxTiles(); if (!m_ntiles) { return true; } - m_tiles = (TileFlags*)dtAlloc(sizeof(TileFlags)*m_ntiles, DT_ALLOC_TEMP); + m_tiles = (TileFlags*)dtAlloc(sizeof(TileFlags) * m_ntiles, DT_ALLOC_TEMP); if (!m_tiles) { return false; } - memset(m_tiles, 0, sizeof(TileFlags)*m_ntiles); + memset(m_tiles, 0, sizeof(TileFlags) * m_ntiles); // Alloc flags for each tile. for (int i = 0; i < nav->getMaxTiles(); ++i) @@ -189,7 +190,8 @@ NavMeshPruneTool::~NavMeshPruneTool() void NavMeshPruneTool::reset() { m_hitPosSet = false; - delete m_flags; m_flags = nullptr; + delete m_flags; + m_flags = nullptr; } void NavMeshPruneTool::handleMenu() @@ -206,7 +208,8 @@ void NavMeshPruneTool::handleMenu() if (imguiButton("Prune Unselected")) { disableUnvisitedPolys(nav, m_flags); - delete m_flags; m_flags = nullptr; + delete m_flags; + m_flags = nullptr; } } @@ -232,7 +235,7 @@ void NavMeshPruneTool::handleClick(const float* s, const float* p, bool shift) m_flags->init(nav); } - const float halfExtents[3] = { 2, 4, 2 }; + const float halfExtents[3] = {2, 4, 2}; dtQueryFilter filter; dtPolyRef ref = 0; query->findNearestPoly(p, halfExtents, &filter, &ref, 0); @@ -247,14 +250,14 @@ void NavMeshPruneTool::handleRender() if (m_hitPosSet) { const float s = m_sample->getAgentRadius(); - const unsigned int col = duRGBA(255,255,255,255); + const unsigned int col = duRGBA(255, 255, 255, 255); debugDraw.begin(DU_DRAW_LINES); - debugDraw.vertex(m_hitPos[0]-s,m_hitPos[1],m_hitPos[2], col); - debugDraw.vertex(m_hitPos[0]+s,m_hitPos[1],m_hitPos[2], col); - debugDraw.vertex(m_hitPos[0],m_hitPos[1]-s,m_hitPos[2], col); - debugDraw.vertex(m_hitPos[0],m_hitPos[1]+s,m_hitPos[2], col); - debugDraw.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]-s, col); - debugDraw.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]+s, col); + debugDraw.vertex(m_hitPos[0] - s, m_hitPos[1], m_hitPos[2], col); + debugDraw.vertex(m_hitPos[0] + s, m_hitPos[1], m_hitPos[2], col); + debugDraw.vertex(m_hitPos[0], m_hitPos[1] - s, m_hitPos[2], col); + debugDraw.vertex(m_hitPos[0], m_hitPos[1] + s, m_hitPos[2], col); + debugDraw.vertex(m_hitPos[0], m_hitPos[1], m_hitPos[2] - s, col); + debugDraw.vertex(m_hitPos[0], m_hitPos[1], m_hitPos[2] + s, col); debugDraw.end(); } @@ -271,7 +274,7 @@ void NavMeshPruneTool::handleRender() const dtPolyRef ref = base | (unsigned int)j; if (m_flags->getFlags(ref)) { - duDebugDrawNavMeshPoly(&debugDraw, *nav, ref, duRGBA(255,255,255,128)); + duDebugDrawNavMeshPoly(&debugDraw, *nav, ref, duRGBA(255, 255, 255, 128)); } } } @@ -280,10 +283,5 @@ void NavMeshPruneTool::handleRender() void NavMeshPruneTool::handleRenderOverlay(double* /*proj*/, double* /*model*/, int* view) { - imguiDrawText( - 280, - view[3] - 40, - IMGUI_ALIGN_LEFT, - "LMB: Click fill area.", - imguiRGBA(255, 255, 255, 192)); + imguiDrawText(280, view[3] - 40, IMGUI_ALIGN_LEFT, "LMB: Click fill area.", imguiRGBA(255, 255, 255, 192)); } diff --git a/RecastDemo/Source/NavMeshTesterTool.cpp b/RecastDemo/Source/NavMeshTesterTool.cpp index cff9def4..4f8a2f5c 100644 --- a/RecastDemo/Source/NavMeshTesterTool.cpp +++ b/RecastDemo/Source/NavMeshTesterTool.cpp @@ -16,27 +16,28 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include "SDL.h" +#include "SDL_opengl.h" + #include #include #include #include -#include "SDL.h" -#include "SDL_opengl.h" #ifdef __APPLE__ # include #else # include #endif -#include "imgui.h" -#include "NavMeshTesterTool.h" -#include "Sample.h" -#include "Recast.h" -#include "RecastDebugDraw.h" +#include "DetourCommon.h" +#include "DetourDebugDraw.h" #include "DetourNavMesh.h" #include "DetourNavMeshBuilder.h" -#include "DetourDebugDraw.h" -#include "DetourCommon.h" #include "DetourPathCorridor.h" +#include "NavMeshTesterTool.h" +#include "Recast.h" +#include "RecastDebugDraw.h" +#include "Sample.h" +#include "imgui.h" #ifdef WIN32 # define snprintf _snprintf @@ -48,8 +49,7 @@ // Returns a random number [0..1] static float frand() { -// return ((float)(rand() & 0xffff)/(float)0xffff); - return (float)rand()/(float)RAND_MAX; + return (float)rand() / (float)RAND_MAX; } inline bool inRange(const float* v1, const float* v2, const float r, const float h) @@ -57,7 +57,7 @@ inline bool inRange(const float* v1, const float* v2, const float r, const float const float dx = v2[0] - v1[0]; const float dy = v2[1] - v1[1]; const float dz = v2[2] - v1[2]; - return (dx*dx + dz*dz) < r*r && fabsf(dy) < h; + return (dx * dx + dz * dz) < r * r && fabsf(dy) < h; } // This function checks if the path has a small U-turn, that is, @@ -65,7 +65,7 @@ inline bool inRange(const float* v1, const float* v2, const float r, const float // in the path. If that happens, a shortcut is taken. // This can happen if the target (T) location is at tile boundary, // and we're (S) approaching it parallel to the tile edge. -// The choice at the vertex can be arbitrary, +// The choice at the vertex can be arbitrary, // +---+---+ // |:::|:::| // +-S-+-T-+ @@ -73,8 +73,7 @@ inline bool inRange(const float* v1, const float* v2, const float r, const float // +---+---+ static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery) { - if (npath < 3) - return npath; + if (npath < 3) { return npath; } // Get connected polygons static const int maxNeis = 16; @@ -83,16 +82,17 @@ static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery) const dtMeshTile* tile = 0; const dtPoly* poly = 0; - if (dtStatusFailed(navQuery->getAttachedNavMesh()->getTileAndPolyByRef(path[0], &tile, &poly))) - return npath; - + if (dtStatusFailed(navQuery->getAttachedNavMesh()->getTileAndPolyByRef(path[0], &tile, &poly))) { return npath; } + for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) { const dtLink* link = &tile->links[k]; if (link->ref != 0) { if (nneis < maxNeis) + { neis[nneis++] = link->ref; + } } } @@ -100,10 +100,12 @@ static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery) // in the path, short cut to that polygon directly. static const int maxLookAhead = 6; int cut = 0; - for (int i = dtMin(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--) { + for (int i = dtMin(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--) + { for (int j = 0; j < nneis; j++) { - if (path[i] == neis[j]) { + if (path[i] == neis[j]) + { cut = i; break; } @@ -111,94 +113,81 @@ static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery) } if (cut > 1) { - int offset = cut-1; + int offset = cut - 1; npath -= offset; for (int i = 1; i < npath; i++) - path[i] = path[i+offset]; + { + path[i] = path[i + offset]; + } } return npath; } -static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, const float* endPos, - const float minTargetDist, - const dtPolyRef* path, const int pathSize, - float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef, - float* outPoints = 0, int* outPointCount = 0) +static bool getSteerTarget(dtNavMeshQuery* navQuery, + const float* startPos, + const float* endPos, + const float minTargetDist, + const dtPolyRef* path, + const int pathSize, + float* steerPos, + unsigned char& steerPosFlag, + dtPolyRef& steerPosRef, + float* outPoints = 0, + int* outPointCount = 0) { // Find steer target. static const int MAX_STEER_POINTS = 3; - float steerPath[MAX_STEER_POINTS*3]; + float steerPath[MAX_STEER_POINTS * 3]; unsigned char steerPathFlags[MAX_STEER_POINTS]; dtPolyRef steerPathPolys[MAX_STEER_POINTS]; int nsteerPath = 0; - navQuery->findStraightPath(startPos, endPos, path, pathSize, - steerPath, steerPathFlags, steerPathPolys, &nsteerPath, MAX_STEER_POINTS); - if (!nsteerPath) - return false; - + navQuery->findStraightPath( + startPos, + endPos, + path, + pathSize, + steerPath, + steerPathFlags, + steerPathPolys, + &nsteerPath, + MAX_STEER_POINTS); + + if (!nsteerPath) { return false; } + if (outPoints && outPointCount) { *outPointCount = nsteerPath; for (int i = 0; i < nsteerPath; ++i) - dtVcopy(&outPoints[i*3], &steerPath[i*3]); + { + dtVcopy(&outPoints[i * 3], &steerPath[i * 3]); + } } - // Find vertex far enough to steer to. int ns = 0; while (ns < nsteerPath) { // Stop at Off-Mesh link or when point is further than slop away. - if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || - !inRange(&steerPath[ns*3], startPos, minTargetDist, 1000.0f)) - break; + if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)) { break; } + if (!inRange(&steerPath[ns * 3], startPos, minTargetDist, 1000.0f)) { break; } ns++; } // Failed to find good point to steer to. - if (ns >= nsteerPath) - return false; - - dtVcopy(steerPos, &steerPath[ns*3]); + if (ns >= nsteerPath) { return false; } + + dtVcopy(steerPos, &steerPath[ns * 3]); steerPos[1] = startPos[1]; steerPosFlag = steerPathFlags[ns]; steerPosRef = steerPathPolys[ns]; - + return true; } - -NavMeshTesterTool::NavMeshTesterTool() : - m_sample(0), - m_navMesh(0), - m_navQuery(0), - m_pathFindStatus(DT_FAILURE), - m_toolMode(TOOLMODE_PATHFIND_FOLLOW), - m_straightPathOptions(0), - m_startRef(0), - m_endRef(0), - m_npolys(0), - m_nstraightPath(0), - m_nsmoothPath(0), - m_nrandPoints(0), - m_randPointsInCircle(false), - m_hitResult(false), - m_distanceToWall(0), - m_sposSet(false), - m_eposSet(false), - m_pathIterNum(0), - m_pathIterPolyCount(0), - m_steerPointCount(0) +NavMeshTesterTool::NavMeshTesterTool() { m_filter.setIncludeFlags(SAMPLE_POLYFLAGS_ALL ^ SAMPLE_POLYFLAGS_DISABLED); m_filter.setExcludeFlags(0); - - m_polyPickExt[0] = 2; - m_polyPickExt[1] = 4; - m_polyPickExt[2] = 2; - - m_neighbourhoodRadius = 2.5f; - m_randomRadius = 5.0f; } void NavMeshTesterTool::init(Sample* sample) @@ -218,7 +207,7 @@ void NavMeshTesterTool::init(Sample* sample) m_filter.setAreaCost(SAMPLE_POLYAREA_GRASS, 2.0f); m_filter.setAreaCost(SAMPLE_POLYAREA_JUMP, 1.5f); } - + m_neighbourhoodRadius = sample->getAgentRadius() * 20.0f; m_randomRadius = sample->getAgentRadius() * 30.0f; } @@ -301,7 +290,7 @@ void NavMeshTesterTool::handleMenu() } imguiSeparator(); - + if (imguiButton("Set Random Start")) { dtStatus status = m_navQuery->findRandomPoint(&m_filter, frand, &m_startRef, m_spos); @@ -315,7 +304,14 @@ void NavMeshTesterTool::handleMenu() { if (m_sposSet) { - dtStatus status = m_navQuery->findRandomPointAroundCircle(m_startRef, m_spos, m_randomRadius, &m_filter, frand, &m_endRef, m_epos); + dtStatus status = m_navQuery->findRandomPointAroundCircle( + m_startRef, + m_spos, + m_randomRadius, + &m_filter, + frand, + &m_endRef, + m_epos); if (dtStatusSucceed(status)) { m_eposSet = true; @@ -337,7 +333,7 @@ void NavMeshTesterTool::handleMenu() dtStatus status = m_navQuery->findRandomPoint(&m_filter, frand, &ref, pt); if (dtStatusSucceed(status)) { - dtVcopy(&m_randPoints[m_nrandPoints*3], pt); + dtVcopy(&m_randPoints[m_nrandPoints * 3], pt); m_nrandPoints++; } } @@ -352,17 +348,23 @@ void NavMeshTesterTool::handleMenu() { float pt[3]; dtPolyRef ref; - dtStatus status = m_navQuery->findRandomPointAroundCircle(m_startRef, m_spos, m_randomRadius, &m_filter, frand, &ref, pt); + dtStatus status = m_navQuery->findRandomPointAroundCircle( + m_startRef, + m_spos, + m_randomRadius, + &m_filter, + frand, + &ref, + pt); if (dtStatusSucceed(status)) { - dtVcopy(&m_randPoints[m_nrandPoints*3], pt); + dtVcopy(&m_randPoints[m_nrandPoints * 3], pt); m_nrandPoints++; } } } } - imguiSeparator(); imguiLabel("Include Flags"); @@ -392,7 +394,7 @@ void NavMeshTesterTool::handleMenu() imguiSeparator(); imguiLabel("Exclude Flags"); - + imguiIndent(); if (imguiCheck("Walk", (m_filter.getExcludeFlags() & SAMPLE_POLYFLAGS_WALK) != 0)) { @@ -416,7 +418,7 @@ void NavMeshTesterTool::handleMenu() } imguiUnindent(); - imguiSeparator(); + imguiSeparator(); } void NavMeshTesterTool::handleClick(const float* /*s*/, const float* p, bool shift) @@ -434,19 +436,15 @@ void NavMeshTesterTool::handleClick(const float* /*s*/, const float* p, bool shi recalc(); } -void NavMeshTesterTool::handleStep() -{ -} +void NavMeshTesterTool::handleStep() {} void NavMeshTesterTool::handleToggle() { // TODO: merge separate to a path iterator. Use same code in recalc() too. - if (m_toolMode != TOOLMODE_PATHFIND_FOLLOW) - return; - - if (!m_sposSet || !m_eposSet || !m_startRef || !m_endRef) - return; - + if (m_toolMode != TOOLMODE_PATHFIND_FOLLOW) { return; } + + if (!m_sposSet || !m_eposSet || !m_startRef || !m_endRef) { return; } + static const float STEP_SIZE = 0.5f; static const float SLOP = 0.01f; @@ -457,30 +455,30 @@ void NavMeshTesterTool::handleToggle() m_pathIterPolyCount = m_npolys; if (m_pathIterPolyCount) - memcpy(m_pathIterPolys, m_polys, sizeof(dtPolyRef)*m_pathIterPolyCount); - + { + memcpy(m_pathIterPolys, m_polys, sizeof(dtPolyRef) * m_pathIterPolyCount); + } + if (m_pathIterPolyCount) { // Iterate over the path to find smooth path on the detail mesh surface. m_navQuery->closestPointOnPoly(m_startRef, m_spos, m_iterPos, 0); - m_navQuery->closestPointOnPoly(m_pathIterPolys[m_pathIterPolyCount-1], m_epos, m_targetPos, 0); - + m_navQuery->closestPointOnPoly(m_pathIterPolys[m_pathIterPolyCount - 1], m_epos, m_targetPos, 0); + m_nsmoothPath = 0; - - dtVcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos); + + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], m_iterPos); m_nsmoothPath++; } } - + dtVcopy(m_prevIterPos, m_iterPos); m_pathIterNum++; - if (!m_pathIterPolyCount) - return; + if (!m_pathIterPolyCount) { return; } - if (m_nsmoothPath >= MAX_SMOOTH) - return; + if (m_nsmoothPath >= MAX_SMOOTH) { return; } // Move towards target a small advancement at a time until target reached or // when ran out of memory to store the path. @@ -489,44 +487,57 @@ void NavMeshTesterTool::handleToggle() float steerPos[3]; unsigned char steerPosFlag; dtPolyRef steerPosRef; - - if (!getSteerTarget(m_navQuery, m_iterPos, m_targetPos, SLOP, - m_pathIterPolys, m_pathIterPolyCount, steerPos, steerPosFlag, steerPosRef, - m_steerPoints, &m_steerPointCount)) + + if (!getSteerTarget( + m_navQuery, + m_iterPos, + m_targetPos, + SLOP, + m_pathIterPolys, + m_pathIterPolyCount, + steerPos, + steerPosFlag, + steerPosRef, + m_steerPoints, + &m_steerPointCount)) + { return; - + } + dtVcopy(m_steerPos, steerPos); - + bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) ? true : false; bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ? true : false; - + // Find movement delta. float delta[3], len; dtVsub(delta, steerPos, m_iterPos); - len = sqrtf(dtVdot(delta,delta)); + len = sqrtf(dtVdot(delta, delta)); // If the steer target is end of path or off-mesh link, do not move past the location. if ((endOfPath || offMeshConnection) && len < STEP_SIZE) + { len = 1; + } else + { len = STEP_SIZE / len; + } float moveTgt[3]; dtVmad(moveTgt, m_iterPos, delta, len); - + // Move float result[3]; dtPolyRef visited[16]; int nvisited = 0; - m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter, - result, visited, &nvisited, 16); - m_pathIterPolyCount = dtMergeCorridorStartMoved(m_pathIterPolys, m_pathIterPolyCount, - MAX_POLYS, visited, nvisited); + m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter, result, visited, &nvisited, 16); + m_pathIterPolyCount = dtMergeCorridorStartMoved(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited); m_pathIterPolyCount = fixupShortcuts(m_pathIterPolys, m_pathIterPolyCount, m_navQuery); float h = 0; m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h); result[1] = h; dtVcopy(m_iterPos, result); - + // Handle end of path and off-mesh links when close enough. if (endOfPath && inRange(m_iterPos, steerPos, SLOP, 1.0f)) { @@ -534,7 +545,7 @@ void NavMeshTesterTool::handleToggle() dtVcopy(m_iterPos, m_targetPos); if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], m_iterPos); m_nsmoothPath++; } return; @@ -543,7 +554,7 @@ void NavMeshTesterTool::handleToggle() { // Reached off-mesh connection. float startPos[3], endPos[3]; - + // Advance the path up to and over the off-mesh connection. dtPolyRef prevRef = 0, polyRef = m_pathIterPolys[0]; int npos = 0; @@ -554,21 +565,23 @@ void NavMeshTesterTool::handleToggle() npos++; } for (int i = npos; i < m_pathIterPolyCount; ++i) - m_pathIterPolys[i-npos] = m_pathIterPolys[i]; + { + m_pathIterPolys[i - npos] = m_pathIterPolys[i]; + } m_pathIterPolyCount -= npos; - + // Handle the connection. dtStatus status = m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos); if (dtStatusSucceed(status)) { if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], startPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], startPos); m_nsmoothPath++; // Hack to make the dotted path not visible during off-mesh connection. if (m_nsmoothPath & 1) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], startPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], startPos); m_nsmoothPath++; } } @@ -579,14 +592,13 @@ void NavMeshTesterTool::handleToggle() m_iterPos[1] = eh; } } - + // Store results. if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], m_iterPos); m_nsmoothPath++; } - } void NavMeshTesterTool::handleUpdate(const float /*dt*/) @@ -595,7 +607,7 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/) { if (dtStatusInProgress(m_pathFindStatus)) { - m_pathFindStatus = m_navQuery->updateSlicedFindPath(1,0); + m_pathFindStatus = m_navQuery->updateSlicedFindPath(1, 0); } if (dtStatusSucceed(m_pathFindStatus)) { @@ -606,14 +618,24 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/) // In case of partial path, make sure the end point is clamped to the last polygon. float epos[3]; dtVcopy(epos, m_epos); - if (m_polys[m_npolys-1] != m_endRef) - m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0); + if (m_polys[m_npolys - 1] != m_endRef) + { + m_navQuery->closestPointOnPoly(m_polys[m_npolys - 1], m_epos, epos, 0); + } - m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys, - m_straightPath, m_straightPathFlags, - m_straightPathPolys, &m_nstraightPath, MAX_POLYS, DT_STRAIGHTPATH_ALL_CROSSINGS); + m_navQuery->findStraightPath( + m_spos, + epos, + m_polys, + m_npolys, + m_straightPath, + m_straightPathFlags, + m_straightPathPolys, + &m_nstraightPath, + MAX_POLYS, + DT_STRAIGHTPATH_ALL_CROSSINGS); } - + m_pathFindStatus = DT_FAILURE; } } @@ -631,24 +653,30 @@ void NavMeshTesterTool::reset() m_distanceToWall = 0; } - void NavMeshTesterTool::recalc() { - if (!m_navMesh) - return; - + if (!m_navMesh) { return; } + if (m_sposSet) + { m_navQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, 0); + } else + { m_startRef = 0; - + } + if (m_eposSet) + { m_navQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, 0); + } else + { m_endRef = 0; - + } + m_pathFindStatus = DT_FAILURE; - + if (m_toolMode == TOOLMODE_PATHFIND_FOLLOW) { m_pathIterNum = 0; @@ -656,8 +684,14 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("pi %f %f %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2], - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + m_epos[0], + m_epos[1], + m_epos[2], + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, &m_npolys, MAX_POLYS); @@ -668,21 +702,21 @@ void NavMeshTesterTool::recalc() { // Iterate over the path to find smooth path on the detail mesh surface. dtPolyRef polys[MAX_POLYS]; - memcpy(polys, m_polys, sizeof(dtPolyRef)*m_npolys); + memcpy(polys, m_polys, sizeof(dtPolyRef) * m_npolys); int npolys = m_npolys; - + float iterPos[3], targetPos[3]; m_navQuery->closestPointOnPoly(m_startRef, m_spos, iterPos, 0); - m_navQuery->closestPointOnPoly(polys[npolys-1], m_epos, targetPos, 0); - + m_navQuery->closestPointOnPoly(polys[npolys - 1], m_epos, targetPos, 0); + static const float STEP_SIZE = 0.5f; static const float SLOP = 0.01f; - + m_nsmoothPath = 0; - - dtVcopy(&m_smoothPath[m_nsmoothPath*3], iterPos); + + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], iterPos); m_nsmoothPath++; - + // Move towards target a small advancement at a time until target reached or // when ran out of memory to store the path. while (npolys && m_nsmoothPath < MAX_SMOOTH) @@ -691,32 +725,45 @@ void NavMeshTesterTool::recalc() float steerPos[3]; unsigned char steerPosFlag; dtPolyRef steerPosRef; - - if (!getSteerTarget(m_navQuery, iterPos, targetPos, SLOP, - polys, npolys, steerPos, steerPosFlag, steerPosRef)) + + if (!getSteerTarget( + m_navQuery, + iterPos, + targetPos, + SLOP, + polys, + npolys, + steerPos, + steerPosFlag, + steerPosRef)) + { break; - + } + bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) ? true : false; bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ? true : false; - + // Find movement delta. float delta[3], len; dtVsub(delta, steerPos, iterPos); len = dtMathSqrtf(dtVdot(delta, delta)); // If the steer target is end of path or off-mesh link, do not move past the location. if ((endOfPath || offMeshConnection) && len < STEP_SIZE) + { len = 1; + } else + { len = STEP_SIZE / len; + } float moveTgt[3]; dtVmad(moveTgt, iterPos, delta, len); - + // Move float result[3]; dtPolyRef visited[16]; int nvisited = 0; - m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, - result, visited, &nvisited, 16); + m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, result, visited, &nvisited, 16); npolys = dtMergeCorridorStartMoved(polys, npolys, MAX_POLYS, visited, nvisited); npolys = fixupShortcuts(polys, npolys, m_navQuery); @@ -733,7 +780,7 @@ void NavMeshTesterTool::recalc() dtVcopy(iterPos, targetPos); if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], iterPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], iterPos); m_nsmoothPath++; } break; @@ -742,7 +789,7 @@ void NavMeshTesterTool::recalc() { // Reached off-mesh connection. float startPos[3], endPos[3]; - + // Advance the path up to and over the off-mesh connection. dtPolyRef prevRef = 0, polyRef = polys[0]; int npos = 0; @@ -752,22 +799,21 @@ void NavMeshTesterTool::recalc() polyRef = polys[npos]; npos++; } - for (int i = npos; i < npolys; ++i) - polys[i-npos] = polys[i]; + for (int i = npos; i < npolys; ++i) { polys[i - npos] = polys[i]; } npolys -= npos; - + // Handle the connection. dtStatus status = m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos); if (dtStatusSucceed(status)) { if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], startPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], startPos); m_nsmoothPath++; // Hack to make the dotted path not visible during off-mesh connection. if (m_nsmoothPath & 1) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], startPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], startPos); m_nsmoothPath++; } } @@ -778,16 +824,15 @@ void NavMeshTesterTool::recalc() iterPos[1] = eh; } } - + // Store results. if (m_nsmoothPath < MAX_SMOOTH) { - dtVcopy(&m_smoothPath[m_nsmoothPath*3], iterPos); + dtVcopy(&m_smoothPath[m_nsmoothPath * 3], iterPos); m_nsmoothPath++; } } } - } else { @@ -801,8 +846,14 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("ps %f %f %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2], - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + m_epos[0], + m_epos[1], + m_epos[2], + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, &m_npolys, MAX_POLYS); m_nstraightPath = 0; @@ -811,12 +862,22 @@ void NavMeshTesterTool::recalc() // In case of partial path, make sure the end point is clamped to the last polygon. float epos[3]; dtVcopy(epos, m_epos); - if (m_polys[m_npolys-1] != m_endRef) - m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0); - - m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys, - m_straightPath, m_straightPathFlags, - m_straightPathPolys, &m_nstraightPath, MAX_POLYS, m_straightPathOptions); + if (m_polys[m_npolys - 1] != m_endRef) + { + m_navQuery->closestPointOnPoly(m_polys[m_npolys - 1], m_epos, epos, 0); + } + + m_navQuery->findStraightPath( + m_spos, + epos, + m_polys, + m_npolys, + m_straightPath, + m_straightPathFlags, + m_straightPathPolys, + &m_nstraightPath, + MAX_POLYS, + m_straightPathOptions); } } else @@ -831,13 +892,25 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("ps %f %f %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2], - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + m_epos[0], + m_epos[1], + m_epos[2], + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif m_npolys = 0; m_nstraightPath = 0; - - m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, DT_FINDPATH_ANY_ANGLE); + + m_pathFindStatus = m_navQuery->initSlicedFindPath( + m_startRef, + m_endRef, + m_spos, + m_epos, + &m_filter, + DT_FINDPATH_ANY_ANGLE); } else { @@ -852,8 +925,14 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("rc %f %f %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2], - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + m_epos[0], + m_epos[1], + m_epos[2], + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif float t = 0; m_npolys = 0; @@ -878,7 +957,7 @@ void NavMeshTesterTool::recalc() if (m_npolys > 0) { float h = 0; - m_navQuery->getPolyHeight(m_polys[m_npolys-1], m_hitPos, &h); + m_navQuery->getPolyHeight(m_polys[m_npolys - 1], m_hitPos, &h); m_hitPos[1] = h; } dtVcopy(&m_straightPath[3], m_hitPos); @@ -891,8 +970,12 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("dw %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], 100.0f, - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + 100.0f, + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif m_distanceToWall = 0.0f; m_navQuery->findDistanceToWall(m_startRef, m_spos, 100.0f, &m_filter, &m_distanceToWall, m_hitPos, m_hitNormal); @@ -904,51 +987,61 @@ void NavMeshTesterTool::recalc() { const float dx = m_epos[0] - m_spos[0]; const float dz = m_epos[2] - m_spos[2]; - float dist = sqrtf(dx*dx + dz*dz); + float dist = sqrtf(dx * dx + dz * dz); #ifdef DUMP_REQS printf("fpc %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], dist, - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + dist, + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif - m_navQuery->findPolysAroundCircle(m_startRef, m_spos, dist, &m_filter, - m_polys, m_parent, 0, &m_npolys, MAX_POLYS); - + m_navQuery->findPolysAroundCircle(m_startRef, m_spos, dist, &m_filter, m_polys, m_parent, 0, &m_npolys, MAX_POLYS); } } else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE) { if (m_sposSet && m_startRef && m_eposSet) { - const float nx = (m_epos[2] - m_spos[2])*0.25f; - const float nz = -(m_epos[0] - m_spos[0])*0.25f; + const float nx = (m_epos[2] - m_spos[2]) * 0.25f; + const float nz = -(m_epos[0] - m_spos[0]) * 0.25f; const float agentHeight = m_sample ? m_sample->getAgentHeight() : 0; - m_queryPoly[0] = m_spos[0] + nx*1.2f; - m_queryPoly[1] = m_spos[1] + agentHeight/2; - m_queryPoly[2] = m_spos[2] + nz*1.2f; + m_queryPoly[0] = m_spos[0] + nx * 1.2f; + m_queryPoly[1] = m_spos[1] + agentHeight / 2; + m_queryPoly[2] = m_spos[2] + nz * 1.2f; - m_queryPoly[3] = m_spos[0] - nx*1.3f; - m_queryPoly[4] = m_spos[1] + agentHeight/2; - m_queryPoly[5] = m_spos[2] - nz*1.3f; + m_queryPoly[3] = m_spos[0] - nx * 1.3f; + m_queryPoly[4] = m_spos[1] + agentHeight / 2; + m_queryPoly[5] = m_spos[2] - nz * 1.3f; - m_queryPoly[6] = m_epos[0] - nx*0.8f; - m_queryPoly[7] = m_epos[1] + agentHeight/2; - m_queryPoly[8] = m_epos[2] - nz*0.8f; + m_queryPoly[6] = m_epos[0] - nx * 0.8f; + m_queryPoly[7] = m_epos[1] + agentHeight / 2; + m_queryPoly[8] = m_epos[2] - nz * 0.8f; m_queryPoly[9] = m_epos[0] + nx; - m_queryPoly[10] = m_epos[1] + agentHeight/2; + m_queryPoly[10] = m_epos[1] + agentHeight / 2; m_queryPoly[11] = m_epos[2] + nz; - + #ifdef DUMP_REQS printf("fpp %f %f %f %f %f %f %f %f %f %f %f %f 0x%x 0x%x\n", - m_queryPoly[0],m_queryPoly[1],m_queryPoly[2], - m_queryPoly[3],m_queryPoly[4],m_queryPoly[5], - m_queryPoly[6],m_queryPoly[7],m_queryPoly[8], - m_queryPoly[9],m_queryPoly[10],m_queryPoly[11], - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_queryPoly[0], + m_queryPoly[1], + m_queryPoly[2], + m_queryPoly[3], + m_queryPoly[4], + m_queryPoly[5], + m_queryPoly[6], + m_queryPoly[7], + m_queryPoly[8], + m_queryPoly[9], + m_queryPoly[10], + m_queryPoly[11], + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif - m_navQuery->findPolysAroundShape(m_startRef, m_queryPoly, 4, &m_filter, - m_polys, m_parent, 0, &m_npolys, MAX_POLYS); + m_navQuery->findPolysAroundShape(m_startRef, m_queryPoly, 4, &m_filter, m_polys, m_parent, 0, &m_npolys, MAX_POLYS); } } else if (m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD) @@ -957,11 +1050,15 @@ void NavMeshTesterTool::recalc() { #ifdef DUMP_REQS printf("fln %f %f %f %f 0x%x 0x%x\n", - m_spos[0],m_spos[1],m_spos[2], m_neighbourhoodRadius, - m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); + m_spos[0], + m_spos[1], + m_spos[2], + m_neighbourhoodRadius, + m_filter.getIncludeFlags(), + m_filter.getExcludeFlags()); #endif - m_navQuery->findLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, &m_filter, - m_polys, m_parent, &m_npolys, MAX_POLYS); + m_navQuery->findLocalNeighbourhood( + m_startRef, m_spos, m_neighbourhoodRadius, &m_filter, m_polys, m_parent, &m_npolys, MAX_POLYS); } } } @@ -971,16 +1068,15 @@ static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center) center[0] = 0; center[1] = 0; center[2] = 0; - + const dtMeshTile* tile = 0; const dtPoly* poly = 0; dtStatus status = navMesh->getTileAndPolyByRef(ref, &tile, &poly); - if (dtStatusFailed(status)) - return; - + if (dtStatusFailed(status)) { return; } + for (int i = 0; i < (int)poly->vertCount; ++i) { - const float* v = &tile->verts[poly->verts[i]*3]; + const float* v = &tile->verts[poly->verts[i] * 3]; center[0] += v[0]; center[1] += v[1]; center[2] += v[2]; @@ -991,138 +1087,146 @@ static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center) center[2] *= s; } - - void NavMeshTesterTool::handleRender() { duDebugDraw& dd = m_sample->getDebugDraw(); - - static const unsigned int startCol = duRGBA(128,25,0,192); - static const unsigned int endCol = duRGBA(51,102,0,129); - static const unsigned int pathCol = duRGBA(0,0,0,64); - + + static const unsigned int startCol = duRGBA(128, 25, 0, 192); + static const unsigned int endCol = duRGBA(51, 102, 0, 129); + static const unsigned int pathCol = duRGBA(0, 0, 0, 64); + const float agentRadius = m_sample->getAgentRadius(); const float agentHeight = m_sample->getAgentHeight(); const float agentClimb = m_sample->getAgentClimb(); - + dd.depthMask(false); - if (m_sposSet) - drawAgent(m_spos, agentRadius, agentHeight, agentClimb, startCol); - if (m_eposSet) - drawAgent(m_epos, agentRadius, agentHeight, agentClimb, endCol); + if (m_sposSet) { drawAgent(m_spos, agentRadius, agentHeight, agentClimb, startCol); } + if (m_eposSet) { drawAgent(m_epos, agentRadius, agentHeight, agentClimb, endCol); } dd.depthMask(true); - - if (!m_navMesh) - { - return; - } + + if (!m_navMesh) { return; } if (m_toolMode == TOOLMODE_PATHFIND_FOLLOW) { duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol); duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_endRef, endCol); - + if (m_npolys) { for (int i = 0; i < m_npolys; ++i) { - if (m_polys[i] == m_startRef || m_polys[i] == m_endRef) - continue; + if (m_polys[i] == m_startRef || m_polys[i] == m_endRef) { continue; } duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_polys[i], pathCol); } } - + if (m_nsmoothPath) { dd.depthMask(false); - const unsigned int spathCol = duRGBA(0,0,0,220); + const unsigned int spathCol = duRGBA(0, 0, 0, 220); dd.begin(DU_DRAW_LINES, 3.0f); for (int i = 0; i < m_nsmoothPath; ++i) - dd.vertex(m_smoothPath[i*3], m_smoothPath[i*3+1]+0.1f, m_smoothPath[i*3+2], spathCol); + { + dd.vertex(m_smoothPath[i * 3], m_smoothPath[i * 3 + 1] + 0.1f, m_smoothPath[i * 3 + 2], spathCol); + } dd.end(); dd.depthMask(true); } - + if (m_pathIterNum) { - duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_pathIterPolys[0], duRGBA(255,255,255,128)); + duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_pathIterPolys[0], duRGBA(255, 255, 255, 128)); dd.depthMask(false); dd.begin(DU_DRAW_LINES, 1.0f); - - const unsigned int prevCol = duRGBA(255,192,0,220); - const unsigned int curCol = duRGBA(255,255,255,220); - const unsigned int steerCol = duRGBA(0,192,255,220); - dd.vertex(m_prevIterPos[0],m_prevIterPos[1]-0.3f,m_prevIterPos[2], prevCol); - dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], prevCol); + const unsigned int prevCol = duRGBA(255, 192, 0, 220); + const unsigned int curCol = duRGBA(255, 255, 255, 220); + const unsigned int steerCol = duRGBA(0, 192, 255, 220); - dd.vertex(m_iterPos[0],m_iterPos[1]-0.3f,m_iterPos[2], curCol); - dd.vertex(m_iterPos[0],m_iterPos[1]+0.3f,m_iterPos[2], curCol); + dd.vertex(m_prevIterPos[0], m_prevIterPos[1] - 0.3f, m_prevIterPos[2], prevCol); + dd.vertex(m_prevIterPos[0], m_prevIterPos[1] + 0.3f, m_prevIterPos[2], prevCol); - dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], prevCol); - dd.vertex(m_iterPos[0],m_iterPos[1]+0.3f,m_iterPos[2], prevCol); + dd.vertex(m_iterPos[0], m_iterPos[1] - 0.3f, m_iterPos[2], curCol); + dd.vertex(m_iterPos[0], m_iterPos[1] + 0.3f, m_iterPos[2], curCol); - dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], steerCol); - dd.vertex(m_steerPos[0],m_steerPos[1]+0.3f,m_steerPos[2], steerCol); - - for (int i = 0; i < m_steerPointCount-1; ++i) + dd.vertex(m_prevIterPos[0], m_prevIterPos[1] + 0.3f, m_prevIterPos[2], prevCol); + dd.vertex(m_iterPos[0], m_iterPos[1] + 0.3f, m_iterPos[2], prevCol); + + dd.vertex(m_prevIterPos[0], m_prevIterPos[1] + 0.3f, m_prevIterPos[2], steerCol); + dd.vertex(m_steerPos[0], m_steerPos[1] + 0.3f, m_steerPos[2], steerCol); + + for (int i = 0; i < m_steerPointCount - 1; ++i) { - dd.vertex(m_steerPoints[i*3+0],m_steerPoints[i*3+1]+0.2f,m_steerPoints[i*3+2], duDarkenCol(steerCol)); - dd.vertex(m_steerPoints[(i+1)*3+0],m_steerPoints[(i+1)*3+1]+0.2f,m_steerPoints[(i+1)*3+2], duDarkenCol(steerCol)); + dd.vertex( + m_steerPoints[i * 3 + 0], + m_steerPoints[i * 3 + 1] + 0.2f, + m_steerPoints[i * 3 + 2], + duDarkenCol(steerCol)); + dd.vertex( + m_steerPoints[(i + 1) * 3 + 0], + m_steerPoints[(i + 1) * 3 + 1] + 0.2f, + m_steerPoints[(i + 1) * 3 + 2], + duDarkenCol(steerCol)); } - + dd.end(); dd.depthMask(true); } } - else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT || - m_toolMode == TOOLMODE_PATHFIND_SLICED) + else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT || m_toolMode == TOOLMODE_PATHFIND_SLICED) { duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol); duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_endRef, endCol); - + if (m_npolys) { for (int i = 0; i < m_npolys; ++i) { - if (m_polys[i] == m_startRef || m_polys[i] == m_endRef) - continue; + if (m_polys[i] == m_startRef || m_polys[i] == m_endRef) { continue; } duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_polys[i], pathCol); } } - + if (m_nstraightPath) { dd.depthMask(false); - const unsigned int spathCol = duRGBA(64,16,0,220); - const unsigned int offMeshCol = duRGBA(128,96,0,220); + const unsigned int spathCol = duRGBA(64, 16, 0, 220); + const unsigned int offMeshCol = duRGBA(128, 96, 0, 220); dd.begin(DU_DRAW_LINES, 2.0f); - for (int i = 0; i < m_nstraightPath-1; ++i) + for (int i = 0; i < m_nstraightPath - 1; ++i) { unsigned int col; if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) + { col = offMeshCol; + } else + { col = spathCol; - - dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], col); - dd.vertex(m_straightPath[(i+1)*3], m_straightPath[(i+1)*3+1]+0.4f, m_straightPath[(i+1)*3+2], col); + } + + dd.vertex( + m_straightPath[i * 3], + m_straightPath[i * 3 + 1] + 0.4f, + m_straightPath[i * 3 + 2], + col); + dd.vertex( + m_straightPath[(i + 1) * 3], + m_straightPath[(i + 1) * 3 + 1] + 0.4f, + m_straightPath[(i + 1) * 3 + 2], + col); } dd.end(); dd.begin(DU_DRAW_POINTS, 6.0f); for (int i = 0; i < m_nstraightPath; ++i) { unsigned int col; - if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START) - col = startCol; - else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_END) - col = endCol; - else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) - col = offMeshCol; - else - col = spathCol; - dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], col); + if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START) { col = startCol; } + else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_END) { col = endCol; } + else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) { col = offMeshCol; } + else { col = spathCol; } + dd.vertex(m_straightPath[i * 3], m_straightPath[i * 3 + 1] + 0.4f, m_straightPath[i * 3 + 2], col); } dd.end(); dd.depthMask(true); @@ -1131,34 +1235,56 @@ void NavMeshTesterTool::handleRender() else if (m_toolMode == TOOLMODE_RAYCAST) { duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol); - + if (m_nstraightPath) { for (int i = 1; i < m_npolys; ++i) - duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_polys[i], pathCol); - - dd.depthMask(false); - const unsigned int spathCol = m_hitResult ? duRGBA(64,16,0,220) : duRGBA(240,240,240,220); - dd.begin(DU_DRAW_LINES, 2.0f); - for (int i = 0; i < m_nstraightPath-1; ++i) { - dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], spathCol); - dd.vertex(m_straightPath[(i+1)*3], m_straightPath[(i+1)*3+1]+0.4f, m_straightPath[(i+1)*3+2], spathCol); + duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_polys[i], pathCol); + } + + dd.depthMask(false); + const unsigned int spathCol = m_hitResult ? duRGBA(64, 16, 0, 220) : duRGBA(240, 240, 240, 220); + dd.begin(DU_DRAW_LINES, 2.0f); + for (int i = 0; i < m_nstraightPath - 1; ++i) + { + dd.vertex( + m_straightPath[i * 3], + m_straightPath[i * 3 + 1] + 0.4f, + m_straightPath[i * 3 + 2], + spathCol); + dd.vertex( + m_straightPath[(i + 1) * 3], + m_straightPath[(i + 1) * 3 + 1] + 0.4f, + m_straightPath[(i + 1) * 3 + 2], + spathCol); } dd.end(); dd.begin(DU_DRAW_POINTS, 4.0f); for (int i = 0; i < m_nstraightPath; ++i) - dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], spathCol); + { + dd.vertex( + m_straightPath[i * 3], + m_straightPath[i * 3 + 1] + 0.4f, + m_straightPath[i * 3 + 2], + spathCol); + } dd.end(); if (m_hitResult) { - const unsigned int hitCol = duRGBA(0,0,0,128); + const unsigned int hitCol = duRGBA(0, 0, 0, 128); dd.begin(DU_DRAW_LINES, 2.0f); - dd.vertex(m_hitPos[0], m_hitPos[1] + 0.4f, m_hitPos[2], hitCol); - dd.vertex(m_hitPos[0] + m_hitNormal[0]*agentRadius, - m_hitPos[1] + 0.4f + m_hitNormal[1]*agentRadius, - m_hitPos[2] + m_hitNormal[2]*agentRadius, hitCol); + dd.vertex( + m_hitPos[0], + m_hitPos[1] + 0.4f, + m_hitPos[2], + hitCol); + dd.vertex( + m_hitPos[0] + m_hitNormal[0] * agentRadius, + m_hitPos[1] + 0.4f + m_hitNormal[1] * agentRadius, + m_hitPos[2] + m_hitNormal[2] * agentRadius, + hitCol); dd.end(); } dd.depthMask(true); @@ -1168,10 +1294,17 @@ void NavMeshTesterTool::handleRender() { duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol); dd.depthMask(false); - duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+agentHeight/2, m_spos[2], m_distanceToWall, duRGBA(64,16,0,220), 2.0f); + duDebugDrawCircle( + &dd, + m_spos[0], + m_spos[1] + agentHeight / 2, + m_spos[2], + m_distanceToWall, + duRGBA(64, 16, 0, 220), + 2.0f); dd.begin(DU_DRAW_LINES, 3.0f); - dd.vertex(m_hitPos[0], m_hitPos[1] + 0.02f, m_hitPos[2], duRGBA(0,0,0,192)); - dd.vertex(m_hitPos[0], m_hitPos[1] + agentHeight, m_hitPos[2], duRGBA(0,0,0,192)); + dd.vertex(m_hitPos[0], m_hitPos[1] + 0.02f, m_hitPos[2], duRGBA(0, 0, 0, 192)); + dd.vertex(m_hitPos[0], m_hitPos[1] + agentHeight, m_hitPos[2], duRGBA(0, 0, 0, 192)); dd.end(); dd.depthMask(true); } @@ -1187,22 +1320,22 @@ void NavMeshTesterTool::handleRender() dd.depthMask(false); getPolyCenter(m_navMesh, m_parent[i], p0); getPolyCenter(m_navMesh, m_polys[i], p1); - duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0,0,0,128), 2.0f); + duDebugDrawArc(&dd, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0, 0, 0, 128), 2.0f); dd.depthMask(true); } dd.depthMask(true); } - + if (m_sposSet && m_eposSet) { dd.depthMask(false); const float dx = m_epos[0] - m_spos[0]; const float dz = m_epos[2] - m_spos[2]; - const float dist = sqrtf(dx*dx + dz*dz); - duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+agentHeight/2, m_spos[2], dist, duRGBA(64,16,0,220), 2.0f); + const float dist = sqrtf(dx * dx + dz * dz); + duDebugDrawCircle(&dd, m_spos[0], m_spos[1] + agentHeight / 2, m_spos[2], dist, duRGBA(64, 16, 0, 220), 2.0f); dd.depthMask(true); } - } + } else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE) { for (int i = 0; i < m_npolys; ++i) @@ -1215,21 +1348,21 @@ void NavMeshTesterTool::handleRender() dd.depthMask(false); getPolyCenter(m_navMesh, m_parent[i], p0); getPolyCenter(m_navMesh, m_polys[i], p1); - duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0,0,0,128), 2.0f); + duDebugDrawArc(&dd, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0, 0, 0, 128), 2.0f); dd.depthMask(true); } dd.depthMask(true); } - + if (m_sposSet && m_eposSet) { dd.depthMask(false); - const unsigned int col = duRGBA(64,16,0,220); + const unsigned int col = duRGBA(64, 16, 0, 220); dd.begin(DU_DRAW_LINES, 2.0f); - for (int i = 0, j = 3; i < 4; j=i++) + for (int i = 0, j = 3; i < 4; j = i++) { - const float* p0 = &m_queryPoly[j*3]; - const float* p1 = &m_queryPoly[i*3]; + const float* p0 = &m_queryPoly[j * 3]; + const float* p1 = &m_queryPoly[i * 3]; dd.vertex(p0, col); dd.vertex(p1, col); } @@ -1249,82 +1382,100 @@ void NavMeshTesterTool::handleRender() dd.depthMask(false); getPolyCenter(m_navMesh, m_parent[i], p0); getPolyCenter(m_navMesh, m_polys[i], p1); - duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0,0,0,128), 2.0f); + duDebugDrawArc(&dd, p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0, 0, 0, 128), 2.0f); dd.depthMask(true); } - static const int MAX_SEGS = DT_VERTS_PER_POLYGON*4; - float segs[MAX_SEGS*6]; + static const int MAX_SEGS = DT_VERTS_PER_POLYGON * 4; + float segs[MAX_SEGS * 6]; dtPolyRef refs[MAX_SEGS]; - memset(refs, 0, sizeof(dtPolyRef)*MAX_SEGS); + memset(refs, 0, sizeof(dtPolyRef) * MAX_SEGS); int nsegs = 0; m_navQuery->getPolyWallSegments(m_polys[i], &m_filter, segs, refs, &nsegs, MAX_SEGS); dd.begin(DU_DRAW_LINES, 2.0f); for (int j = 0; j < nsegs; ++j) { - const float* s = &segs[j*6]; - + const float* s = &segs[j * 6]; + // Skip too distant segments. float tseg; - float distSqr = dtDistancePtSegSqr2D(m_spos, s, s+3, tseg); - if (distSqr > dtSqr(m_neighbourhoodRadius)) - continue; - - float delta[3], norm[3], p0[3], p1[3]; - dtVsub(delta, s+3,s); + float distSqr = dtDistancePtSegSqr2D(m_spos, s, s + 3, tseg); + if (distSqr > dtSqr(m_neighbourhoodRadius)) { continue; } + + float delta[3]; + float norm[3]; + float p0[3]; + float p1[3]; + dtVsub(delta, s + 3, s); dtVmad(p0, s, delta, 0.5f); norm[0] = delta[2]; norm[1] = 0; norm[2] = -delta[0]; dtVnormalize(norm); - dtVmad(p1, p0, norm, agentRadius*0.5f); + dtVmad(p1, p0, norm, agentRadius * 0.5f); // Skip backfacing segments. if (refs[j]) { - unsigned int col = duRGBA(255,255,255,32); - dd.vertex(s[0],s[1]+agentClimb,s[2],col); - dd.vertex(s[3],s[4]+agentClimb,s[5],col); + unsigned int col = duRGBA(255, 255, 255, 32); + dd.vertex(s[0], s[1] + agentClimb, s[2], col); + dd.vertex(s[3], s[4] + agentClimb, s[5], col); } else { - unsigned int col = duRGBA(192,32,16,192); - if (dtTriArea2D(m_spos, s, s+3) < 0.0f) - col = duRGBA(96,32,16,192); - - dd.vertex(p0[0],p0[1]+agentClimb,p0[2],col); - dd.vertex(p1[0],p1[1]+agentClimb,p1[2],col); + unsigned int col = duRGBA(192, 32, 16, 192); + if (dtTriArea2D(m_spos, s, s + 3) < 0.0f) + { + col = duRGBA(96, 32, 16, 192); + } - dd.vertex(s[0],s[1]+agentClimb,s[2],col); - dd.vertex(s[3],s[4]+agentClimb,s[5],col); + dd.vertex(p0[0], p0[1] + agentClimb, p0[2], col); + dd.vertex(p1[0], p1[1] + agentClimb, p1[2], col); + + dd.vertex(s[0], s[1] + agentClimb, s[2], col); + dd.vertex(s[3], s[4] + agentClimb, s[5], col); } } dd.end(); - + dd.depthMask(true); } - + if (m_sposSet) { dd.depthMask(false); - duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+agentHeight/2, m_spos[2], m_neighbourhoodRadius, duRGBA(64,16,0,220), 2.0f); + duDebugDrawCircle( + &dd, + m_spos[0], + m_spos[1] + agentHeight / 2, + m_spos[2], + m_neighbourhoodRadius, + duRGBA(64, 16, 0, 220), + 2.0f); dd.depthMask(true); } } - + if (m_nrandPoints > 0) { dd.begin(DU_DRAW_POINTS, 6.0f); for (int i = 0; i < m_nrandPoints; i++) { - const float* p = &m_randPoints[i*3]; - dd.vertex(p[0],p[1]+0.1f,p[2], duRGBA(220,32,16,192)); - } + const float* p = &m_randPoints[i * 3]; + dd.vertex(p[0], p[1] + 0.1f, p[2], duRGBA(220, 32, 16, 192)); + } dd.end(); - + if (m_randPointsInCircle && m_sposSet) { - duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+agentHeight/2, m_spos[2], m_randomRadius, duRGBA(64,16,0,220), 2.0f); + duDebugDrawCircle( + &dd, + m_spos[0], + m_spos[1] + agentHeight / 2, + m_spos[2], + m_randomRadius, + duRGBA(64, 16, 0, 220), + 2.0f); } } } @@ -1332,44 +1483,47 @@ void NavMeshTesterTool::handleRender() void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* view) { GLdouble x, y, z; - + // Draw start and end point labels - if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2], - model, proj, view, &x, &y, &z)) + if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2], model, proj, view, &x, &y, &z)) { - imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0, 0, 0, 220)); } - if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2], - model, proj, view, &x, &y, &z)) + if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2], model, proj, view, &x, &y, &z)) { - imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0, 0, 0, 220)); } - + // Tool help const int h = view[3]; - imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB+SHIFT: Set start location LMB: Set end location", imguiRGBA(255,255,255,192)); + imguiDrawText( + 280, + h - 40, + IMGUI_ALIGN_LEFT, + "LMB+SHIFT: Set start location LMB: Set end location", + imguiRGBA(255, 255, 255, 192)); } void NavMeshTesterTool::drawAgent(const float* pos, float r, float h, float c, const unsigned int col) { duDebugDraw& dd = m_sample->getDebugDraw(); - + dd.depthMask(false); - - // Agent dimensions. - duDebugDrawCylinderWire(&dd, pos[0]-r, pos[1]+0.02f, pos[2]-r, pos[0]+r, pos[1]+h, pos[2]+r, col, 2.0f); - duDebugDrawCircle(&dd, pos[0],pos[1]+c,pos[2],r,duRGBA(0,0,0,64),1.0f); + // Agent dimensions. + duDebugDrawCylinderWire(&dd, pos[0] - r, pos[1] + 0.02f, pos[2] - r, pos[0] + r, pos[1] + h, pos[2] + r, col, 2.0f); - unsigned int colb = duRGBA(0,0,0,196); + duDebugDrawCircle(&dd, pos[0], pos[1] + c, pos[2], r, duRGBA(0, 0, 0, 64), 1.0f); + + unsigned int colb = duRGBA(0, 0, 0, 196); dd.begin(DU_DRAW_LINES); - dd.vertex(pos[0], pos[1]-c, pos[2], colb); - dd.vertex(pos[0], pos[1]+c, pos[2], colb); - dd.vertex(pos[0]-r/2, pos[1]+0.02f, pos[2], colb); - dd.vertex(pos[0]+r/2, pos[1]+0.02f, pos[2], colb); - dd.vertex(pos[0], pos[1]+0.02f, pos[2]-r/2, colb); - dd.vertex(pos[0], pos[1]+0.02f, pos[2]+r/2, colb); + dd.vertex(pos[0], pos[1] - c, pos[2], colb); + dd.vertex(pos[0], pos[1] + c, pos[2], colb); + dd.vertex(pos[0] - r / 2, pos[1] + 0.02f, pos[2], colb); + dd.vertex(pos[0] + r / 2, pos[1] + 0.02f, pos[2], colb); + dd.vertex(pos[0], pos[1] + 0.02f, pos[2] - r / 2, colb); + dd.vertex(pos[0], pos[1] + 0.02f, pos[2] + r / 2, colb); dd.end(); - + dd.depthMask(true); } diff --git a/RecastDemo/Source/OffMeshConnectionTool.cpp b/RecastDemo/Source/OffMeshConnectionTool.cpp index 99b814c8..af3cb10b 100644 --- a/RecastDemo/Source/OffMeshConnectionTool.cpp +++ b/RecastDemo/Source/OffMeshConnectionTool.cpp @@ -16,45 +16,30 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include "SDL.h" +#include "SDL_opengl.h" + +#include #include #include #include -#include -#include "SDL.h" -#include "SDL_opengl.h" #ifdef __APPLE__ # include #else # include #endif -#include "imgui.h" -#include "OffMeshConnectionTool.h" +#include "DetourDebugDraw.h" #include "InputGeom.h" -#include "Sample.h" +#include "OffMeshConnectionTool.h" #include "Recast.h" #include "RecastDebugDraw.h" -#include "DetourDebugDraw.h" +#include "Sample.h" +#include "imgui.h" #ifdef WIN32 # define snprintf _snprintf #endif -OffMeshConnectionTool::OffMeshConnectionTool() : - m_sample(0), - m_hitPosSet(0), - m_bidir(true), - m_oldFlags(0) -{ -} - -OffMeshConnectionTool::~OffMeshConnectionTool() -{ - if (m_sample) - { - m_sample->setNavMeshDrawFlags(m_oldFlags); - } -} - void OffMeshConnectionTool::init(Sample* sample) { if (m_sample != sample) @@ -73,16 +58,20 @@ void OffMeshConnectionTool::reset() void OffMeshConnectionTool::handleMenu() { if (imguiCheck("One Way", !m_bidir)) + { m_bidir = false; + } if (imguiCheck("Bidirectional", m_bidir)) + { m_bidir = true; + } } void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool shift) { - if (!m_sample) return; + if (!m_sample) { return; } InputGeom* geom = m_sample->getInputGeom(); - if (!geom) return; + if (!geom) { return; } if (shift) { @@ -91,26 +80,25 @@ void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool float nearestDist = FLT_MAX; int nearestIndex = -1; const float* verts = geom->getOffMeshConnectionVerts(); - for (int i = 0; i < geom->getOffMeshConnectionCount()*2; ++i) + for (int i = 0; i < geom->getOffMeshConnectionCount() * 2; ++i) { - const float* v = &verts[i*3]; + const float* v = &verts[i * 3]; float d = rcVdistSqr(p, v); if (d < nearestDist) { nearestDist = d; - nearestIndex = i/2; // Each link has two vertices. + nearestIndex = i / 2; // Each link has two vertices. } } // If end point close enough, delete it. - if (nearestIndex != -1 && - sqrtf(nearestDist) < m_sample->getAgentRadius()) + if (nearestIndex != -1 && sqrtf(nearestDist) < m_sample->getAgentRadius()) { geom->deleteOffMeshConnection(nearestIndex); } } else { - // Create + // Create if (!m_hitPosSet) { rcVcopy(m_hitPos, p); @@ -119,58 +107,58 @@ void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool else { const unsigned char area = SAMPLE_POLYAREA_JUMP; - const unsigned short flags = SAMPLE_POLYFLAGS_JUMP; + const unsigned short flags = SAMPLE_POLYFLAGS_JUMP; geom->addOffMeshConnection(m_hitPos, p, m_sample->getAgentRadius(), m_bidir ? 1 : 0, area, flags); m_hitPosSet = false; } } - } -void OffMeshConnectionTool::handleToggle() -{ -} +void OffMeshConnectionTool::handleToggle() {} -void OffMeshConnectionTool::handleStep() -{ -} +void OffMeshConnectionTool::handleStep() {} -void OffMeshConnectionTool::handleUpdate(const float /*dt*/) -{ -} +void OffMeshConnectionTool::handleUpdate(const float /*dt*/) {} void OffMeshConnectionTool::handleRender() { duDebugDraw& dd = m_sample->getDebugDraw(); const float s = m_sample->getAgentRadius(); - + if (m_hitPosSet) - duDebugDrawCross(&dd, m_hitPos[0],m_hitPos[1]+0.1f,m_hitPos[2], s, duRGBA(0,0,0,128), 2.0f); + { + duDebugDrawCross(&dd, m_hitPos[0], m_hitPos[1] + 0.1f, m_hitPos[2], s, duRGBA(0, 0, 0, 128), 2.0f); + } InputGeom* geom = m_sample->getInputGeom(); if (geom) + { geom->drawOffMeshConnections(&dd, true); + } } void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int* view) { GLdouble x, y, z; - + // Draw start and end point labels - if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2], - model, proj, view, &x, &y, &z)) + if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2], model, proj, view, &x, &y, &z)) { - imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0,0,0,220)); + imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0, 0, 0, 220)); } - + // Tool help const int h = view[3]; if (!m_hitPosSet) { - imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.", imguiRGBA(255,255,255,192)); + imguiDrawText(280, + h - 40, + IMGUI_ALIGN_LEFT, + "LMB: Create new connection. SHIFT+LMB: Delete existing connection, click close to start or end point.", + imguiRGBA(255, 255, 255, 192)); } else { - imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Set connection end point and finish.", imguiRGBA(255,255,255,192)); + imguiDrawText(280, h - 40, IMGUI_ALIGN_LEFT, "LMB: Set connection end point and finish.", imguiRGBA(255, 255, 255, 192)); } } diff --git a/RecastDemo/Source/PerfTimer.cpp b/RecastDemo/Source/PerfTimer.cpp index a8c86bd2..480ef23e 100644 --- a/RecastDemo/Source/PerfTimer.cpp +++ b/RecastDemo/Source/PerfTimer.cpp @@ -21,7 +21,7 @@ #if defined(WIN32) // Win32 -#include +# include TimeVal getPerfTime() { @@ -33,27 +33,21 @@ TimeVal getPerfTime() int getPerfTimeUsec(const TimeVal duration) { static __int64 freq = 0; - if (freq == 0) - QueryPerformanceFrequency((LARGE_INTEGER*)&freq); - return (int)(duration*1000000 / freq); + if (freq == 0) { QueryPerformanceFrequency((LARGE_INTEGER*)&freq); } + return (int)(duration * 1000000 / freq); } -#else +#else // Linux, BSD, OSX -// Linux, BSD, OSX - -#include +# include TimeVal getPerfTime() { timeval now; gettimeofday(&now, 0); - return (TimeVal)now.tv_sec*1000000L + (TimeVal)now.tv_usec; + return (TimeVal)now.tv_sec * 1000000L + (TimeVal)now.tv_usec; } -int getPerfTimeUsec(const TimeVal duration) -{ - return (int)duration; -} +int getPerfTimeUsec(const TimeVal duration) { return (int)duration; } #endif diff --git a/RecastDemo/Source/SampleInterfaces.cpp b/RecastDemo/Source/SampleInterfaces.cpp index 24f6ea12..7836236a 100644 --- a/RecastDemo/Source/SampleInterfaces.cpp +++ b/RecastDemo/Source/SampleInterfaces.cpp @@ -1,30 +1,28 @@ -#include -#include -#include #include "SampleInterfaces.h" -#include "Recast.h" -#include "RecastDebugDraw.h" + #include "DetourDebugDraw.h" #include "PerfTimer.h" +#include "Recast.h" +#include "RecastDebugDraw.h" #include "SDL.h" #include "SDL_opengl.h" +#include +#include +#include + #ifdef WIN32 # define snprintf _snprintf #endif //////////////////////////////////////////////////////////////////////////////////////////////////// -BuildContext::BuildContext() : - m_messageCount(0), - m_textPoolSize(0) +BuildContext::BuildContext() { memset(m_messages, 0, sizeof(char*) * MAX_MESSAGES); - resetTimers(); } -// Virtual functions for custom implementations. void BuildContext::doResetLog() { m_messageCount = 0; @@ -33,30 +31,27 @@ void BuildContext::doResetLog() void BuildContext::doLog(const rcLogCategory category, const char* msg, const int len) { - if (!len) return; - if (m_messageCount >= MAX_MESSAGES) - return; + if (!len) { return; } + if (m_messageCount >= MAX_MESSAGES) { return; } char* dst = &m_textPool[m_textPoolSize]; int n = TEXT_POOL_SIZE - m_textPoolSize; - if (n < 2) - return; + if (n < 2) { return; } char* cat = dst; - char* text = dst+1; - const int maxtext = n-1; + char* text = dst + 1; + const int maxtext = n - 1; // Store category *cat = (char)category; // Store message - const int count = rcMin(len+1, maxtext); + const int count = rcMin(len + 1, maxtext); memcpy(text, msg, count); - text[count-1] = '\0'; + text[count - 1] = '\0'; m_textPoolSize += 1 + count; m_messages[m_messageCount++] = dst; } void BuildContext::doResetTimers() { - for (int i = 0; i < RC_MAX_TIMERS; ++i) - m_accTime[i] = -1; + for (int i = 0; i < RC_MAX_TIMERS; ++i) { m_accTime[i] = -1; } } void BuildContext::doStartTimer(const rcTimerLabel label) @@ -68,10 +63,8 @@ void BuildContext::doStopTimer(const rcTimerLabel label) { const TimeVal endTime = getPerfTime(); const TimeVal deltaTime = endTime - m_startTime[label]; - if (m_accTime[label] == -1) - m_accTime[label] = deltaTime; - else - m_accTime[label] += deltaTime; + if (m_accTime[label] == -1) { m_accTime[label] = deltaTime; } + else { m_accTime[label] += deltaTime; } } int BuildContext::doGetAccumulatedTime(const rcTimerLabel label) const @@ -87,12 +80,12 @@ void BuildContext::dumpLog(const char* format, ...) vprintf(format, ap); va_end(ap); printf("\n"); - + // Print messages - const int TAB_STOPS[4] = { 28, 36, 44, 52 }; + const int TAB_STOPS[4] = {28, 36, 44, 52}; for (int i = 0; i < m_messageCount; ++i) { - const char* msg = m_messages[i]+1; + const char* msg = m_messages[i] + 1; int n = 0; while (*msg) { @@ -131,34 +124,37 @@ int BuildContext::getLogCount() const const char* BuildContext::getLogText(const int i) const { - return m_messages[i]+1; + return m_messages[i] + 1; } //////////////////////////////////////////////////////////////////////////////////////////////////// class GLCheckerTexture { - unsigned int m_texId; + unsigned int m_texId = 0; + public: - GLCheckerTexture() : m_texId(0) - { - } - ~GLCheckerTexture() { - if (m_texId != 0) + if (m_texId != 0) { glDeleteTextures(1, &m_texId); + } } + void bind() { - if (m_texId == 0) + if (m_texId != 0) + { + glBindTexture(GL_TEXTURE_2D, m_texId); + } + else { // Create checker pattern. - const unsigned int col0 = duRGBA(215,215,215,255); - const unsigned int col1 = duRGBA(255,255,255,255); + const unsigned int col0 = duRGBA(215, 215, 215, 255); + const unsigned int col1 = duRGBA(255, 255, 255, 255); static const int TSIZE = 64; - unsigned int data[TSIZE*TSIZE]; - + unsigned int data[TSIZE * TSIZE]; + glGenTextures(1, &m_texId); glBindTexture(GL_TEXTURE_2D, m_texId); @@ -167,25 +163,24 @@ public: while (size > 0) { for (int y = 0; y < size; ++y) + { for (int x = 0; x < size; ++x) - data[x+y*size] = (x==0 || y==0) ? col0 : col1; - glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size,size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + { + data[x + y * size] = (x == 0 || y == 0) ? col0 : col1; + } + } + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); size /= 2; level++; } - + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } - else - { - glBindTexture(GL_TEXTURE_2D, m_texId); - } } }; static GLCheckerTexture g_tex; - void DebugDrawGL::depthMask(bool state) { glDepthMask(state ? GL_TRUE : GL_FALSE); @@ -208,20 +203,16 @@ void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size) { switch (prim) { - case DU_DRAW_POINTS: - glPointSize(size); - glBegin(GL_POINTS); - break; - case DU_DRAW_LINES: - glLineWidth(size); - glBegin(GL_LINES); - break; - case DU_DRAW_TRIS: - glBegin(GL_TRIANGLES); - break; - case DU_DRAW_QUADS: - glBegin(GL_QUADS); - break; + case DU_DRAW_POINTS: + glPointSize(size); + glBegin(GL_POINTS); + break; + case DU_DRAW_LINES: + glLineWidth(size); + glBegin(GL_LINES); + break; + case DU_DRAW_TRIS: glBegin(GL_TRIANGLES); break; + case DU_DRAW_QUADS: glBegin(GL_QUADS); break; }; } @@ -234,7 +225,7 @@ void DebugDrawGL::vertex(const float* pos, unsigned int color) void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color) { glColor4ubv((GLubyte*)&color); - glVertex3f(x,y,z); + glVertex3f(x, y, z); } void DebugDrawGL::vertex(const float* pos, unsigned int color, const float* uv) @@ -247,8 +238,8 @@ void DebugDrawGL::vertex(const float* pos, unsigned int color, const float* uv) void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v) { glColor4ubv((GLubyte*)&color); - glTexCoord2f(u,v); - glVertex3f(x,y,z); + glTexCoord2f(u, v); + glVertex3f(x, y, z); } void DebugDrawGL::end() @@ -260,31 +251,28 @@ void DebugDrawGL::end() //////////////////////////////////////////////////////////////////////////////////////////////////// -FileIO::FileIO() : - m_fp(0), - m_mode(-1) -{ -} - FileIO::~FileIO() { - if (m_fp) fclose(m_fp); + if (m_fp) + { + fclose(m_fp); + } } bool FileIO::openForWrite(const char* path) { - if (m_fp) return false; + if (m_fp) { return false; } m_fp = fopen(path, "wb"); - if (!m_fp) return false; + if (!m_fp) { return false; } m_mode = 1; return true; } bool FileIO::openForRead(const char* path) { - if (m_fp) return false; + if (m_fp) { return false; } m_fp = fopen(path, "rb"); - if (!m_fp) return false; + if (!m_fp) { return false; } m_mode = 2; return true; } @@ -301,16 +289,14 @@ bool FileIO::isReading() const bool FileIO::write(const void* ptr, const size_t size) { - if (!m_fp || m_mode != 1) return false; + if (!m_fp || m_mode != 1) { return false; } fwrite(ptr, size, 1, m_fp); return true; } bool FileIO::read(void* ptr, const size_t size) { - if (!m_fp || m_mode != 2) return false; + if (!m_fp || m_mode != 2) { return false; } size_t readLen = fread(ptr, size, 1, m_fp); return readLen == 1; } - - diff --git a/RecastDemo/Source/TestCase.cpp b/RecastDemo/Source/TestCase.cpp index 5ce42623..cb70c864 100644 --- a/RecastDemo/Source/TestCase.cpp +++ b/RecastDemo/Source/TestCase.cpp @@ -16,33 +16,30 @@ // 3. This notice may not be removed or altered from any source distribution. // -#include -#include -#include -#include #include "TestCase.h" + +#include "DetourCommon.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" -#include "DetourCommon.h" #include "SDL.h" #include "SDL_opengl.h" + +#include +#include +#include +#include #ifdef __APPLE__ # include #else # include #endif -#include "imgui.h" #include "PerfTimer.h" +#include "imgui.h" #ifdef WIN32 -#define snprintf _snprintf +# define snprintf _snprintf #endif -TestCase::TestCase() : - m_tests(0) -{ -} - TestCase::~TestCase() { Test* iter = m_tests; @@ -54,7 +51,6 @@ TestCase::~TestCase() } } - static char* parseRow(char* buf, char* bufEnd, char* row, int len) { bool start = true; @@ -67,22 +63,20 @@ static char* parseRow(char* buf, char* bufEnd, char* row, int len) // multirow switch (c) { - case '\n': - if (start) break; - done = true; - break; - case '\r': - break; - case '\t': - case ' ': - if (start) break; - // else falls through - default: - start = false; - row[n++] = c; - if (n >= len-1) - done = true; - break; + case '\n': + if (start) { break; } + done = true; + break; + case '\r': break; + case '\t': + case ' ': + if (start) { break; } + // else falls through + default: + start = false; + row[n++] = c; + if (n >= len - 1) { done = true; } + break; } } row[n] = '\0'; @@ -93,7 +87,9 @@ static void copyName(std::string& dst, const char* src) { // Skip white spaces while (*src && isspace(*src)) + { src++; + } dst = src; } @@ -102,7 +98,9 @@ bool TestCase::load(const std::string& filePath) char* buf = 0; FILE* fp = fopen(filePath.c_str(), "rb"); if (!fp) + { return false; + } if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); @@ -140,16 +138,16 @@ bool TestCase::load(const std::string& filePath) { // Parse one row row[0] = '\0'; - src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char)); + src = parseRow(src, srcEnd, row, sizeof(row) / sizeof(char)); if (row[0] == 's') { // Sample name. - copyName(m_sampleName, row+1); + copyName(m_sampleName, row + 1); } else if (row[0] == 'f') { // File name. - copyName(m_geomFileName, row+1); + copyName(m_geomFileName, row + 1); } else if (row[0] == 'p' && row[1] == 'f') { @@ -159,10 +157,16 @@ bool TestCase::load(const std::string& filePath) test->expand = false; test->next = m_tests; m_tests = test; - sscanf(row+2, "%f %f %f %f %f %f %hx %hx", - &test->spos[0], &test->spos[1], &test->spos[2], - &test->epos[0], &test->epos[1], &test->epos[2], - &test->includeFlags, &test->excludeFlags); + sscanf(row + 2, + "%f %f %f %f %f %f %hx %hx", + &test->spos[0], + &test->spos[1], + &test->spos[2], + &test->epos[0], + &test->epos[1], + &test->epos[2], + &test->includeFlags, + &test->excludeFlags); } else if (row[0] == 'r' && row[1] == 'c') { @@ -172,18 +176,23 @@ bool TestCase::load(const std::string& filePath) test->expand = false; test->next = m_tests; m_tests = test; - sscanf(row+2, "%f %f %f %f %f %f %hx %hx", - &test->spos[0], &test->spos[1], &test->spos[2], - &test->epos[0], &test->epos[1], &test->epos[2], - &test->includeFlags, &test->excludeFlags); + sscanf(row + 2, + "%f %f %f %f %f %f %hx %hx", + &test->spos[0], + &test->spos[1], + &test->spos[2], + &test->epos[0], + &test->epos[1], + &test->epos[2], + &test->includeFlags, + &test->excludeFlags); } } - - delete [] buf; + delete[] buf; return true; } - + void TestCase::resetTimes() { for (Test* iter = m_tests; iter; iter = iter->next) @@ -196,32 +205,31 @@ void TestCase::resetTimes() void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery) { - if (!navmesh || !navquery) - return; - + if (!navmesh || !navquery) { return; } + resetTimes(); - + static const int MAX_POLYS = 256; dtPolyRef polys[MAX_POLYS]; - float straight[MAX_POLYS*3]; - const float polyPickExt[3] = {2,4,2}; - + float straight[MAX_POLYS * 3]; + const float polyPickExt[3] = {2, 4, 2}; + for (Test* iter = m_tests; iter; iter = iter->next) { - delete [] iter->polys; + delete[] iter->polys; iter->polys = 0; iter->npolys = 0; - delete [] iter->straight; + delete[] iter->straight; iter->straight = 0; iter->nstraight = 0; - + dtQueryFilter filter; filter.setIncludeFlags(iter->includeFlags); filter.setExcludeFlags(iter->excludeFlags); - + // Find start points TimeVal findNearestPolyStart = getPerfTime(); - + dtPolyRef startRef, endRef; navquery->findNearestPoly(iter->spos, polyPickExt, &filter, &startRef, iter->nspos); navquery->findNearestPoly(iter->epos, polyPickExt, &filter, &endRef, iter->nepos); @@ -229,56 +237,55 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery) TimeVal findNearestPolyEnd = getPerfTime(); iter->findNearestPolyTime += getPerfTimeUsec(findNearestPolyEnd - findNearestPolyStart); - if (!startRef || ! endRef) - continue; - + if (!startRef || !endRef) { continue; } + if (iter->type == TEST_PATHFIND) { // Find path TimeVal findPathStart = getPerfTime(); navquery->findPath(startRef, endRef, iter->spos, iter->epos, &filter, polys, &iter->npolys, MAX_POLYS); - + TimeVal findPathEnd = getPerfTime(); iter->findPathTime += getPerfTimeUsec(findPathEnd - findPathStart); - + // Find straight path if (iter->npolys) { TimeVal findStraightPathStart = getPerfTime(); - - navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys, - straight, 0, 0, &iter->nstraight, MAX_POLYS); + + navquery->findStraightPath( + iter->spos, iter->epos, polys, iter->npolys, straight, 0, 0, &iter->nstraight, MAX_POLYS); TimeVal findStraightPathEnd = getPerfTime(); iter->findStraightPathTime += getPerfTimeUsec(findStraightPathEnd - findStraightPathStart); } - + // Copy results if (iter->npolys) { iter->polys = new dtPolyRef[iter->npolys]; - memcpy(iter->polys, polys, sizeof(dtPolyRef)*iter->npolys); + memcpy(iter->polys, polys, sizeof(dtPolyRef) * iter->npolys); } if (iter->nstraight) { - iter->straight = new float[iter->nstraight*3]; - memcpy(iter->straight, straight, sizeof(float)*3*iter->nstraight); + iter->straight = new float[iter->nstraight * 3]; + memcpy(iter->straight, straight, sizeof(float) * 3 * iter->nstraight); } } else if (iter->type == TEST_RAYCAST) { float t = 0; float hitNormal[3], hitPos[3]; - - iter->straight = new float[2*3]; + + iter->straight = new float[2 * 3]; iter->nstraight = 2; - + iter->straight[0] = iter->spos[0]; iter->straight[1] = iter->spos[1]; iter->straight[2] = iter->spos[2]; - + TimeVal findPathStart = getPerfTime(); - + navquery->raycast(startRef, iter->spos, iter->epos, &filter, &t, hitNormal, polys, &iter->npolys, MAX_POLYS); TimeVal findPathEnd = getPerfTime(); @@ -298,7 +305,7 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery) if (iter->npolys > 0) { float h = 0; - navquery->getPolyHeight(polys[iter->npolys-1], hitPos, &h); + navquery->getPolyHeight(polys[iter->npolys - 1], hitPos, &h); hitPos[1] = h; } dtVcopy(&iter->straight[3], hitPos); @@ -306,21 +313,20 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery) if (iter->npolys) { iter->polys = new dtPolyRef[iter->npolys]; - memcpy(iter->polys, polys, sizeof(dtPolyRef)*iter->npolys); + memcpy(iter->polys, polys, sizeof(dtPolyRef) * iter->npolys); } } } - printf("Test Results:\n"); int n = 0; for (Test* iter = m_tests; iter; iter = iter->next) { const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime; - printf(" - Path %02d: %.4f ms\n", n, (float)total/1000.0f); - printf(" - poly: %.4f ms\n", (float)iter->findNearestPolyTime/1000.0f); - printf(" - path: %.4f ms\n", (float)iter->findPathTime/1000.0f); - printf(" - straight: %.4f ms\n", (float)iter->findStraightPathTime/1000.0f); + printf(" - Path %02d: %.4f ms\n", n, (float)total / 1000.0f); + printf(" - poly: %.4f ms\n", (float)iter->findNearestPolyTime / 1000.0f); + printf(" - path: %.4f ms\n", (float)iter->findPathTime / 1000.0f); + printf(" - straight: %.4f ms\n", (float)iter->findStraightPathTime / 1000.0f); n++; } } @@ -334,50 +340,48 @@ void TestCase::handleRender() float dir[3]; dtVsub(dir, iter->epos, iter->spos); dtVnormalize(dir); - glColor4ub(128,25,0,192); - glVertex3f(iter->spos[0],iter->spos[1]-0.3f,iter->spos[2]); - glVertex3f(iter->spos[0],iter->spos[1]+0.3f,iter->spos[2]); - glVertex3f(iter->spos[0],iter->spos[1]+0.3f,iter->spos[2]); - glVertex3f(iter->spos[0]+dir[0]*0.3f,iter->spos[1]+0.3f+dir[1]*0.3f,iter->spos[2]+dir[2]*0.3f); - glColor4ub(51,102,0,129); - glVertex3f(iter->epos[0],iter->epos[1]-0.3f,iter->epos[2]); - glVertex3f(iter->epos[0],iter->epos[1]+0.3f,iter->epos[2]); + glColor4ub(128, 25, 0, 192); + glVertex3f(iter->spos[0], iter->spos[1] - 0.3f, iter->spos[2]); + glVertex3f(iter->spos[0], iter->spos[1] + 0.3f, iter->spos[2]); + glVertex3f(iter->spos[0], iter->spos[1] + 0.3f, iter->spos[2]); + glVertex3f(iter->spos[0] + dir[0] * 0.3f, iter->spos[1] + 0.3f + dir[1] * 0.3f, iter->spos[2] + dir[2] * 0.3f); + glColor4ub(51, 102, 0, 129); + glVertex3f(iter->epos[0], iter->epos[1] - 0.3f, iter->epos[2]); + glVertex3f(iter->epos[0], iter->epos[1] + 0.3f, iter->epos[2]); if (iter->expand) { const float s = 0.1f; - glColor4ub(255,32,0,128); - glVertex3f(iter->spos[0]-s,iter->spos[1],iter->spos[2]); - glVertex3f(iter->spos[0]+s,iter->spos[1],iter->spos[2]); - glVertex3f(iter->spos[0],iter->spos[1],iter->spos[2]-s); - glVertex3f(iter->spos[0],iter->spos[1],iter->spos[2]+s); - glColor4ub(255,192,0,255); - glVertex3f(iter->nspos[0]-s,iter->nspos[1],iter->nspos[2]); - glVertex3f(iter->nspos[0]+s,iter->nspos[1],iter->nspos[2]); - glVertex3f(iter->nspos[0],iter->nspos[1],iter->nspos[2]-s); - glVertex3f(iter->nspos[0],iter->nspos[1],iter->nspos[2]+s); - - glColor4ub(255,32,0,128); - glVertex3f(iter->epos[0]-s,iter->epos[1],iter->epos[2]); - glVertex3f(iter->epos[0]+s,iter->epos[1],iter->epos[2]); - glVertex3f(iter->epos[0],iter->epos[1],iter->epos[2]-s); - glVertex3f(iter->epos[0],iter->epos[1],iter->epos[2]+s); - glColor4ub(255,192,0,255); - glVertex3f(iter->nepos[0]-s,iter->nepos[1],iter->nepos[2]); - glVertex3f(iter->nepos[0]+s,iter->nepos[1],iter->nepos[2]); - glVertex3f(iter->nepos[0],iter->nepos[1],iter->nepos[2]-s); - glVertex3f(iter->nepos[0],iter->nepos[1],iter->nepos[2]+s); + glColor4ub(255, 32, 0, 128); + glVertex3f(iter->spos[0] - s, iter->spos[1], iter->spos[2]); + glVertex3f(iter->spos[0] + s, iter->spos[1], iter->spos[2]); + glVertex3f(iter->spos[0], iter->spos[1], iter->spos[2] - s); + glVertex3f(iter->spos[0], iter->spos[1], iter->spos[2] + s); + glColor4ub(255, 192, 0, 255); + glVertex3f(iter->nspos[0] - s, iter->nspos[1], iter->nspos[2]); + glVertex3f(iter->nspos[0] + s, iter->nspos[1], iter->nspos[2]); + glVertex3f(iter->nspos[0], iter->nspos[1], iter->nspos[2] - s); + glVertex3f(iter->nspos[0], iter->nspos[1], iter->nspos[2] + s); + + glColor4ub(255, 32, 0, 128); + glVertex3f(iter->epos[0] - s, iter->epos[1], iter->epos[2]); + glVertex3f(iter->epos[0] + s, iter->epos[1], iter->epos[2]); + glVertex3f(iter->epos[0], iter->epos[1], iter->epos[2] - s); + glVertex3f(iter->epos[0], iter->epos[1], iter->epos[2] + s); + glColor4ub(255, 192, 0, 255); + glVertex3f(iter->nepos[0] - s, iter->nepos[1], iter->nepos[2]); + glVertex3f(iter->nepos[0] + s, iter->nepos[1], iter->nepos[2]); + glVertex3f(iter->nepos[0], iter->nepos[1], iter->nepos[2] - s); + glVertex3f(iter->nepos[0], iter->nepos[1], iter->nepos[2] + s); } - - if (iter->expand) - glColor4ub(255,192,0,255); - else - glColor4ub(0,0,0,64); - - for (int i = 0; i < iter->nstraight-1; ++i) + + if (iter->expand) { glColor4ub(255, 192, 0, 255); } + else { glColor4ub(0, 0, 0, 64); } + + for (int i = 0; i < iter->nstraight - 1; ++i) { - glVertex3f(iter->straight[i*3+0],iter->straight[i*3+1]+0.3f,iter->straight[i*3+2]); - glVertex3f(iter->straight[(i+1)*3+0],iter->straight[(i+1)*3+1]+0.3f,iter->straight[(i+1)*3+2]); + glVertex3f(iter->straight[i * 3 + 0], iter->straight[i * 3 + 1] + 0.3f, iter->straight[i * 3 + 2]); + glVertex3f(iter->straight[(i + 1) * 3 + 0], iter->straight[(i + 1) * 3 + 1] + 0.3f, iter->straight[(i + 1) * 3 + 2]); } } glEnd(); @@ -387,14 +391,16 @@ void TestCase::handleRender() bool TestCase::handleRenderOverlay(double* proj, double* model, int* view) { GLdouble x, y, z; - char text[64], subtext[64]; + char text[64]; + char subtext[64]; int n = 0; - static const float LABEL_DIST = 1.0f; + static constexpr float LABEL_DIST = 1.0f; for (Test* iter = m_tests; iter; iter = iter->next) { - float pt[3], dir[3]; + float pt[3]; + float dir[3]; if (iter->nstraight) { dtVcopy(pt, &iter->straight[3]); @@ -404,59 +410,60 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view) dtVnormalize(dir); dtVmad(pt, iter->spos, dir, LABEL_DIST); } - pt[1]+=0.5f; + pt[1] += 0.5f; } else { dtVsub(dir, iter->epos, iter->spos); dtVnormalize(dir); dtVmad(pt, iter->spos, dir, LABEL_DIST); - pt[1]+=0.5f; + pt[1] += 0.5f; } - - if (gluProject((GLdouble)pt[0], (GLdouble)pt[1], (GLdouble)pt[2], - model, proj, view, &x, &y, &z)) + + if (gluProject((GLdouble)pt[0], (GLdouble)pt[1], (GLdouble)pt[2], model, proj, view, &x, &y, &z)) { snprintf(text, 64, "Path %d\n", n); - unsigned int col = imguiRGBA(0,0,0,128); + unsigned int col = imguiRGBA(0, 0, 0, 128); if (iter->expand) - col = imguiRGBA(255,192,0,220); - imguiDrawText((int)x, (int)(y-25), IMGUI_ALIGN_CENTER, text, col); + { + col = imguiRGBA(255, 192, 0, 220); + } + imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, text, col); } n++; } - + static int resScroll = 0; bool mouseOverMenu = imguiBeginScrollArea("Test Results", 10, view[3] - 10 - 350, 200, 350, &resScroll); -// mouseOverMenu = true; - + n = 0; - for (Test* iter = m_tests; iter; iter = iter->next) + for (Test* iter = m_tests; iter; iter = iter->next, n++) { const int total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime; - snprintf(subtext, 64, "%.4f ms", (float)total/1000.0f); + snprintf(subtext, 64, "%.4f ms", (float)total / 1000.0f); snprintf(text, 64, "Path %d", n); - + if (imguiCollapse(text, subtext, iter->expand)) + { iter->expand = !iter->expand; + } + if (iter->expand) { - snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime/1000.0f); + snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime / 1000.0f); imguiValue(text); - snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime/1000.0f); + snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime / 1000.0f); imguiValue(text); - snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime/1000.0f); + snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime / 1000.0f); imguiValue(text); - + imguiSeparator(); } - - n++; } imguiEndScrollArea(); - + return mouseOverMenu; } diff --git a/RecastDemo/Source/imgui.cpp b/RecastDemo/Source/imgui.cpp index 84022012..d86e0d37 100644 --- a/RecastDemo/Source/imgui.cpp +++ b/RecastDemo/Source/imgui.cpp @@ -16,10 +16,11 @@ // 3. This notice may not be removed or altered from any source distribution. // +#include "imgui.h" + +#include #include #include -#include -#include "imgui.h" #ifdef WIN32 # define snprintf _snprintf @@ -32,10 +33,9 @@ static char g_textPool[TEXT_POOL_SIZE]; static unsigned g_textPoolSize = 0; static const char* allocText(const char* text) { - unsigned len = static_cast(strlen(text)+1); - if (g_textPoolSize + len >= TEXT_POOL_SIZE) - return 0; - char* dst = &g_textPool[g_textPoolSize]; + unsigned len = static_cast(strlen(text) + 1); + if (g_textPoolSize + len >= TEXT_POOL_SIZE) { return 0; } + char* dst = &g_textPool[g_textPoolSize]; memcpy(dst, text, len); g_textPoolSize += len; return dst; @@ -53,8 +53,7 @@ static void resetGfxCmdQueue() static void addGfxCmdScissor(int x, int y, int w, int h) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_SCISSOR; cmd.flags = x < 0 ? 0 : 1; // on/off flag. @@ -67,67 +66,62 @@ static void addGfxCmdScissor(int x, int y, int w, int h) static void addGfxCmdRect(float x, float y, float w, float h, unsigned int color) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_RECT; cmd.flags = 0; cmd.col = color; - cmd.rect.x = (short)(x*8.0f); - cmd.rect.y = (short)(y*8.0f); - cmd.rect.w = (short)(w*8.0f); - cmd.rect.h = (short)(h*8.0f); + cmd.rect.x = (short)(x * 8.0f); + cmd.rect.y = (short)(y * 8.0f); + cmd.rect.w = (short)(w * 8.0f); + cmd.rect.h = (short)(h * 8.0f); cmd.rect.r = 0; } static void addGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_LINE; cmd.flags = 0; cmd.col = color; - cmd.line.x0 = (short)(x0*8.0f); - cmd.line.y0 = (short)(y0*8.0f); - cmd.line.x1 = (short)(x1*8.0f); - cmd.line.y1 = (short)(y1*8.0f); - cmd.line.r = (short)(r*8.0f); + cmd.line.x0 = (short)(x0 * 8.0f); + cmd.line.y0 = (short)(y0 * 8.0f); + cmd.line.x1 = (short)(x1 * 8.0f); + cmd.line.y1 = (short)(y1 * 8.0f); + cmd.line.r = (short)(r * 8.0f); } static void addGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_RECT; cmd.flags = 0; cmd.col = color; - cmd.rect.x = (short)(x*8.0f); - cmd.rect.y = (short)(y*8.0f); - cmd.rect.w = (short)(w*8.0f); - cmd.rect.h = (short)(h*8.0f); - cmd.rect.r = (short)(r*8.0f); + cmd.rect.x = (short)(x * 8.0f); + cmd.rect.y = (short)(y * 8.0f); + cmd.rect.w = (short)(w * 8.0f); + cmd.rect.h = (short)(h * 8.0f); + cmd.rect.r = (short)(r * 8.0f); } static void addGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_TRIANGLE; cmd.flags = (char)flags; cmd.col = color; - cmd.rect.x = (short)(x*8.0f); - cmd.rect.y = (short)(y*8.0f); - cmd.rect.w = (short)(w*8.0f); - cmd.rect.h = (short)(h*8.0f); + cmd.rect.x = (short)(x * 8.0f); + cmd.rect.y = (short)(y * 8.0f); + cmd.rect.w = (short)(w * 8.0f); + cmd.rect.h = (short)(h * 8.0f); } static void addGfxCmdText(int x, int y, int align, const char* text, unsigned int color) { - if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) - return; + if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE) { return; } imguiGfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++]; cmd.type = IMGUI_GFXCMD_TEXT; cmd.flags = 0; @@ -141,18 +135,34 @@ static void addGfxCmdText(int x, int y, int align, const char* text, unsigned in ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// struct GuiState { - GuiState() : - left(false), leftPressed(false), leftReleased(false), - mx(-1), my(-1), scroll(0), - active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false), - dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100), - insideCurrentScroll(false), areaId(0), widgetId(0) + GuiState() + : left(false) + , leftPressed(false) + , leftReleased(false) + , mx(-1) + , my(-1) + , scroll(0) + , active(0) + , hot(0) + , hotToBe(0) + , isHot(false) + , isActive(false) + , wentActive(false) + , dragX(0) + , dragY(0) + , dragOrig(0) + , widgetX(0) + , widgetY(0) + , widgetW(100) + , insideCurrentScroll(false) + , areaId(0) + , widgetId(0) { } bool left; bool leftPressed, leftReleased; - int mx,my; + int mx, my; int scroll; unsigned int active; unsigned int hot; @@ -164,7 +174,7 @@ struct GuiState float dragOrig; int widgetX, widgetY, widgetW; bool insideCurrentScroll; - + unsigned int areaId; unsigned int widgetId; }; @@ -188,7 +198,11 @@ inline bool isHot(unsigned int id) inline bool inRect(int x, int y, int w, int h, bool checkScroll = true) { - return (!checkScroll || g_state.insideCurrentScroll) && g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h; + return (!checkScroll || g_state.insideCurrentScroll) + && g_state.mx >= x + && g_state.mx <= x + w + && g_state.my >= y + && g_state.my <= y + h; } inline void clearInput() @@ -213,10 +227,9 @@ inline void setActive(unsigned int id) inline void setHot(unsigned int id) { - g_state.hotToBe = id; + g_state.hotToBe = id; } - static bool buttonLogic(unsigned int id, bool over) { bool res = false; @@ -224,9 +237,13 @@ static bool buttonLogic(unsigned int id, bool over) if (!anyActive()) { if (over) + { setHot(id); + } if (isHot(id) && g_state.leftPressed) + { setActive(id); + } } // if button is active, then react on left up @@ -234,17 +251,23 @@ static bool buttonLogic(unsigned int id, bool over) { g_state.isActive = true; if (over) + { setHot(id); + } if (g_state.leftReleased) { if (isHot(id)) + { res = true; + } clearActive(); } } if (isHot(id)) + { g_state.isHot = true; + } return res; } @@ -264,7 +287,7 @@ static void updateInput(int mx, int my, unsigned char mbut, int scroll) void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll) { - updateInput(mx,my,mbut,scroll); + updateInput(mx, my, mbut, scroll); g_state.hot = g_state.hotToBe; g_state.hotToBe = 0; @@ -298,7 +321,6 @@ int imguiGetRenderQueueSize() return g_gfxCmdQueueSize; } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static const int BUTTON_HEIGHT = 20; static const int SLIDER_HEIGHT = 20; @@ -324,29 +346,44 @@ bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scr { g_state.areaId++; g_state.widgetId = 0; - g_scrollId = (g_state.areaId<<16) | g_state.widgetId; + g_scrollId = (g_state.areaId << 16) | g_state.widgetId; g_state.widgetX = x + SCROLL_AREA_PADDING; - g_state.widgetY = y+h-AREA_HEADER + (*scroll); - g_state.widgetW = w - SCROLL_AREA_PADDING*4; - g_scrollTop = y-AREA_HEADER+h; - g_scrollBottom = y+SCROLL_AREA_PADDING; - g_scrollRight = x+w - SCROLL_AREA_PADDING*3; + g_state.widgetY = y + h - AREA_HEADER + (*scroll); + g_state.widgetW = w - SCROLL_AREA_PADDING * 4; + g_scrollTop = y - AREA_HEADER + h; + g_scrollBottom = y + SCROLL_AREA_PADDING; + g_scrollRight = x + w - SCROLL_AREA_PADDING * 3; g_scrollVal = scroll; g_scrollAreaTop = g_state.widgetY; - g_focusTop = y-AREA_HEADER; - g_focusBottom = y-AREA_HEADER+h; + g_focusTop = y - AREA_HEADER; + g_focusBottom = y - AREA_HEADER + h; g_insideScrollArea = inRect(x, y, w, h, false); g_state.insideCurrentScroll = g_insideScrollArea; - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, imguiRGBA(0,0,0,192)); + addGfxCmdRoundedRect( + (float)x, + (float)y, + (float)w, + (float)h, + 6, + imguiRGBA(0, 0, 0, 192)); - addGfxCmdText(x+AREA_HEADER/2, y+h-AREA_HEADER/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128)); + addGfxCmdText( + x + AREA_HEADER / 2, + y + h - AREA_HEADER / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + name, + imguiRGBA(255, 255, 255, 128)); - addGfxCmdScissor(x+SCROLL_AREA_PADDING, y+SCROLL_AREA_PADDING, w-SCROLL_AREA_PADDING*4, h-AREA_HEADER-SCROLL_AREA_PADDING); + addGfxCmdScissor( + x + SCROLL_AREA_PADDING, + y + SCROLL_AREA_PADDING, + w - SCROLL_AREA_PADDING * 4, + h - AREA_HEADER - SCROLL_AREA_PADDING); return g_insideScrollArea; } @@ -354,39 +391,45 @@ bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scr void imguiEndScrollArea() { // Disable scissoring. - addGfxCmdScissor(-1,-1,-1,-1); + addGfxCmdScissor(-1, -1, -1, -1); // Draw scroll bar - int x = g_scrollRight+SCROLL_AREA_PADDING/2; + int x = g_scrollRight + SCROLL_AREA_PADDING / 2; int y = g_scrollBottom; - int w = SCROLL_AREA_PADDING*2; + int w = SCROLL_AREA_PADDING * 2; int h = g_scrollTop - g_scrollBottom; int stop = g_scrollAreaTop; int sbot = g_state.widgetY; - int sh = stop - sbot; // The scrollable area height. + int sh = stop - sbot; // The scrollable area height. + + float barHeight = (float)h / (float)sh; - float barHeight = (float)h/(float)sh; - if (barHeight < 1) { - float barY = (float)(y - sbot)/(float)sh; - if (barY < 0) barY = 0; - if (barY > 1) barY = 1; - + float barY = (float)(y - sbot) / (float)sh; + if (barY < 0) + { + barY = 0; + } + if (barY > 1) + { + barY = 1; + } + // Handle scroll bar logic. unsigned int hid = g_scrollId; int hx = x; - int hy = y + (int)(barY*h); + int hy = y + (int)(barY * h); int hw = w; - int hh = (int)(barHeight*h); - - const int range = h - (hh-1); + int hh = (int)(barHeight * h); + + const int range = h - (hh - 1); bool over = inRect(hx, hy, hw, hh); buttonLogic(hid, over); if (isActive(hid)) { - float u = (float)(hy-y) / (float)range; + float u = (float)(hy - y) / (float)range; if (g_state.wentActive) { g_state.dragY = g_state.my; @@ -395,28 +438,56 @@ void imguiEndScrollArea() if (g_state.dragY != g_state.my) { u = g_state.dragOrig + (g_state.my - g_state.dragY) / (float)range; - if (u < 0) u = 0; - if (u > 1) u = 1; - *g_scrollVal = (int)((1-u) * (sh - h)); + if (u < 0) { u = 0; } + if (u > 1) { u = 1; } + *g_scrollVal = (int)((1 - u) * (sh - h)); } } - + // BG - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)w/2-1, imguiRGBA(0,0,0,196)); + addGfxCmdRoundedRect( + (float)x, + (float)y, + (float)w, + (float)h, + (float)w / 2 - 1, + imguiRGBA(0, 0, 0, 196)); // Bar if (isActive(hid)) - addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, imguiRGBA(255,196,0,196)); + { + addGfxCmdRoundedRect( + (float)hx, + (float)hy, + (float)hw, + (float)hh, + (float)w / 2 - 1, + imguiRGBA(255, 196, 0, 196)); + } else - addGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w/2-1, isHot(hid) ? imguiRGBA(255,196,0,96) : imguiRGBA(255,255,255,64)); + { + addGfxCmdRoundedRect( + (float)hx, + (float)hy, + (float)hw, + (float)hh, + (float)w / 2 - 1, + isHot(hid) ? imguiRGBA(255, 196, 0, 96) : imguiRGBA(255, 255, 255, 64)); + } // Handle mouse scrolling. - if (g_insideScrollArea) // && !anyActive()) + if (g_insideScrollArea) // && !anyActive()) { if (g_state.scroll) { - *g_scrollVal += 20*g_state.scroll; - if (*g_scrollVal < 0) *g_scrollVal = 0; - if (*g_scrollVal > (sh - h)) *g_scrollVal = (sh - h); + *g_scrollVal += 20 * g_state.scroll; + if (*g_scrollVal < 0) + { + *g_scrollVal = 0; + } + if (*g_scrollVal > (sh - h)) + { + *g_scrollVal = (sh - h); + } } } } @@ -426,8 +497,8 @@ void imguiEndScrollArea() bool imguiButton(const char* text, bool enabled) { g_state.widgetId++; - unsigned int id = (g_state.areaId<<16) | g_state.widgetId; - + unsigned int id = (g_state.areaId << 16) | g_state.widgetId; + int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; @@ -437,11 +508,31 @@ bool imguiButton(const char* text, bool enabled) bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT/2-1, imguiRGBA(128,128,128, isActive(id)?196:96)); + addGfxCmdRoundedRect( + (float)x, + (float)y, + (float)w, + (float)h, + (float)BUTTON_HEIGHT / 2 - 1, + imguiRGBA(128, 128, 128, isActive(id) ? 196 : 96)); if (enabled) - addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + isHot(id) ? imguiRGBA(255, 196, 0, 255) : imguiRGBA(255, 255, 255, 200)); + } else - addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + imguiRGBA(128, 128, 128, 200)); + } return res; } @@ -449,33 +540,55 @@ bool imguiButton(const char* text, bool enabled) bool imguiItem(const char* text, bool enabled) { g_state.widgetId++; - unsigned int id = (g_state.areaId<<16) | g_state.widgetId; - + unsigned int id = (g_state.areaId << 16) | g_state.widgetId; + int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; int h = BUTTON_HEIGHT; g_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING; - + bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); - + if (isHot(id)) - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 2.0f, imguiRGBA(255,196,0,isActive(id)?196:96)); + { + addGfxCmdRoundedRect( + (float)x, + (float)y, + (float)w, + (float)h, + 2.0f, + imguiRGBA(255, 196, 0, isActive(id) ? 196 : 96)); + } if (enabled) - addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + imguiRGBA(255, 255, 255, 200)); + } else - addGfxCmdText(x+BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); - + { + addGfxCmdText( + x + BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + imguiRGBA(128, 128, 128, 200)); + } + return res; } bool imguiCheck(const char* text, bool checked, bool enabled) { g_state.widgetId++; - unsigned int id = (g_state.areaId<<16) | g_state.widgetId; - + unsigned int id = (g_state.areaId << 16) | g_state.widgetId; + int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; @@ -484,22 +597,58 @@ bool imguiCheck(const char* text, bool checked, bool enabled) bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); - - const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2; - const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2; - addGfxCmdRoundedRect((float)cx-3, (float)cy-3, (float)CHECK_SIZE+6, (float)CHECK_SIZE+6, 4, imguiRGBA(128,128,128, isActive(id)?196:96)); + + const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; + const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; + addGfxCmdRoundedRect( + (float)cx - 3, + (float)cy - 3, + (float)CHECK_SIZE + 6, + (float)CHECK_SIZE + 6, + 4, + imguiRGBA(128, 128, 128, isActive(id) ? 196 : 96)); if (checked) { if (enabled) - addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(255,255,255,isActive(id)?255:200)); + { + addGfxCmdRoundedRect( + (float)cx, + (float)cy, + (float)CHECK_SIZE, + (float)CHECK_SIZE, + (float)CHECK_SIZE / 2 - 1, + imguiRGBA(255, 255, 255, isActive(id) ? 255 : 200)); + } else - addGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE/2-1, imguiRGBA(128,128,128,200)); + { + addGfxCmdRoundedRect( + (float)cx, + (float)cy, + (float)CHECK_SIZE, + (float)CHECK_SIZE, + (float)CHECK_SIZE / 2 - 1, + imguiRGBA(128, 128, 128, 200)); + } } if (enabled) - addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + isHot(id) ? imguiRGBA(255, 196, 0, 255) : imguiRGBA(255, 255, 255, 200)); + } else - addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + imguiRGBA(128, 128, 128, 200)); + } return res; } @@ -507,33 +656,64 @@ bool imguiCheck(const char* text, bool checked, bool enabled) bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled) { g_state.widgetId++; - unsigned int id = (g_state.areaId<<16) | g_state.widgetId; - + unsigned int id = (g_state.areaId << 16) | g_state.widgetId; + int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; int h = BUTTON_HEIGHT; - g_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING; + g_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING; - const int cx = x+BUTTON_HEIGHT/2-CHECK_SIZE/2; - const int cy = y+BUTTON_HEIGHT/2-CHECK_SIZE/2; + const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; + const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); - - if (checked) - addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, imguiRGBA(255,255,255,isActive(id)?255:200)); + + if (checked) { + addGfxCmdTriangle( + cx, + cy, + CHECK_SIZE, + CHECK_SIZE, + 2, + imguiRGBA(255, 255, 255, isActive(id) ? 255 : 200)); + } else - addGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, imguiRGBA(255,255,255,isActive(id)?255:200)); + { + addGfxCmdTriangle( + cx, + cy, + CHECK_SIZE, + CHECK_SIZE, + 1, + imguiRGBA(255, 255, 255, isActive(id) ? 255 : 200)); + } if (enabled) - addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + isHot(id) ? imguiRGBA(255, 196, 0, 255) : imguiRGBA(255, 255, 255, 200)); + } else - addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); + { + addGfxCmdText( + x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128, 128, 128, 200)); + } if (subtext) - addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, subtext, imguiRGBA(255,255,255,128)); - + { + addGfxCmdText(x + w - BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_RIGHT, + subtext, + imguiRGBA(255, 255, 255, 128)); + } + return res; } @@ -542,7 +722,7 @@ void imguiLabel(const char* text) int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; g_state.widgetY -= BUTTON_HEIGHT; - addGfxCmdText(x, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,255)); + addGfxCmdText(x, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, IMGUI_ALIGN_LEFT, text, imguiRGBA(255, 255, 255, 255)); } void imguiValue(const char* text) @@ -551,31 +731,35 @@ void imguiValue(const char* text) const int y = g_state.widgetY - BUTTON_HEIGHT; const int w = g_state.widgetW; g_state.widgetY -= BUTTON_HEIGHT; - - addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, text, imguiRGBA(255,255,255,200)); + + addGfxCmdText(x + w - BUTTON_HEIGHT / 2, + y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_RIGHT, + text, + imguiRGBA(255, 255, 255, 200)); } bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled) { g_state.widgetId++; - unsigned int id = (g_state.areaId<<16) | g_state.widgetId; - + unsigned int id = (g_state.areaId << 16) | g_state.widgetId; + int x = g_state.widgetX; int y = g_state.widgetY - BUTTON_HEIGHT; int w = g_state.widgetW; int h = SLIDER_HEIGHT; g_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING; - addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, imguiRGBA(0,0,0,128)); + addGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, imguiRGBA(0, 0, 0, 128)); const int range = w - SLIDER_MARKER_WIDTH; - float u = (*val - vmin) / (vmax-vmin); - if (u < 0) u = 0; - if (u > 1) u = 1; + float u = (*val - vmin) / (vmax - vmin); + if (u < 0) { u = 0; } + if (u > 1) { u = 1; } int m = (int)(u * range); - bool over = enabled && inRect(x+m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT); + bool over = enabled && inRect(x + m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT); bool res = buttonLogic(id, over); bool valChanged = false; @@ -589,19 +773,28 @@ bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vin if (g_state.dragX != g_state.mx) { u = g_state.dragOrig + (float)(g_state.mx - g_state.dragX) / (float)range; - if (u < 0) u = 0; - if (u > 1) u = 1; - *val = vmin + u*(vmax-vmin); - *val = floorf(*val/vinc+0.5f)*vinc; // Snap to vinc + if (u < 0) { u = 0; } + if (u > 1) { u = 1; } + *val = vmin + u * (vmax - vmin); + *val = floorf(*val / vinc + 0.5f) * vinc; // Snap to vinc m = (int)(u * range); valChanged = true; } } if (isActive(id)) - addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, imguiRGBA(255,255,255,255)); + { + addGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, imguiRGBA(255, 255, 255, 255)); + } else - addGfxCmdRoundedRect((float)(x+m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? imguiRGBA(255,196,0,128) : imguiRGBA(255,255,255,64)); + { + addGfxCmdRoundedRect((float)(x + m), + (float)y, + (float)SLIDER_MARKER_WIDTH, + (float)SLIDER_HEIGHT, + 4.0f, + isHot(id) ? imguiRGBA(255, 196, 0, 128) : imguiRGBA(255, 255, 255, 64)); + } // TODO: fix this, take a look at 'nicenum'. int digits = (int)(ceilf(log10f(vinc))); @@ -609,22 +802,37 @@ bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vin snprintf(fmt, 16, "%%.%df", digits >= 0 ? 0 : -digits); char msg[128]; snprintf(msg, 128, fmt, *val); - + if (enabled) { - addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); - addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200)); + addGfxCmdText(x + SLIDER_HEIGHT / 2, + y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + isHot(id) ? imguiRGBA(255, 196, 0, 255) : imguiRGBA(255, 255, 255, 200)); + addGfxCmdText(x + w - SLIDER_HEIGHT / 2, + y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_RIGHT, + msg, + isHot(id) ? imguiRGBA(255, 196, 0, 255) : imguiRGBA(255, 255, 255, 200)); } else { - addGfxCmdText(x+SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200)); - addGfxCmdText(x+w-SLIDER_HEIGHT/2, y+SLIDER_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, msg, imguiRGBA(128,128,128,200)); + addGfxCmdText(x + SLIDER_HEIGHT / 2, + y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_LEFT, + text, + imguiRGBA(128, 128, 128, 200)); + addGfxCmdText(x + w - SLIDER_HEIGHT / 2, + y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, + IMGUI_ALIGN_RIGHT, + msg, + imguiRGBA(128, 128, 128, 200)); } return res || valChanged; } - void imguiIndent() { g_state.widgetX += INDENT_SIZE; @@ -639,18 +847,18 @@ void imguiUnindent() void imguiSeparator() { - g_state.widgetY -= DEFAULT_SPACING*3; + g_state.widgetY -= DEFAULT_SPACING * 3; } void imguiSeparatorLine() { int x = g_state.widgetX; - int y = g_state.widgetY - DEFAULT_SPACING*2; + int y = g_state.widgetY - DEFAULT_SPACING * 2; int w = g_state.widgetW; int h = 1; - g_state.widgetY -= DEFAULT_SPACING*4; + g_state.widgetY -= DEFAULT_SPACING * 4; - addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255,255,255,32)); + addGfxCmdRect((float)x, (float)y, (float)w, (float)h, imguiRGBA(255, 255, 255, 32)); } void imguiDrawText(int x, int y, int align, const char* text, unsigned int color) @@ -672,4 +880,3 @@ void imguiDrawRoundedRect(float x, float y, float w, float h, float r, unsigned { addGfxCmdRoundedRect(x, y, w, h, r, color); } - diff --git a/RecastDemo/Source/imguiRenderGL.cpp b/RecastDemo/Source/imguiRenderGL.cpp index f81b13e7..862ac354 100644 --- a/RecastDemo/Source/imguiRenderGL.cpp +++ b/RecastDemo/Source/imguiRenderGL.cpp @@ -16,11 +16,12 @@ // 3. This notice may not be removed or altered from any source distribution. // -#include -#include -#include "imgui.h" #include "SDL.h" #include "SDL_opengl.h" +#include "imgui.h" + +#include +#include // Some math headers don't have PI defined. static const float PI = 3.14159265f; @@ -28,29 +29,23 @@ static const float PI = 3.14159265f; void imguifree(void* ptr, void* userptr); void* imguimalloc(size_t size, void* userptr); -#define STBTT_malloc(x,y) imguimalloc(x,y) -#define STBTT_free(x,y) imguifree(x,y) +#define STBTT_malloc(x, y) imguimalloc(x, y) +#define STBTT_free(x, y) imguifree(x, y) #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" -void imguifree(void* ptr, void* /*userptr*/) -{ - free(ptr); -} +void imguifree(void* ptr, void* /*userptr*/) { free(ptr); } -void* imguimalloc(size_t size, void* /*userptr*/) -{ - return malloc(size); -} +void* imguimalloc(size_t size, void* /*userptr*/) { return malloc(size); } static const unsigned TEMP_COORD_COUNT = 100; -static float g_tempCoords[TEMP_COORD_COUNT*2]; -static float g_tempNormals[TEMP_COORD_COUNT*2]; +static float g_tempCoords[TEMP_COORD_COUNT * 2]; +static float g_tempNormals[TEMP_COORD_COUNT * 2]; -static const int CIRCLE_VERTS = 8*4; -static float g_circleVerts[CIRCLE_VERTS*2]; +static const int CIRCLE_VERTS = 8 * 4; +static float g_circleVerts[CIRCLE_VERTS * 2]; -static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs +static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs static GLuint g_ftex = 0; inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) @@ -60,84 +55,87 @@ inline unsigned int RGBA(unsigned char r, unsigned char g, unsigned char b, unsi static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col) { - if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT; - - for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + if (numCoords > TEMP_COORD_COUNT) { numCoords = TEMP_COORD_COUNT; } + + for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++) { - const float* v0 = &coords[j*2]; - const float* v1 = &coords[i*2]; + const float* v0 = &coords[j * 2]; + const float* v1 = &coords[i * 2]; float dx = v1[0] - v0[0]; float dy = v1[1] - v0[1]; - float d = sqrtf(dx*dx+dy*dy); + float d = sqrtf(dx * dx + dy * dy); if (d > 0) { - d = 1.0f/d; + d = 1.0f / d; dx *= d; dy *= d; } - g_tempNormals[j*2+0] = dy; - g_tempNormals[j*2+1] = -dx; + g_tempNormals[j * 2 + 0] = dy; + g_tempNormals[j * 2 + 1] = -dx; } - - for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + + for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++) { - float dlx0 = g_tempNormals[j*2+0]; - float dly0 = g_tempNormals[j*2+1]; - float dlx1 = g_tempNormals[i*2+0]; - float dly1 = g_tempNormals[i*2+1]; + float dlx0 = g_tempNormals[j * 2 + 0]; + float dly0 = g_tempNormals[j * 2 + 1]; + float dlx1 = g_tempNormals[i * 2 + 0]; + float dly1 = g_tempNormals[i * 2 + 1]; float dmx = (dlx0 + dlx1) * 0.5f; float dmy = (dly0 + dly1) * 0.5f; - float dmr2 = dmx*dmx + dmy*dmy; + float dmr2 = dmx * dmx + dmy * dmy; if (dmr2 > 0.000001f) { - float scale = 1.0f / dmr2; - if (scale > 10.0f) scale = 10.0f; + float scale = 1.0f / dmr2; + if (scale > 10.0f) { scale = 10.0f; } dmx *= scale; dmy *= scale; } - g_tempCoords[i*2+0] = coords[i*2+0]+dmx*r; - g_tempCoords[i*2+1] = coords[i*2+1]+dmy*r; + g_tempCoords[i * 2 + 0] = coords[i * 2 + 0] + dmx * r; + g_tempCoords[i * 2 + 1] = coords[i * 2 + 1] + dmy * r; } - - unsigned int colTrans = RGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, 0); - + + unsigned int colTrans = RGBA(col & 0xff, (col >> 8) & 0xff, (col >> 16) & 0xff, 0); + glBegin(GL_TRIANGLES); - + glColor4ubv((GLubyte*)&col); - - for (unsigned i = 0, j = numCoords-1; i < numCoords; j=i++) + + for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++) { - glVertex2fv(&coords[i*2]); - glVertex2fv(&coords[j*2]); + glVertex2fv(&coords[i * 2]); + glVertex2fv(&coords[j * 2]); glColor4ubv((GLubyte*)&colTrans); - glVertex2fv(&g_tempCoords[j*2]); - - glVertex2fv(&g_tempCoords[j*2]); - glVertex2fv(&g_tempCoords[i*2]); - + glVertex2fv(&g_tempCoords[j * 2]); + + glVertex2fv(&g_tempCoords[j * 2]); + glVertex2fv(&g_tempCoords[i * 2]); + glColor4ubv((GLubyte*)&col); - glVertex2fv(&coords[i*2]); + glVertex2fv(&coords[i * 2]); } - + glColor4ubv((GLubyte*)&col); for (unsigned i = 2; i < numCoords; ++i) { glVertex2fv(&coords[0]); - glVertex2fv(&coords[(i-1)*2]); - glVertex2fv(&coords[i*2]); + glVertex2fv(&coords[(i - 1) * 2]); + glVertex2fv(&coords[i * 2]); } - + glEnd(); } static void drawRect(float x, float y, float w, float h, float fth, unsigned int col) { - float verts[4*2] = - { - x+0.5f, y+0.5f, - x+w-0.5f, y+0.5f, - x+w-0.5f, y+h-0.5f, - x+0.5f, y+h-0.5f, + float verts[4 * 2] = { + x + 0.5f, + y + 0.5f, + x + w - 0.5f, + y + 0.5f, + x + w - 0.5f, + y + h - 0.5f, + x + 0.5f, + y + h - 0.5f, }; drawPolygon(verts, 4, fth, col); } @@ -148,104 +146,102 @@ static void drawEllipse(float x, float y, float w, float h, float fth, unsigned float verts[CIRCLE_VERTS*2]; const float* cverts = g_circleVerts; float* v = verts; - + for (int i = 0; i < CIRCLE_VERTS; ++i) { *v++ = x + cverts[i*2]*w; *v++ = y + cverts[i*2+1]*h; } - + drawPolygon(verts, CIRCLE_VERTS, fth, col); } */ static void drawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col) { - const unsigned n = CIRCLE_VERTS/4; - float verts[(n+1)*4*2]; + const unsigned n = CIRCLE_VERTS / 4; + float verts[(n + 1) * 4 * 2]; const float* cverts = g_circleVerts; float* v = verts; - + for (unsigned i = 0; i <= n; ++i) { - *v++ = x+w-r + cverts[i*2]*r; - *v++ = y+h-r + cverts[i*2+1]*r; + *v++ = x + w - r + cverts[i * 2] * r; + *v++ = y + h - r + cverts[i * 2 + 1] * r; } - - for (unsigned i = n; i <= n*2; ++i) - { - *v++ = x+r + cverts[i*2]*r; - *v++ = y+h-r + cverts[i*2+1]*r; - } - - for (unsigned i = n*2; i <= n*3; ++i) - { - *v++ = x+r + cverts[i*2]*r; - *v++ = y+r + cverts[i*2+1]*r; - } - - for (unsigned i = n*3; i < n*4; ++i) - { - *v++ = x+w-r + cverts[i*2]*r; - *v++ = y+r + cverts[i*2+1]*r; - } - *v++ = x+w-r + cverts[0]*r; - *v++ = y+r + cverts[1]*r; - - drawPolygon(verts, (n+1)*4, fth, col); -} + for (unsigned i = n; i <= n * 2; ++i) + { + *v++ = x + r + cverts[i * 2] * r; + *v++ = y + h - r + cverts[i * 2 + 1] * r; + } + + for (unsigned i = n * 2; i <= n * 3; ++i) + { + *v++ = x + r + cverts[i * 2] * r; + *v++ = y + r + cverts[i * 2 + 1] * r; + } + + for (unsigned i = n * 3; i < n * 4; ++i) + { + *v++ = x + w - r + cverts[i * 2] * r; + *v++ = y + r + cverts[i * 2 + 1] * r; + } + *v++ = x + w - r + cverts[0] * r; + *v++ = y + r + cverts[1] * r; + + drawPolygon(verts, (n + 1) * 4, fth, col); +} static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col) { - float dx = x1-x0; - float dy = y1-y0; - float d = sqrtf(dx*dx+dy*dy); + float dx = x1 - x0; + float dy = y1 - y0; + float d = sqrtf(dx * dx + dy * dy); if (d > 0.0001f) { - d = 1.0f/d; + d = 1.0f / d; dx *= d; dy *= d; } float nx = dy; float ny = -dx; - float verts[4*2]; + float verts[4 * 2]; r -= fth; r *= 0.5f; - if (r < 0.01f) r = 0.01f; + if (r < 0.01f) { r = 0.01f; } dx *= r; dy *= r; nx *= r; ny *= r; - - verts[0] = x0-dx-nx; - verts[1] = y0-dy-ny; - - verts[2] = x0-dx+nx; - verts[3] = y0-dy+ny; - - verts[4] = x1+dx+nx; - verts[5] = y1+dy+ny; - - verts[6] = x1+dx-nx; - verts[7] = y1+dy-ny; - + + verts[0] = x0 - dx - nx; + verts[1] = y0 - dy - ny; + + verts[2] = x0 - dx + nx; + verts[3] = y0 - dy + ny; + + verts[4] = x1 + dx + nx; + verts[5] = y1 + dy + ny; + + verts[6] = x1 + dx - nx; + verts[7] = y1 + dy - ny; + drawPolygon(verts, 4, fth, col); } - bool imguiRenderGLInit(const char* fontpath) { for (int i = 0; i < CIRCLE_VERTS; ++i) { - float a = (float)i/(float)CIRCLE_VERTS * PI*2; - g_circleVerts[i*2+0] = cosf(a); - g_circleVerts[i*2+1] = sinf(a); + float a = (float)i / (float)CIRCLE_VERTS * PI * 2; + g_circleVerts[i * 2 + 0] = cosf(a); + g_circleVerts[i * 2 + 1] = sinf(a); } // Load font. FILE* fp = fopen(fontpath, "rb"); - if (!fp) return false; + if (!fp) { return false; } if (fseek(fp, 0, SEEK_END) != 0) { fclose(fp); @@ -262,14 +258,14 @@ bool imguiRenderGLInit(const char* fontpath) fclose(fp); return false; } - - unsigned char* ttfBuffer = (unsigned char*)malloc(size); + + unsigned char* ttfBuffer = (unsigned char*)malloc(size); if (!ttfBuffer) { fclose(fp); return false; } - + size_t readLen = fread(ttfBuffer, 1, size, fp); fclose(fp); if (readLen != static_cast(size)) @@ -279,20 +275,20 @@ bool imguiRenderGLInit(const char* fontpath) } fp = 0; - - unsigned char* bmap = (unsigned char*)malloc(512*512); + + unsigned char* bmap = (unsigned char*)malloc(512 * 512); if (!bmap) { free(ttfBuffer); return false; } - - stbtt_BakeFontBitmap(ttfBuffer,0, 15.0f, bmap,512,512, 32,96, g_cdata); - + + stbtt_BakeFontBitmap(ttfBuffer, 0, 15.0f, bmap, 512, 512, 32, 96, g_cdata); + // can free ttf_buffer at this point glGenTextures(1, &g_ftex); glBindTexture(GL_TEXTURE_2D, g_ftex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bmap); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bmap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -311,29 +307,29 @@ void imguiRenderGLDestroy() } } -static void getBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, - float *xpos, float *ypos, stbtt_aligned_quad *q) +static void +getBakedQuad(stbtt_bakedchar* chardata, int pw, int ph, int char_index, float* xpos, float* ypos, stbtt_aligned_quad* q) { - stbtt_bakedchar *b = chardata + char_index; + stbtt_bakedchar* b = chardata + char_index; int round_x = STBTT_ifloor(*xpos + b->xoff); int round_y = STBTT_ifloor(*ypos - b->yoff); - + q->x0 = (float)round_x; q->y0 = (float)round_y; q->x1 = (float)round_x + b->x1 - b->x0; q->y1 = (float)round_y - b->y1 + b->y0; - + q->s0 = b->x0 / (float)pw; q->t0 = b->y0 / (float)pw; q->s1 = b->x1 / (float)ph; q->t1 = b->y1 / (float)ph; - + *xpos += b->xadvance; } static const float g_tabStops[4] = {150, 210, 270, 330}; -static float getTextLength(stbtt_bakedchar *chardata, const char* text) +static float getTextLength(stbtt_bakedchar* chardata, const char* text) { float xpos = 0; float len = 0; @@ -353,7 +349,7 @@ static float getTextLength(stbtt_bakedchar *chardata, const char* text) } else if (c >= 32 && c < 128) { - stbtt_bakedchar *b = chardata + c-32; + stbtt_bakedchar* b = chardata + c - 32; int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5); len = round_x + b->x1 - b->x0 + 0.5f; xpos += b->xadvance; @@ -363,27 +359,25 @@ static float getTextLength(stbtt_bakedchar *chardata, const char* text) return len; } -static void drawText(float x, float y, const char *text, int align, unsigned int col) +static void drawText(float x, float y, const char* text, int align, unsigned int col) { - if (!g_ftex) return; - if (!text) return; - - if (align == IMGUI_ALIGN_CENTER) - x -= getTextLength(g_cdata, text)/2; - else if (align == IMGUI_ALIGN_RIGHT) - x -= getTextLength(g_cdata, text); - - glColor4ub(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff); - + if (!g_ftex) { return; } + if (!text) { return; } + + if (align == IMGUI_ALIGN_CENTER) { x -= getTextLength(g_cdata, text) / 2; } + else if (align == IMGUI_ALIGN_RIGHT) { x -= getTextLength(g_cdata, text); } + + glColor4ub(col & 0xff, (col >> 8) & 0xff, (col >> 16) & 0xff, (col >> 24) & 0xff); + glEnable(GL_TEXTURE_2D); - + // assume orthographic projection with units = screen pixels, origin at top left glBindTexture(GL_TEXTURE_2D, g_ftex); - + glBegin(GL_TRIANGLES); - + const float ox = x; - + while (*text) { int c = (unsigned char)*text; @@ -391,25 +385,25 @@ static void drawText(float x, float y, const char *text, int align, unsigned int { for (int i = 0; i < 4; ++i) { - if (x < g_tabStops[i]+ox) + if (x < g_tabStops[i] + ox) { - x = g_tabStops[i]+ox; + x = g_tabStops[i] + ox; break; } } } else if (c >= 32 && c < 128) - { + { stbtt_aligned_quad q; - getBakedQuad(g_cdata, 512,512, c-32, &x,&y,&q); - + getBakedQuad(g_cdata, 512, 512, c - 32, &x, &y, &q); + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); - + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); glTexCoord2f(q.s0, q.t1); @@ -419,18 +413,17 @@ static void drawText(float x, float y, const char *text, int align, unsigned int } ++text; } - - glEnd(); + + glEnd(); glDisable(GL_TEXTURE_2D); } - void imguiRenderGLDraw() { const imguiGfxCmd* q = imguiGetRenderQueue(); int nq = imguiGetRenderQueueSize(); - const float s = 1.0f/8.0f; + const float s = 1.0f / 8.0f; glDisable(GL_SCISSOR_TEST); for (int i = 0; i < nq; ++i) @@ -440,48 +433,56 @@ void imguiRenderGLDraw() { if (cmd.rect.r == 0) { - drawRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, - (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, - 1.0f, cmd.col); + drawRect((float)cmd.rect.x * s + 0.5f, + (float)cmd.rect.y * s + 0.5f, + (float)cmd.rect.w * s - 1, + (float)cmd.rect.h * s - 1, + 1.0f, + cmd.col); } else { - drawRoundedRect((float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, - (float)cmd.rect.w*s-1, (float)cmd.rect.h*s-1, - (float)cmd.rect.r*s, 1.0f, cmd.col); + drawRoundedRect((float)cmd.rect.x * s + 0.5f, + (float)cmd.rect.y * s + 0.5f, + (float)cmd.rect.w * s - 1, + (float)cmd.rect.h * s - 1, + (float)cmd.rect.r * s, + 1.0f, + cmd.col); } } else if (cmd.type == IMGUI_GFXCMD_LINE) { - drawLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col); + drawLine(cmd.line.x0 * s, cmd.line.y0 * s, cmd.line.x1 * s, cmd.line.y1 * s, cmd.line.r * s, 1.0f, cmd.col); } else if (cmd.type == IMGUI_GFXCMD_TRIANGLE) { if (cmd.flags == 1) { - const float verts[3*2] = - { - (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f, - (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s/2-0.5f, - (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + const float verts[3 * 2] = { + (float)cmd.rect.x * s + 0.5f, + (float)cmd.rect.y * s + 0.5f, + (float)cmd.rect.x * s + 0.5f + (float)cmd.rect.w * s - 1, + (float)cmd.rect.y * s + 0.5f + (float)cmd.rect.h * s / 2 - 0.5f, + (float)cmd.rect.x * s + 0.5f, + (float)cmd.rect.y * s + 0.5f + (float)cmd.rect.h * s - 1, }; drawPolygon(verts, 3, 1.0f, cmd.col); } if (cmd.flags == 2) { - const float verts[3*2] = - { - (float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, - (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s/2-0.5f, (float)cmd.rect.y*s+0.5f, - (float)cmd.rect.x*s+0.5f+(float)cmd.rect.w*s-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1, + const float verts[3 * 2] = { + (float)cmd.rect.x * s + 0.5f, + (float)cmd.rect.y * s + 0.5f + (float)cmd.rect.h * s - 1, + (float)cmd.rect.x * s + 0.5f + (float)cmd.rect.w * s / 2 - 0.5f, + (float)cmd.rect.y * s + 0.5f, + (float)cmd.rect.x * s + 0.5f + (float)cmd.rect.w * s - 1, + (float)cmd.rect.y * s + 0.5f + (float)cmd.rect.h * s - 1, }; drawPolygon(verts, 3, 1.0f, cmd.col); } } - else if (cmd.type == IMGUI_GFXCMD_TEXT) - { - drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col); - } + else if (cmd.type == IMGUI_GFXCMD_TEXT) { drawText(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col); } else if (cmd.type == IMGUI_GFXCMD_SCISSOR) { if (cmd.flags) @@ -489,10 +490,7 @@ void imguiRenderGLDraw() glEnable(GL_SCISSOR_TEST); glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h); } - else - { - glDisable(GL_SCISSOR_TEST); - } + else { glDisable(GL_SCISSOR_TEST); } } } glDisable(GL_SCISSOR_TEST);