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

View File

@ -141,7 +141,8 @@ public:
void optimizePath(const float* next, const float pathOptimizationRange,
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);
@ -250,6 +251,7 @@ class CrowdManager
static const int MAX_AGENTS = 128;
Agent m_agents[MAX_AGENTS];
dtObstacleAvoidanceDebugData* m_vodebug[MAX_AGENTS];
dtObstacleAvoidanceQuery* m_obstacleQuery;
PathQueue m_pathq;
ProximityGrid m_grid;
@ -266,19 +268,26 @@ class CrowdManager
enum MoveRequestState
{
MR_TARGET_FAILED,
MR_TARGET_VALID,
MR_TARGET_REQUESTING,
MR_TARGET_WAITING_FOR_PATH,
MR_TARGET_VALID,
MR_TARGET_FAILED,
MR_TARGET_ADJUST,
};
static const int MAX_TEMP_PATH = 32;
struct MoveRequest
{
int idx;
dtPolyRef ref;
float pos[3];
unsigned char state;
PathQueueRef pathqRef;
unsigned char state; // State of the request
int idx; // Agent index
dtPolyRef ref; // Goal ref
float pos[3]; // Goal position
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];
int m_moveRequestCount;
@ -295,10 +304,12 @@ public:
const int getAgentCount() const;
int addAgent(const float* pos, const float radius, const float height, dtNavMeshQuery* navquery);
void removeAgent(const int idx);
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);
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);
const dtQueryFilter* getFilter() const { return &m_filter; }

View File

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

View File

@ -190,7 +190,6 @@ int ProximityGrid::getItemCountAt(const int x, const int y) const
return n;
}
PathQueue::PathQueue() :
m_nextHandle(1),
m_delay(0)
@ -207,6 +206,7 @@ void PathQueue::update(dtNavMeshQuery* navquery)
{
// Artificial delay to test the code better,
// update only one request too.
// TODO: Use sliced pathfinder.
m_delay++;
if ((m_delay % 4) == 0)
@ -346,6 +346,44 @@ static int fixupCorridor(dtPolyRef* path, const int npath, const int maxPath,
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,
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.
float goal[3];
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 (distSqr < dtSqr(0.01f))
if (dist < 0.01f)
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.
if (distSqr > dtSqr(pathOptimizationRange))
{
float delta[3];
dtVsub(delta, goal, m_pos);
dtVmad(goal, m_pos, delta, dtSqr(pathOptimizationRange)/distSqr);
}
// Adjust ray length.
float delta[3];
dtVsub(delta, goal, m_pos);
dtVmad(goal, m_pos, delta, pathOptimizationRange/dist);
static const int MAX_RES = 32;
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_npath);
@ -512,13 +550,35 @@ void PathCorridor::updatePosition(const float* npos, dtNavMeshQuery* navquery, c
result, visited, MAX_VISITED);
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];
navquery->getPolyHeight(m_path[0], result, &h);
result[1] = h;
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)
{
dtAssert(m_path);
@ -859,6 +919,7 @@ bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float*
if (m_moveRequestCount >= MAX_AGENTS)
return false;
req = &m_moveRequests[m_moveRequestCount++];
memset(req, 0, sizeof(MoveRequest));
}
// Initialize request.
@ -868,6 +929,45 @@ bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float*
req->pathqRef = PATHQ_INVALID;
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;
}
@ -955,9 +1055,9 @@ int CrowdManager::getNeighbours(const float* pos, const float height, const floa
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)
{
MoveRequest* req = &m_moveRequests[i];
@ -967,6 +1067,33 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (!ag->active)
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)
{
// Calculate request position.
@ -991,7 +1118,19 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
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.
int state = m_pathq.getRequestState(req->pathqRef);
@ -1016,6 +1155,12 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (!nres)
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.
// The agent might have moved whilst the request is
// being processed, so the path may have changed.
@ -1056,7 +1201,7 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery)
if (valid)
{
ag->corridor.setCorridor(targetPos, res, nres);
req->state = MR_TARGET_FAILED;
req->state = MR_TARGET_VALID;
}
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)
{
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)
@ -1097,7 +1241,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
static const float MAX_SPEED = 3.5f;
// Update async move request and path finder.
updateMoveRequest(dt, navquery);
updateMoveRequest(dt, navquery, &m_filter);
// Register agents to proximity grid.
m_grid.clear();
@ -1306,7 +1450,7 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
{
Agent* ag = agents[i];
// Move along navmesh.
ag->corridor.updatePosition(ag->npos, navquery, &m_filter);
ag->corridor.movePosition(ag->npos, navquery, &m_filter);
// Get valid constrained position back.
dtVcopy(ag->npos, ag->corridor.getPos());
}

View File

@ -142,6 +142,8 @@ void CrowdTool::handleMenu()
m_mode = TOOLMODE_CREATE;
if (imguiCheck("Move Agents", m_mode == TOOLMODE_MOVE))
m_mode = TOOLMODE_MOVE;
if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET))
m_mode = TOOLMODE_MOVE_TARGET;
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()

View File

@ -452,7 +452,7 @@ void imguiRenderGLDraw()
{
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-1, (float)cmd.rect.y*s+0.5f+(float)cmd.rect.h*s-1,
};