Tiny fix for imgui drawing. Implemented adjusting of the moving target without path finding.

This commit is contained in:
Mikko Mononen 2010-10-29 07:28:20 +00:00
parent 2dd22d024a
commit aa18cf4a8d
8 changed files with 965 additions and 1168 deletions

File diff suppressed because it is too large Load Diff

View File

@ -284,13 +284,13 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>61</integer> <integer>62</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 623}, {264, 660}}</string> <string>{{0, 824}, {264, 660}}</string>
</dict> </dict>
<key>PBXTopSmartGroupGIDs</key> <key>PBXTopSmartGroupGIDs</key>
<array/> <array/>
@ -325,7 +325,7 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>SlideShow.cpp</string> <string>CrowdManager.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
<dict> <dict>
<key>Split0</key> <key>Split0</key>
@ -333,11 +333,11 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string> <string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>SlideShow.cpp</string> <string>CrowdManager.cpp</string>
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>6BB9C2C612744A1C00B97C1C</string> <string>6B8D55EA127AAE680077C699</string>
<key>history</key> <key>history</key>
<array> <array>
<string>6BBB4C34115B7A3D00CF791D</string> <string>6BBB4C34115B7A3D00CF791D</string>
@ -370,7 +370,6 @@
<string>6B84778B122D279700ADF63D</string> <string>6B84778B122D279700ADF63D</string>
<string>6B8477BB122D297200ADF63D</string> <string>6B8477BB122D297200ADF63D</string>
<string>6B8477E1122D2B9100ADF63D</string> <string>6B8477E1122D2B9100ADF63D</string>
<string>6B8477FC122D2E2A00ADF63D</string>
<string>6B8477FE122D2E2A00ADF63D</string> <string>6B8477FE122D2E2A00ADF63D</string>
<string>6B8477FF122D2E2A00ADF63D</string> <string>6B8477FF122D2E2A00ADF63D</string>
<string>6BD6681812434B790021A7A4</string> <string>6BD6681812434B790021A7A4</string>
@ -392,21 +391,17 @@
<string>6BA8CF511255D44700272A3B</string> <string>6BA8CF511255D44700272A3B</string>
<string>6BA8CF5B1255D49B00272A3B</string> <string>6BA8CF5B1255D49B00272A3B</string>
<string>6BA8CF951255D97400272A3B</string> <string>6BA8CF951255D97400272A3B</string>
<string>6BA8CFA81255DC6500272A3B</string>
<string>6BA8CFBE1255DE0500272A3B</string> <string>6BA8CFBE1255DE0500272A3B</string>
<string>6BB2EDF91261C75400E350F8</string> <string>6BB2EDF91261C75400E350F8</string>
<string>6BB2EE241261C92300E350F8</string> <string>6BB2EE241261C92300E350F8</string>
<string>6BB2EE261261C92300E350F8</string> <string>6BB2EE261261C92300E350F8</string>
<string>6BB2EE271261C92300E350F8</string> <string>6BB2EE271261C92300E350F8</string>
<string>6BB2EE351261CEB800E350F8</string>
<string>6BB2EE361261CEB800E350F8</string> <string>6BB2EE361261CEB800E350F8</string>
<string>6BB2EE3F1261D02000E350F8</string> <string>6BB2EE3F1261D02000E350F8</string>
<string>6BB2EE661261D48100E350F8</string> <string>6BB2EE661261D48100E350F8</string>
<string>6BB2EE691261D48100E350F8</string> <string>6BB2EE691261D48100E350F8</string>
<string>6BB2EE731261DA0400E350F8</string> <string>6BB2EE731261DA0400E350F8</string>
<string>6BB2EE7B1264CD7900E350F8</string>
<string>6B1633101268326F0083FC15</string> <string>6B1633101268326F0083FC15</string>
<string>6B1633111268326F0083FC15</string>
<string>6B1633121268326F0083FC15</string> <string>6B1633121268326F0083FC15</string>
<string>6B1633141268326F0083FC15</string> <string>6B1633141268326F0083FC15</string>
<string>6B163317126832D20083FC15</string> <string>6B163317126832D20083FC15</string>
@ -423,14 +418,20 @@
<string>6B16360A126891A40083FC15</string> <string>6B16360A126891A40083FC15</string>
<string>6BB9C228126F4A9100B97C1C</string> <string>6BB9C228126F4A9100B97C1C</string>
<string>6BB9C229126F4A9100B97C1C</string> <string>6BB9C229126F4A9100B97C1C</string>
<string>6BB9C22C126F4A9100B97C1C</string>
<string>6BB9C253126F555F00B97C1C</string> <string>6BB9C253126F555F00B97C1C</string>
<string>6BB9C2A2126F623D00B97C1C</string> <string>6BB9C2A2126F623D00B97C1C</string>
<string>6BB9C2AA126F62C000B97C1C</string> <string>6BB9C2AA126F62C000B97C1C</string>
<string>6BB9C2AB126F62C000B97C1C</string>
<string>6BB9C2B5127449CE00B97C1C</string> <string>6BB9C2B5127449CE00B97C1C</string>
<string>6BB9C2BD127449CE00B97C1C</string> <string>6BB9C2BD127449CE00B97C1C</string>
<string>6BB9C2BF127449CE00B97C1C</string> <string>6BB9C372127A0E5600B97C1C</string>
<string>6B8D5565127A98FB0077C699</string>
<string>6B8D5582127AA2270077C699</string>
<string>6B8D559E127AA3E70077C699</string>
<string>6B8D559F127AA3E70077C699</string>
<string>6B8D55A0127AA3E70077C699</string>
<string>6B8D55B5127AA5E60077C699</string>
<string>6B8D55D9127AABD80077C699</string>
<string>6B8D55DA127AABD80077C699</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -470,6 +471,8 @@
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {992, -27}}</string> <string>{{10, 27}, {992, -27}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1278 719 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>XCDetailModule</string> <string>XCDetailModule</string>
@ -523,9 +526,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {992, -27}}</string> <string>{{0, 0}, {568, 405}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1278 719 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXBuildResultsModule</string> <string>PBXBuildResultsModule</string>
@ -553,11 +554,11 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6BB9C1C0126B562300B97C1C</string> <string>6B8D5569127A98FB0077C699</string>
<string>1CA23ED40692098700951B8B</string> <string>1CA23ED40692098700951B8B</string>
<string>6BB9C1C1126B562300B97C1C</string> <string>6B8D556A127A98FB0077C699</string>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<string>6BB9C1C2126B562300B97C1C</string> <string>6B8D556B127A98FB0077C699</string>
<string>1CA23EDF0692099D00951B8B</string> <string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string> <string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string> <string>1CA23EE10692099D00951B8B</string>
@ -631,8 +632,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {578, 140}}</string> <string>{{0, 0}, {580, 119}}</string>
<string>{{578, 0}, {700, 140}}</string> <string>{{580, 0}, {698, 119}}</string>
</array> </array>
</dict> </dict>
<key>VerticalSplitView</key> <key>VerticalSplitView</key>
@ -647,8 +648,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {1278, 140}}</string> <string>{{0, 0}, {1278, 119}}</string>
<string>{{0, 140}, {1278, 257}}</string> <string>{{0, 119}, {1278, 278}}</string>
</array> </array>
</dict> </dict>
</dict> </dict>
@ -678,10 +679,10 @@
<string>Value</string> <string>Value</string>
<real>168</real> <real>168</real>
<string>Summary</string> <string>Summary</string>
<real>324</real> <real>322</real>
</array> </array>
<key>Frame</key> <key>Frame</key>
<string>{{578, 0}, {700, 140}}</string> <string>{{580, 0}, {698, 119}}</string>
</dict> </dict>
</dict> </dict>
<key>Module</key> <key>Module</key>
@ -705,14 +706,14 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6BB9C1C3126B562300B97C1C</string> <string>6B8D5585127AA2270077C699</string>
<string>1CCC7628064C1048000F2A68</string> <string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string> <string>1CCC7629064C1048000F2A68</string>
<string>6BB9C1C4126B562300B97C1C</string> <string>6B8D5586127AA2270077C699</string>
<string>6BB9C1C5126B562300B97C1C</string> <string>6B8D5587127AA2270077C699</string>
<string>6BB9C1C6126B562300B97C1C</string> <string>6B8D5588127AA2270077C699</string>
<string>6BB9C1C7126B562300B97C1C</string> <string>6B8D5589127AA2270077C699</string>
<string>6B8632A30F78115100E2684A</string> <string>6B8D558A127AA2270077C699</string>
</array> </array>
<key>ToolbarConfigUserDefaultsMinorVersion</key> <key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string> <string>2</string>
@ -744,8 +745,9 @@
<integer>5</integer> <integer>5</integer>
<key>WindowOrderList</key> <key>WindowOrderList</key>
<array> <array>
<string>6BB9C1C9126B562300B97C1C</string> <string>6B8D55EB127AAE680077C699</string>
<string>6BB9C1CA126B562300B97C1C</string> <string>6B8D558C127AA2270077C699</string>
<string>6B8D558D127AA2270077C699</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string> <string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array> </array>
<key>WindowString</key> <key>WindowString</key>
@ -1075,16 +1077,18 @@
<string>Yes</string> <string>Yes</string>
</dict> </dict>
<dict> <dict>
<key>FirstTimeWindowDisplayed</key>
<false/>
<key>Identifier</key> <key>Identifier</key>
<string>windowTool.debuggerConsole</string> <string>windowTool.debuggerConsole</string>
<key>IsVertical</key>
<true/>
<key>Layout</key> <key>Layout</key>
<array> <array>
<dict> <dict>
<key>Dock</key> <key>Dock</key>
<array> <array>
<dict> <dict>
<key>BecomeActive</key>
<integer>1</integer>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
<dict> <dict>
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
@ -1095,18 +1099,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {700, 358}}</string> <string>{{0, 0}, {440, 359}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>149 87 700 400 0 0 1440 878 </string> <string>21 355 440 400 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXDebugCLIModule</string> <string>PBXDebugCLIModule</string>
<key>Proportion</key> <key>Proportion</key>
<string>358pt</string> <string>359pt</string>
</dict> </dict>
</array> </array>
<key>Proportion</key> <key>Proportion</key>
<string>358pt</string> <string>359pt</string>
</dict> </dict>
</array> </array>
<key>Name</key> <key>Name</key>
@ -1116,21 +1120,21 @@
<string>PBXDebugCLIModule</string> <string>PBXDebugCLIModule</string>
</array> </array>
<key>StatusbarIsVisible</key> <key>StatusbarIsVisible</key>
<integer>1</integer> <true/>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>1C530D5B069F1CE1000CFCEE</string> <string>1C530D5B069F1CE1000CFCEE</string>
<string>1C530D5C069F1CE1000CFCEE</string> <string>6BB9C382127A0FB400B97C1C</string>
<string>1C78EAAC065D492600B07095</string> <string>1C78EAAC065D492600B07095</string>
</array> </array>
<key>ToolbarConfiguration</key> <key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.consoleV3</string> <string>xcode.toolbar.config.consoleV3</string>
<key>WindowString</key> <key>WindowString</key>
<string>149 87 440 400 0 0 1440 878 </string> <string>21 355 440 400 0 0 1280 778 </string>
<key>WindowToolGUID</key> <key>WindowToolGUID</key>
<string>1C530D5B069F1CE1000CFCEE</string> <string>1C530D5B069F1CE1000CFCEE</string>
<key>WindowToolIsVisible</key> <key>WindowToolIsVisible</key>
<integer>0</integer> <false/>
</dict> </dict>
<dict> <dict>
<key>Identifier</key> <key>Identifier</key>

View File

@ -141,7 +141,8 @@ public:
void optimizePath(const float* next, const float pathOptimizationRange, void optimizePath(const float* next, const float pathOptimizationRange,
dtNavMeshQuery* navquery, const dtQueryFilter* filter); dtNavMeshQuery* navquery, const dtQueryFilter* filter);
void updatePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter); void movePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
void moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
void setCorridor(const float* target, const dtPolyRef* polys, const int npolys); void setCorridor(const float* target, const dtPolyRef* polys, const int npolys);
@ -250,6 +251,7 @@ class CrowdManager
static const int MAX_AGENTS = 128; static const int MAX_AGENTS = 128;
Agent m_agents[MAX_AGENTS]; Agent m_agents[MAX_AGENTS];
dtObstacleAvoidanceDebugData* m_vodebug[MAX_AGENTS]; dtObstacleAvoidanceDebugData* m_vodebug[MAX_AGENTS];
dtObstacleAvoidanceQuery* m_obstacleQuery; dtObstacleAvoidanceQuery* m_obstacleQuery;
PathQueue m_pathq; PathQueue m_pathq;
ProximityGrid m_grid; ProximityGrid m_grid;
@ -266,19 +268,26 @@ class CrowdManager
enum MoveRequestState enum MoveRequestState
{ {
MR_TARGET_FAILED,
MR_TARGET_VALID,
MR_TARGET_REQUESTING, MR_TARGET_REQUESTING,
MR_TARGET_WAITING_FOR_PATH, MR_TARGET_WAITING_FOR_PATH,
MR_TARGET_VALID, MR_TARGET_ADJUST,
MR_TARGET_FAILED,
}; };
static const int MAX_TEMP_PATH = 32;
struct MoveRequest struct MoveRequest
{ {
int idx; unsigned char state; // State of the request
dtPolyRef ref; int idx; // Agent index
float pos[3]; dtPolyRef ref; // Goal ref
unsigned char state; float pos[3]; // Goal position
PathQueueRef pathqRef; PathQueueRef pathqRef; // Path find query ref
dtPolyRef aref; // Goal adjustment ref
float apos[3]; // Goal adjustment pos
dtPolyRef temp[MAX_TEMP_PATH]; // Adjusted path to the goal
int ntemp;
}; };
MoveRequest m_moveRequests[MAX_AGENTS]; MoveRequest m_moveRequests[MAX_AGENTS];
int m_moveRequestCount; int m_moveRequestCount;
@ -295,10 +304,12 @@ public:
const int getAgentCount() const; const int getAgentCount() const;
int addAgent(const float* pos, const float radius, const float height, dtNavMeshQuery* navquery); int addAgent(const float* pos, const float radius, const float height, dtNavMeshQuery* navquery);
void removeAgent(const int idx); void removeAgent(const int idx);
bool requestMoveTarget(const int idx, dtPolyRef ref, const float* pos); bool requestMoveTarget(const int idx, dtPolyRef ref, const float* pos);
bool adjustMoveTarget(const int idx, dtPolyRef ref, const float* pos);
int getActiveAgents(Agent** agents, const int maxAgents); int getActiveAgents(Agent** agents, const int maxAgents);
void updateMoveRequest(const float dt, dtNavMeshQuery* navquery); void updateMoveRequest(const float dt, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
void update(const float dt, unsigned int flags, dtNavMeshQuery* navquery); void update(const float dt, unsigned int flags, dtNavMeshQuery* navquery);
const dtQueryFilter* getFilter() const { return &m_filter; } const dtQueryFilter* getFilter() const { return &m_filter; }

View File

@ -62,6 +62,7 @@ class CrowdTool : public SampleTool
{ {
TOOLMODE_CREATE, TOOLMODE_CREATE,
TOOLMODE_MOVE, TOOLMODE_MOVE,
TOOLMODE_MOVE_TARGET,
}; };
ToolMode m_mode; ToolMode m_mode;

View File

@ -190,7 +190,6 @@ int ProximityGrid::getItemCountAt(const int x, const int y) const
return n; return n;
} }
PathQueue::PathQueue() : PathQueue::PathQueue() :
m_nextHandle(1), m_nextHandle(1),
m_delay(0) m_delay(0)
@ -207,6 +206,7 @@ void PathQueue::update(dtNavMeshQuery* navquery)
{ {
// Artificial delay to test the code better, // Artificial delay to test the code better,
// update only one request too. // update only one request too.
// TODO: Use sliced pathfinder. // TODO: Use sliced pathfinder.
m_delay++; m_delay++;
if ((m_delay % 4) == 0) if ((m_delay % 4) == 0)
@ -346,6 +346,44 @@ static int fixupCorridor(dtPolyRef* path, const int npath, const int maxPath,
return req+size; return req+size;
} }
static int fixupCorridorEnd(dtPolyRef* path, const int npath, const int maxPath,
const dtPolyRef* visited, const int nvisited)
{
int furthestPath = -1;
int furthestVisited = -1;
// Find furthest common polygon.
for (int i = 0; i < npath; ++i)
{
bool found = false;
for (int j = nvisited-1; j >= 0; --j)
{
if (path[i] == visited[j])
{
furthestPath = i;
furthestVisited = j;
found = true;
}
}
if (found)
break;
}
// If no intersection found just return current path.
if (furthestPath == -1 || furthestVisited == -1)
return npath;
// Concatenate paths.
const int ppos = furthestPath+1;
const int vpos = furthestVisited+1;
const int count = dtMin(nvisited-vpos, maxPath-ppos);
dtAssert(ppos+count <= maxPath);
if (count)
memcpy(path+ppos, visited+vpos, sizeof(dtPolyRef)*count);
return ppos+count;
}
static int mergeCorridor(dtPolyRef* path, const int npath, const int maxPath, static int mergeCorridor(dtPolyRef* path, const int npath, const int maxPath,
const dtPolyRef* visited, const int nvisited) const dtPolyRef* visited, const int nvisited)
{ {
@ -475,19 +513,19 @@ void PathCorridor::optimizePath(const float* next, const float pathOptimizationR
// Clamp the ray to max distance. // Clamp the ray to max distance.
float goal[3]; float goal[3];
dtVcopy(goal, next); dtVcopy(goal, next);
const float distSqr = dtVdist2DSqr(m_pos, goal); float dist = dtVdist2D(m_pos, goal);
// If too close to the goal, do not try to optimize. // If too close to the goal, do not try to optimize.
if (distSqr < dtSqr(0.01f)) if (dist < 0.01f)
return; return;
// Overshoot a little. This helps to optimize open fields in tiled meshes.
dist = dtMin(dist+0.01f, pathOptimizationRange);
// If too far truncate ray length. // Adjust ray length.
if (distSqr > dtSqr(pathOptimizationRange)) float delta[3];
{ dtVsub(delta, goal, m_pos);
float delta[3]; dtVmad(goal, m_pos, delta, pathOptimizationRange/dist);
dtVsub(delta, goal, m_pos);
dtVmad(goal, m_pos, delta, dtSqr(pathOptimizationRange)/distSqr);
}
static const int MAX_RES = 32; static const int MAX_RES = 32;
dtPolyRef res[MAX_RES]; dtPolyRef res[MAX_RES];
@ -499,7 +537,7 @@ void PathCorridor::optimizePath(const float* next, const float pathOptimizationR
} }
} }
void PathCorridor::updatePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter) void PathCorridor::movePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
{ {
dtAssert(m_path); dtAssert(m_path);
dtAssert(m_npath); dtAssert(m_npath);
@ -512,13 +550,35 @@ void PathCorridor::updatePosition(const float* npos, dtNavMeshQuery* navquery, c
result, visited, MAX_VISITED); result, visited, MAX_VISITED);
m_npath = fixupCorridor(m_path, m_npath, m_maxPath, visited, nvisited); m_npath = fixupCorridor(m_path, m_npath, m_maxPath, visited, nvisited);
// Adjust agent height to stay on top of the navmesh. // Adjust the position to stay on top of the navmesh.
float h = m_pos[1]; float h = m_pos[1];
navquery->getPolyHeight(m_path[0], result, &h); navquery->getPolyHeight(m_path[0], result, &h);
result[1] = h; result[1] = h;
dtVcopy(m_pos, result); dtVcopy(m_pos, result);
} }
void PathCorridor::moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
{
dtAssert(m_path);
dtAssert(m_npath);
// Move along navmesh and update new position.
float result[3];
static const int MAX_VISITED = 16;
dtPolyRef visited[MAX_VISITED];
int nvisited = navquery->moveAlongSurface(m_path[m_npath-1], m_target, npos, filter,
result, visited, MAX_VISITED);
m_npath = fixupCorridorEnd(m_path, m_npath, m_maxPath, visited, nvisited);
// TODO: should we do that?
// Adjust the position to stay on top of the navmesh.
/* float h = m_target[1];
navquery->getPolyHeight(m_path[m_npath-1], result, &h);
result[1] = h;*/
dtVcopy(m_target, result);
}
void PathCorridor::setCorridor(const float* target, const dtPolyRef* path, const int npath) void PathCorridor::setCorridor(const float* target, const dtPolyRef* path, const int npath)
{ {
dtAssert(m_path); dtAssert(m_path);
@ -859,6 +919,7 @@ bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float*
if (m_moveRequestCount >= MAX_AGENTS) if (m_moveRequestCount >= MAX_AGENTS)
return false; return false;
req = &m_moveRequests[m_moveRequestCount++]; req = &m_moveRequests[m_moveRequestCount++];
memset(req, 0, sizeof(MoveRequest));
} }
// Initialize request. // Initialize request.
@ -868,6 +929,45 @@ bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float*
req->pathqRef = PATHQ_INVALID; req->pathqRef = PATHQ_INVALID;
req->state = MR_TARGET_REQUESTING; req->state = MR_TARGET_REQUESTING;
req->temp[0] = ref;
req->ntemp = 1;
return true;
}
bool CrowdManager::adjustMoveTarget(const int idx, dtPolyRef ref, const float* pos)
{
if (idx < 0 || idx > MAX_AGENTS)
return false;
if (!ref)
return false;
MoveRequest* req = 0;
// Check if there is existing request and update that instead.
for (int i = 0; i < m_moveRequestCount; ++i)
{
if (m_moveRequests[i].idx == idx)
{
req = &m_moveRequests[i];
break;
}
}
if (!req)
{
if (m_moveRequestCount >= MAX_AGENTS)
return false;
req = &m_moveRequests[m_moveRequestCount++];
memset(req, 0, sizeof(MoveRequest));
// New adjust request
req->state = MR_TARGET_ADJUST;
req->idx = idx;
}
// Set adjustment request.
req->aref = ref;
dtVcopy(req->apos, pos);
return true; return true;
} }
@ -955,9 +1055,9 @@ int CrowdManager::getNeighbours(const float* pos, const float height, const floa
return n; return n;
} }
void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery) void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
{ {
// Update move requests. // Fire off new requests.
for (int i = 0; i < m_moveRequestCount; ++i) for (int i = 0; i < m_moveRequestCount; ++i)
{ {
MoveRequest* req = &m_moveRequests[i]; MoveRequest* req = &m_moveRequests[i];
@ -967,6 +1067,33 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (!ag->active) if (!ag->active)
req->state = MR_TARGET_FAILED; req->state = MR_TARGET_FAILED;
// Adjust target
if (req->aref)
{
if (req->state == MR_TARGET_ADJUST)
{
// Adjust existing path.
ag->corridor.moveTargetPosition(req->apos, navquery, filter);
req->state = MR_TARGET_VALID;
}
else
{
// Adjust on the flight request.
float result[3];
static const int MAX_VISITED = 16;
dtPolyRef visited[MAX_VISITED];
int nvisited = navquery->moveAlongSurface(req->temp[req->ntemp-1], req->pos, req->apos, filter,
result, visited, MAX_VISITED);
req->ntemp = fixupCorridorEnd(req->temp, req->ntemp, MAX_TEMP_PATH, visited, nvisited);
dtVcopy(req->pos, result);
// Reset adjustment.
dtVset(req->apos, 0,0,0);
req->aref = 0;
}
}
if (req->state == MR_TARGET_REQUESTING) if (req->state == MR_TARGET_REQUESTING)
{ {
// Calculate request position. // Calculate request position.
@ -991,7 +1118,19 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
req->state = MR_TARGET_WAITING_FOR_PATH; req->state = MR_TARGET_WAITING_FOR_PATH;
} }
} }
else if (req->state == MR_TARGET_WAITING_FOR_PATH) }
// Update requests.
m_pathq.update(navquery);
// Process path results.
for (int i = 0; i < m_moveRequestCount; ++i)
{
MoveRequest* req = &m_moveRequests[i];
Agent* ag = &m_agents[req->idx];
if (req->state == MR_TARGET_WAITING_FOR_PATH)
{ {
// Poll path queue. // Poll path queue.
int state = m_pathq.getRequestState(req->pathqRef); int state = m_pathq.getRequestState(req->pathqRef);
@ -1016,6 +1155,12 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (!nres) if (!nres)
valid = false; valid = false;
// Merge with any target adjustment that happened during the search.
if (req->ntemp > 1)
{
nres = fixupCorridorEnd(res, nres, m_maxPathResult, req->temp, req->ntemp);
}
// Merge result and existing path. // Merge result and existing path.
// The agent might have moved whilst the request is // The agent might have moved whilst the request is
// being processed, so the path may have changed. // being processed, so the path may have changed.
@ -1056,7 +1201,7 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (valid) if (valid)
{ {
ag->corridor.setCorridor(targetPos, res, nres); ag->corridor.setCorridor(targetPos, res, nres);
req->state = MR_TARGET_FAILED; req->state = MR_TARGET_VALID;
} }
else else
{ {
@ -1066,7 +1211,7 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
} }
} }
// Remove request. // Remove request when done with it.
if (req->state == MR_TARGET_VALID || req->state == MR_TARGET_FAILED) if (req->state == MR_TARGET_VALID || req->state == MR_TARGET_FAILED)
{ {
m_moveRequestCount--; m_moveRequestCount--;
@ -1076,7 +1221,6 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
} }
} }
m_pathq.update(navquery);
} }
void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* navquery) void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* navquery)
@ -1097,7 +1241,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
static const float MAX_SPEED = 3.5f; static const float MAX_SPEED = 3.5f;
// Update async move request and path finder. // Update async move request and path finder.
updateMoveRequest(dt, navquery); updateMoveRequest(dt, navquery, &m_filter);
// Register agents to proximity grid. // Register agents to proximity grid.
m_grid.clear(); m_grid.clear();
@ -1306,7 +1450,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
{ {
Agent* ag = agents[i]; Agent* ag = agents[i];
// Move along navmesh. // Move along navmesh.
ag->corridor.updatePosition(ag->npos, navquery, &m_filter); ag->corridor.movePosition(ag->npos, navquery, &m_filter);
// Get valid constrained position back. // Get valid constrained position back.
dtVcopy(ag->npos, ag->corridor.getPos()); dtVcopy(ag->npos, ag->corridor.getPos());
} }

View File

@ -142,6 +142,8 @@ void CrowdTool::handleMenu()
m_mode = TOOLMODE_CREATE; m_mode = TOOLMODE_CREATE;
if (imguiCheck("Move Agents", m_mode == TOOLMODE_MOVE)) if (imguiCheck("Move Agents", m_mode == TOOLMODE_MOVE))
m_mode = TOOLMODE_MOVE; m_mode = TOOLMODE_MOVE;
if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET))
m_mode = TOOLMODE_MOVE_TARGET;
imguiSeparator(); imguiSeparator();
@ -260,6 +262,23 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift)
} }
} }
} }
else if (m_mode == TOOLMODE_MOVE_TARGET)
{
// Find nearest point on navmesh and set move request to that location.
dtNavMeshQuery* navquery = m_sample->getNavMeshQuery();
const dtQueryFilter* filter = m_crowd.getFilter();
const float* ext = m_crowd.getQueryExtents();
m_targetRef = navquery->findNearestPoly(p, ext, filter, m_targetPos);
if (m_targetRef)
{
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
{
const Agent* ag = m_crowd.getAgent(i);
if (!ag->active) continue;
m_crowd.adjustMoveTarget(i, m_targetRef, m_targetPos);
}
}
}
} }
void CrowdTool::handleStep() void CrowdTool::handleStep()

View File

@ -452,7 +452,7 @@ void imguiRenderGLDraw()
{ {
const float verts[3*2] = const float verts[3*2] =
{ {
(float)cmd.rect.x*s+0.5f, (float)cmd.rect.y*s+(float)cmd.rect.h*s-1, (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/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, (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,
}; };