- added finalizeSlicedFindPathPartial()
- added handleStep()/handleToggle() to samples - changed how crowds are rendered - added path topology optimization step
This commit is contained in:
parent
e5d603ac92
commit
ccf401d3da
@ -140,6 +140,9 @@ void duDebugDrawCross(struct duDebugDraw* dd, const float x, const float y, cons
|
|||||||
void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
float maxx, float maxy, float maxz, const unsigned int* fcol);
|
float maxx, float maxy, float maxz, const unsigned int* fcol);
|
||||||
|
|
||||||
|
void duDebugDrawCylinder(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
|
float maxx, float maxy, float maxz, unsigned int col);
|
||||||
|
|
||||||
void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz,
|
void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz,
|
||||||
const int w, const int h, const float size,
|
const int w, const int h, const float size,
|
||||||
const unsigned int col, const float lineWidth);
|
const unsigned int col, const float lineWidth);
|
||||||
@ -172,6 +175,9 @@ void duAppendCross(struct duDebugDraw* dd, const float x, const float y, const f
|
|||||||
void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
float maxx, float maxy, float maxz, const unsigned int* fcol);
|
float maxx, float maxy, float maxz, const unsigned int* fcol);
|
||||||
|
|
||||||
|
void duAppendCylinder(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
|
float maxx, float maxy, float maxz, unsigned int col);
|
||||||
|
|
||||||
|
|
||||||
class duDisplayList : public duDebugDraw
|
class duDisplayList : public duDebugDraw
|
||||||
{
|
{
|
||||||
|
@ -135,6 +135,16 @@ void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
|||||||
dd->end();
|
dd->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void duDebugDrawCylinder(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
|
float maxx, float maxy, float maxz, unsigned int col)
|
||||||
|
{
|
||||||
|
if (!dd) return;
|
||||||
|
|
||||||
|
dd->begin(DU_DRAW_TRIS);
|
||||||
|
duAppendCylinder(dd, minx,miny,minz, maxx,maxy,maxz, col);
|
||||||
|
dd->end();
|
||||||
|
}
|
||||||
|
|
||||||
void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz,
|
void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz,
|
||||||
const int w, const int h, const float size,
|
const int w, const int h, const float size,
|
||||||
const unsigned int col, const float lineWidth)
|
const unsigned int col, const float lineWidth)
|
||||||
@ -289,6 +299,58 @@ void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void duAppendCylinder(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||||
|
float maxx, float maxy, float maxz, unsigned int col)
|
||||||
|
{
|
||||||
|
if (!dd) return;
|
||||||
|
|
||||||
|
static const int NUM_SEG = 16;
|
||||||
|
static float dir[NUM_SEG*2];
|
||||||
|
static bool init = false;
|
||||||
|
if (!init)
|
||||||
|
{
|
||||||
|
init = true;
|
||||||
|
for (int i = 0; i < NUM_SEG; ++i)
|
||||||
|
{
|
||||||
|
const float a = (float)i/(float)NUM_SEG*DU_PI*2;
|
||||||
|
dir[i*2] = cosf(a);
|
||||||
|
dir[i*2+1] = sinf(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int col2 = duMultCol(col, 160);
|
||||||
|
|
||||||
|
const float cx = (maxx + minx)/2;
|
||||||
|
const float cz = (maxz + minz)/2;
|
||||||
|
const float rx = (maxx - minx)/2;
|
||||||
|
const float rz = (maxz - minz)/2;
|
||||||
|
|
||||||
|
for (int i = 2; i < NUM_SEG; ++i)
|
||||||
|
{
|
||||||
|
const int a = 0, b = i-1, c = i;
|
||||||
|
dd->vertex(cx+dir[a*2+0]*rx, miny, cz+dir[a*2+1]*rz, col2);
|
||||||
|
dd->vertex(cx+dir[b*2+0]*rx, miny, cz+dir[b*2+1]*rz, col2);
|
||||||
|
dd->vertex(cx+dir[c*2+0]*rx, miny, cz+dir[c*2+1]*rz, col2);
|
||||||
|
}
|
||||||
|
for (int i = 2; i < NUM_SEG; ++i)
|
||||||
|
{
|
||||||
|
const int a = 0, b = i, c = i-1;
|
||||||
|
dd->vertex(cx+dir[a*2+0]*rx, maxy, cz+dir[a*2+1]*rz, col);
|
||||||
|
dd->vertex(cx+dir[b*2+0]*rx, maxy, cz+dir[b*2+1]*rz, col);
|
||||||
|
dd->vertex(cx+dir[c*2+0]*rx, maxy, cz+dir[c*2+1]*rz, col);
|
||||||
|
}
|
||||||
|
for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++)
|
||||||
|
{
|
||||||
|
dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col2);
|
||||||
|
dd->vertex(cx+dir[j*2+0]*rx, miny, cz+dir[j*2+1]*rz, col2);
|
||||||
|
dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col);
|
||||||
|
|
||||||
|
dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col2);
|
||||||
|
dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col);
|
||||||
|
dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void evalArc(const float x0, const float y0, const float z0,
|
inline void evalArc(const float x0, const float y0, const float z0,
|
||||||
const float dx, const float dy, const float dz,
|
const float dx, const float dy, const float dz,
|
||||||
|
@ -72,9 +72,9 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (con)
|
if (con)
|
||||||
c = duRGBA(255,255,255,64);
|
c = duRGBA(255,255,255,24);
|
||||||
else
|
else
|
||||||
c = duRGBA(0,0,0,128);
|
c = duRGBA(0,0,0,48);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
c = duRGBA(0,48,64,32);
|
c = duRGBA(0,48,64,32);
|
||||||
|
@ -173,12 +173,22 @@ public:
|
|||||||
// Returns: Path query state.
|
// Returns: Path query state.
|
||||||
dtStatus updateSlicedFindPath(const int maxIter);
|
dtStatus updateSlicedFindPath(const int maxIter);
|
||||||
|
|
||||||
// Finalizes sliced path find query.
|
// Finalizes sliced path find query and returns found path.
|
||||||
// path - (out) array holding the search result.
|
// path - (out) array holding the search result.
|
||||||
// pathCount - (out) Number of polygons in search result array.
|
// pathCount - (out) Number of polygons in search result array.
|
||||||
// maxPath - (in) The max number of polygons the path array can hold.
|
// maxPath - (in) The max number of polygons the path array can hold.
|
||||||
dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath);
|
dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath);
|
||||||
|
|
||||||
|
// Finalizes partial sliced path find query and returns path to the furthest
|
||||||
|
// polygon on the existing path that was visited during the search.
|
||||||
|
// existing - (out) Array of polygons in the existing path.
|
||||||
|
// existingSize - (out) Number of polygons in existing path array.
|
||||||
|
// path - (out) array holding the search result.
|
||||||
|
// pathCount - (out) Number of polygons in search result array.
|
||||||
|
// maxPath - (in) The max number of polygons the path array can hold.
|
||||||
|
dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize,
|
||||||
|
dtPolyRef* path, int* pathCount, const int maxPath);
|
||||||
|
|
||||||
// Finds a straight path from start to end locations within the corridor
|
// Finds a straight path from start to end locations within the corridor
|
||||||
// described by the path polygons.
|
// described by the path polygons.
|
||||||
// Start and end locations will be clamped on the corridor.
|
// Start and end locations will be clamped on the corridor.
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
inline void operator=(const dtNodePool&) {}
|
inline void operator=(const dtNodePool&) {}
|
||||||
void clear();
|
void clear();
|
||||||
dtNode* getNode(dtPolyRef id);
|
dtNode* getNode(dtPolyRef id);
|
||||||
const dtNode* findNode(dtPolyRef id) const;
|
dtNode* findNode(dtPolyRef id);
|
||||||
|
|
||||||
inline unsigned int getNodeIdx(const dtNode* node) const
|
inline unsigned int getNodeIdx(const dtNode* node) const
|
||||||
{
|
{
|
||||||
|
@ -1015,6 +1015,75 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPath(dtPolyRef* path, int* pathCount,
|
|||||||
return DT_SUCCESS;
|
return DT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize,
|
||||||
|
dtPolyRef* path, int* pathCount, const int maxPath)
|
||||||
|
{
|
||||||
|
*pathCount = 0;
|
||||||
|
|
||||||
|
if (existingSize == 0)
|
||||||
|
{
|
||||||
|
return DT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_query.status != DT_SUCCESS && m_query.status != DT_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
// Reset query.
|
||||||
|
memset(&m_query, 0, sizeof(dtQueryData));
|
||||||
|
return DT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (m_query.startRef == m_query.endRef)
|
||||||
|
{
|
||||||
|
// Special case: the search starts and ends at same poly.
|
||||||
|
path[n++] = m_query.startRef;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find furthest existing node that was visited.
|
||||||
|
dtNode* prev = 0;
|
||||||
|
dtNode* node = 0;
|
||||||
|
for (int i = existingSize-1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
node = m_nodePool->findNode(existing[i]);
|
||||||
|
if (node)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
return DT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse the path.
|
||||||
|
do
|
||||||
|
{
|
||||||
|
dtNode* next = m_nodePool->getNodeAtIdx(node->pidx);
|
||||||
|
node->pidx = m_nodePool->getNodeIdx(prev);
|
||||||
|
prev = node;
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
while (node);
|
||||||
|
|
||||||
|
// Store path
|
||||||
|
node = prev;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
path[n++] = node->id;
|
||||||
|
node = m_nodePool->getNodeAtIdx(node->pidx);
|
||||||
|
}
|
||||||
|
while (node && n < maxPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset query.
|
||||||
|
memset(&m_query, 0, sizeof(dtQueryData));
|
||||||
|
|
||||||
|
*pathCount = n;
|
||||||
|
|
||||||
|
return DT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos,
|
dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos,
|
||||||
const dtPolyRef* path, const int pathSize,
|
const dtPolyRef* path, const int pathSize,
|
||||||
|
@ -70,7 +70,7 @@ void dtNodePool::clear()
|
|||||||
m_nodeCount = 0;
|
m_nodeCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dtNode* dtNodePool::findNode(dtPolyRef id) const
|
dtNode* dtNodePool::findNode(dtPolyRef id)
|
||||||
{
|
{
|
||||||
unsigned int bucket = dtHashRef(id) & (m_hashSize-1);
|
unsigned int bucket = dtHashRef(id) & (m_hashSize-1);
|
||||||
unsigned short i = m_first[bucket];
|
unsigned short i = m_first[bucket];
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -284,14 +284,14 @@
|
|||||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||||
<array>
|
<array>
|
||||||
<array>
|
<array>
|
||||||
<integer>59</integer>
|
<integer>52</integer>
|
||||||
<integer>51</integer>
|
<integer>51</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, 590}, {264, 660}}</string>
|
<string>{{0, 577}, {264, 622}}</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>PBXTopSmartGroupGIDs</key>
|
<key>PBXTopSmartGroupGIDs</key>
|
||||||
<array/>
|
<array/>
|
||||||
@ -301,14 +301,14 @@
|
|||||||
<key>GeometryConfiguration</key>
|
<key>GeometryConfiguration</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Frame</key>
|
<key>Frame</key>
|
||||||
<string>{{0, 0}, {281, 678}}</string>
|
<string>{{0, 0}, {281, 640}}</string>
|
||||||
<key>GroupTreeTableConfiguration</key>
|
<key>GroupTreeTableConfiguration</key>
|
||||||
<array>
|
<array>
|
||||||
<string>MainColumn</string>
|
<string>MainColumn</string>
|
||||||
<real>264</real>
|
<real>264</real>
|
||||||
</array>
|
</array>
|
||||||
<key>RubberWindowFrame</key>
|
<key>RubberWindowFrame</key>
|
||||||
<string>0 59 1278 719 0 0 1280 778 </string>
|
<string>47 97 1200 681 0 0 1280 778 </string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Module</key>
|
<key>Module</key>
|
||||||
<string>PBXSmartGroupTreeModule</string>
|
<string>PBXSmartGroupTreeModule</string>
|
||||||
@ -326,7 +326,7 @@
|
|||||||
<key>PBXProjectModuleGUID</key>
|
<key>PBXProjectModuleGUID</key>
|
||||||
<string>6B8632A30F78115100E2684A</string>
|
<string>6B8632A30F78115100E2684A</string>
|
||||||
<key>PBXProjectModuleLabel</key>
|
<key>PBXProjectModuleLabel</key>
|
||||||
<string>NavMeshTesterTool.cpp</string>
|
<string>CrowdTool.cpp</string>
|
||||||
<key>PBXSplitModuleInNavigatorKey</key>
|
<key>PBXSplitModuleInNavigatorKey</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Split0</key>
|
<key>Split0</key>
|
||||||
@ -334,29 +334,46 @@
|
|||||||
<key>PBXProjectModuleGUID</key>
|
<key>PBXProjectModuleGUID</key>
|
||||||
<string>6B8632A40F78115100E2684A</string>
|
<string>6B8632A40F78115100E2684A</string>
|
||||||
<key>PBXProjectModuleLabel</key>
|
<key>PBXProjectModuleLabel</key>
|
||||||
<string>NavMeshTesterTool.cpp</string>
|
<string>CrowdTool.cpp</string>
|
||||||
<key>_historyCapacity</key>
|
<key>_historyCapacity</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>bookmark</key>
|
<key>bookmark</key>
|
||||||
<string>6B8D56DA127AEC580077C699</string>
|
<string>6B74B7631286BB6900262888</string>
|
||||||
<key>history</key>
|
<key>history</key>
|
||||||
<array>
|
<array>
|
||||||
<string>6B8D565F127ADB0D0077C699</string>
|
<string>6B8D565F127ADB0D0077C699</string>
|
||||||
<string>6B8D566D127ADB7D0077C699</string>
|
|
||||||
<string>6B8D566F127ADB7D0077C699</string>
|
<string>6B8D566F127ADB7D0077C699</string>
|
||||||
<string>6B8D56C7127AEC100077C699</string>
|
<string>6B8D56C7127AEC100077C699</string>
|
||||||
<string>6B8D56C8127AEC100077C699</string>
|
|
||||||
<string>6B8D56C9127AEC100077C699</string>
|
|
||||||
<string>6B8D56CA127AEC100077C699</string>
|
|
||||||
<string>6B8D56CB127AEC100077C699</string>
|
|
||||||
<string>6B8D56CC127AEC100077C699</string>
|
|
||||||
<string>6B8D56CD127AEC100077C699</string>
|
|
||||||
<string>6B8D56CE127AEC100077C699</string>
|
|
||||||
<string>6B8D56CF127AEC100077C699</string>
|
|
||||||
<string>6B8D56D0127AEC100077C699</string>
|
|
||||||
<string>6B8D56D2127AEC100077C699</string>
|
<string>6B8D56D2127AEC100077C699</string>
|
||||||
<string>6B8D56D8127AEC580077C699</string>
|
<string>6B4DE62F12807542001CFDF4</string>
|
||||||
<string>6B8D56D9127AEC580077C699</string>
|
<string>6B4DE647128079E0001CFDF4</string>
|
||||||
|
<string>6B4DE649128079E0001CFDF4</string>
|
||||||
|
<string>6B4DE64A128079E0001CFDF4</string>
|
||||||
|
<string>6B74B5F3128312AC00262888</string>
|
||||||
|
<string>6B74B5F4128312AC00262888</string>
|
||||||
|
<string>6B74B60F128312E900262888</string>
|
||||||
|
<string>6B74B623128314A500262888</string>
|
||||||
|
<string>6B74B624128314A500262888</string>
|
||||||
|
<string>6B74B626128314A500262888</string>
|
||||||
|
<string>6B74B627128314A500262888</string>
|
||||||
|
<string>6B74B628128314A500262888</string>
|
||||||
|
<string>6B74B629128314A500262888</string>
|
||||||
|
<string>6B74B62A128314A500262888</string>
|
||||||
|
<string>6B74B62B128314A500262888</string>
|
||||||
|
<string>6B74B62C128314A500262888</string>
|
||||||
|
<string>6B74B66412869CE100262888</string>
|
||||||
|
<string>6B74B66712869CE100262888</string>
|
||||||
|
<string>6B74B66F12869E3000262888</string>
|
||||||
|
<string>6B74B6BF1286AA0C00262888</string>
|
||||||
|
<string>6B74B6D81286ABC000262888</string>
|
||||||
|
<string>6B74B6FC1286AE0B00262888</string>
|
||||||
|
<string>6B74B7061286AEBD00262888</string>
|
||||||
|
<string>6B74B7071286AEBD00262888</string>
|
||||||
|
<string>6B74B7401286B7C400262888</string>
|
||||||
|
<string>6B74B75F1286BB6900262888</string>
|
||||||
|
<string>6B74B7601286BB6900262888</string>
|
||||||
|
<string>6B74B7611286BB6900262888</string>
|
||||||
|
<string>6B74B7621286BB6900262888</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SplitCount</key>
|
<key>SplitCount</key>
|
||||||
@ -370,18 +387,18 @@
|
|||||||
<key>GeometryConfiguration</key>
|
<key>GeometryConfiguration</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Frame</key>
|
<key>Frame</key>
|
||||||
<string>{{0, 0}, {992, 434}}</string>
|
<string>{{0, 0}, {914, 472}}</string>
|
||||||
<key>RubberWindowFrame</key>
|
<key>RubberWindowFrame</key>
|
||||||
<string>0 59 1278 719 0 0 1280 778 </string>
|
<string>47 97 1200 681 0 0 1280 778 </string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Module</key>
|
<key>Module</key>
|
||||||
<string>PBXNavigatorGroup</string>
|
<string>PBXNavigatorGroup</string>
|
||||||
<key>Proportion</key>
|
<key>Proportion</key>
|
||||||
<string>434pt</string>
|
<string>472pt</string>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Proportion</key>
|
<key>Proportion</key>
|
||||||
<string>239pt</string>
|
<string>164pt</string>
|
||||||
<key>Tabs</key>
|
<key>Tabs</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
@ -395,7 +412,7 @@
|
|||||||
<key>GeometryConfiguration</key>
|
<key>GeometryConfiguration</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Frame</key>
|
<key>Frame</key>
|
||||||
<string>{{10, 27}, {992, -27}}</string>
|
<string>{{10, 27}, {992, 49}}</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Module</key>
|
<key>Module</key>
|
||||||
<string>XCDetailModule</string>
|
<string>XCDetailModule</string>
|
||||||
@ -411,7 +428,7 @@
|
|||||||
<key>GeometryConfiguration</key>
|
<key>GeometryConfiguration</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Frame</key>
|
<key>Frame</key>
|
||||||
<string>{{10, 27}, {992, 212}}</string>
|
<string>{{10, 27}, {992, 169}}</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Module</key>
|
<key>Module</key>
|
||||||
<string>PBXProjectFindModule</string>
|
<string>PBXProjectFindModule</string>
|
||||||
@ -449,9 +466,9 @@
|
|||||||
<key>GeometryConfiguration</key>
|
<key>GeometryConfiguration</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Frame</key>
|
<key>Frame</key>
|
||||||
<string>{{10, 27}, {992, 212}}</string>
|
<string>{{10, 27}, {914, 137}}</string>
|
||||||
<key>RubberWindowFrame</key>
|
<key>RubberWindowFrame</key>
|
||||||
<string>0 59 1278 719 0 0 1280 778 </string>
|
<string>47 97 1200 681 0 0 1280 778 </string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Module</key>
|
<key>Module</key>
|
||||||
<string>PBXBuildResultsModule</string>
|
<string>PBXBuildResultsModule</string>
|
||||||
@ -460,7 +477,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>Proportion</key>
|
<key>Proportion</key>
|
||||||
<string>992pt</string>
|
<string>914pt</string>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>Name</key>
|
<key>Name</key>
|
||||||
@ -479,11 +496,11 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>TableOfContents</key>
|
<key>TableOfContents</key>
|
||||||
<array>
|
<array>
|
||||||
<string>6B8D5625127AD44A0077C699</string>
|
<string>6B74B5DD1283104100262888</string>
|
||||||
<string>1CA23ED40692098700951B8B</string>
|
<string>1CA23ED40692098700951B8B</string>
|
||||||
<string>6B8D5626127AD44A0077C699</string>
|
<string>6B74B5DE1283104100262888</string>
|
||||||
<string>6B8632A30F78115100E2684A</string>
|
<string>6B8632A30F78115100E2684A</string>
|
||||||
<string>6B8D5627127AD44A0077C699</string>
|
<string>6B74B5DF1283104100262888</string>
|
||||||
<string>1CA23EDF0692099D00951B8B</string>
|
<string>1CA23EDF0692099D00951B8B</string>
|
||||||
<string>1CA23EE00692099D00951B8B</string>
|
<string>1CA23EE00692099D00951B8B</string>
|
||||||
<string>1CA23EE10692099D00951B8B</string>
|
<string>1CA23EE10692099D00951B8B</string>
|
||||||
@ -631,14 +648,14 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>TableOfContents</key>
|
<key>TableOfContents</key>
|
||||||
<array>
|
<array>
|
||||||
<string>6B8D563A127AD6CA0077C699</string>
|
<string>6B74B5FD128312AC00262888</string>
|
||||||
<string>1CCC7628064C1048000F2A68</string>
|
<string>1CCC7628064C1048000F2A68</string>
|
||||||
<string>1CCC7629064C1048000F2A68</string>
|
<string>1CCC7629064C1048000F2A68</string>
|
||||||
<string>6B8D563B127AD6CA0077C699</string>
|
<string>6B74B5FE128312AC00262888</string>
|
||||||
<string>6B8D563C127AD6CA0077C699</string>
|
<string>6B74B5FF128312AC00262888</string>
|
||||||
<string>6B8D563D127AD6CA0077C699</string>
|
<string>6B74B600128312AC00262888</string>
|
||||||
<string>6B8D563E127AD6CA0077C699</string>
|
<string>6B74B601128312AC00262888</string>
|
||||||
<string>6B8D563F127AD6CA0077C699</string>
|
<string>6B74B602128312AC00262888</string>
|
||||||
</array>
|
</array>
|
||||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||||
<string>2</string>
|
<string>2</string>
|
||||||
@ -670,13 +687,12 @@
|
|||||||
<integer>5</integer>
|
<integer>5</integer>
|
||||||
<key>WindowOrderList</key>
|
<key>WindowOrderList</key>
|
||||||
<array>
|
<array>
|
||||||
<string>6B8D56D5127AEC100077C699</string>
|
<string>6B74B604128312AC00262888</string>
|
||||||
<string>6B8D56D6127AEC100077C699</string>
|
<string>6B74B605128312AC00262888</string>
|
||||||
<string>6B8D56D7127AEC100077C699</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>
|
||||||
<string>0 59 1278 719 0 0 1280 778 </string>
|
<string>47 97 1200 681 0 0 1280 778 </string>
|
||||||
<key>WindowToolsV3</key>
|
<key>WindowToolsV3</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void handleMenu();
|
virtual void handleMenu();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
|
virtual void handleToggle();
|
||||||
virtual void handleStep();
|
virtual void handleStep();
|
||||||
virtual void handleUpdate(const float dt);
|
virtual void handleUpdate(const float dt);
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
|
@ -138,8 +138,10 @@ public:
|
|||||||
dtPolyRef* cornerPolys, const int maxCorners,
|
dtPolyRef* cornerPolys, const int maxCorners,
|
||||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
|
|
||||||
void optimizePath(const float* next, const float pathOptimizationRange,
|
void optimizePathVisibility(const float* next, const float pathOptimizationRange,
|
||||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
|
|
||||||
|
bool optimizePathTopology(dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
|
|
||||||
void movePosition(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 moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
@ -216,6 +218,8 @@ struct Agent
|
|||||||
float collisionQueryRange;
|
float collisionQueryRange;
|
||||||
float pathOptimizationRange;
|
float pathOptimizationRange;
|
||||||
|
|
||||||
|
float topologyOptTime;
|
||||||
|
|
||||||
Neighbour neis[AGENT_MAX_NEIGHBOURS];
|
Neighbour neis[AGENT_MAX_NEIGHBOURS];
|
||||||
int nneis;
|
int nneis;
|
||||||
|
|
||||||
@ -243,6 +247,8 @@ enum UpdateFlags
|
|||||||
CROWDMAN_ANTICIPATE_TURNS = 1,
|
CROWDMAN_ANTICIPATE_TURNS = 1,
|
||||||
CROWDMAN_USE_VO = 2,
|
CROWDMAN_USE_VO = 2,
|
||||||
CROWDMAN_DRUNK = 4,
|
CROWDMAN_DRUNK = 4,
|
||||||
|
CROWDMAN_OPTIMIZE_VIS = 8,
|
||||||
|
CROWDMAN_OPTIMIZE_TOPO = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -295,6 +301,9 @@ class CrowdManager
|
|||||||
int getNeighbours(const float* pos, const float height, const float range,
|
int getNeighbours(const float* pos, const float height, const float range,
|
||||||
const Agent* skip, Neighbour* result, const int maxResult);
|
const Agent* skip, Neighbour* result, const int maxResult);
|
||||||
|
|
||||||
|
void updateTopologyOptimization(const float dt, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
|
void updateMoveRequest(const float dt, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CrowdManager();
|
CrowdManager();
|
||||||
~CrowdManager();
|
~CrowdManager();
|
||||||
@ -307,9 +316,8 @@ public:
|
|||||||
|
|
||||||
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);
|
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, 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; }
|
||||||
|
@ -44,9 +44,13 @@ class CrowdTool : public SampleTool
|
|||||||
bool m_showVO;
|
bool m_showVO;
|
||||||
bool m_showOpt;
|
bool m_showOpt;
|
||||||
bool m_showGrid;
|
bool m_showGrid;
|
||||||
|
bool m_showNodes;
|
||||||
|
bool m_showPerfGraph;
|
||||||
|
|
||||||
bool m_expandOptions;
|
bool m_expandOptions;
|
||||||
bool m_anticipateTurns;
|
bool m_anticipateTurns;
|
||||||
|
bool m_optimizeVis;
|
||||||
|
bool m_optimizeTopo;
|
||||||
bool m_useVO;
|
bool m_useVO;
|
||||||
bool m_drunkMove;
|
bool m_drunkMove;
|
||||||
|
|
||||||
@ -74,6 +78,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void handleMenu();
|
virtual void handleMenu();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
|
virtual void handleToggle();
|
||||||
virtual void handleStep();
|
virtual void handleStep();
|
||||||
virtual void handleUpdate(const float dt);
|
virtual void handleUpdate(const float dt);
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
|
@ -93,6 +93,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void handleMenu();
|
virtual void handleMenu();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
|
virtual void handleToggle();
|
||||||
virtual void handleStep();
|
virtual void handleStep();
|
||||||
virtual void handleUpdate(const float dt);
|
virtual void handleUpdate(const float dt);
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void handleMenu();
|
virtual void handleMenu();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
|
virtual void handleToggle();
|
||||||
virtual void handleStep();
|
virtual void handleStep();
|
||||||
virtual void handleUpdate(const float dt);
|
virtual void handleUpdate(const float dt);
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
|
@ -65,6 +65,7 @@ struct SampleTool
|
|||||||
virtual void handleClick(const float* s, const float* p, bool shift) = 0;
|
virtual void handleClick(const float* s, const float* p, bool shift) = 0;
|
||||||
virtual void handleRender() = 0;
|
virtual void handleRender() = 0;
|
||||||
virtual void handleRenderOverlay(double* proj, double* model, int* view) = 0;
|
virtual void handleRenderOverlay(double* proj, double* model, int* view) = 0;
|
||||||
|
virtual void handleToggle() = 0;
|
||||||
virtual void handleStep() = 0;
|
virtual void handleStep() = 0;
|
||||||
virtual void handleUpdate(const float dt) = 0;
|
virtual void handleUpdate(const float dt) = 0;
|
||||||
};
|
};
|
||||||
@ -108,6 +109,7 @@ public:
|
|||||||
virtual void handleTools();
|
virtual void handleTools();
|
||||||
virtual void handleDebugMode();
|
virtual void handleDebugMode();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
|
virtual void handleToggle();
|
||||||
virtual void handleStep();
|
virtual void handleStep();
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
virtual void handleTools();
|
virtual void handleTools();
|
||||||
virtual void handleDebugMode();
|
virtual void handleDebugMode();
|
||||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||||
virtual void handleStep();
|
virtual void handleToggle();
|
||||||
virtual void handleRender();
|
virtual void handleRender();
|
||||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||||
virtual void handleMeshChanged(class InputGeom* geom);
|
virtual void handleMeshChanged(class InputGeom* geom);
|
||||||
|
@ -230,6 +230,10 @@ void ConvexVolumeTool::handleClick(const float* /*s*/, const float* p, bool shif
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConvexVolumeTool::handleToggle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ConvexVolumeTool::handleStep()
|
void ConvexVolumeTool::handleStep()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -506,8 +506,8 @@ int PathCorridor::findCorners(float* cornerVerts, unsigned char* cornerFlags,
|
|||||||
return ncorners;
|
return ncorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathCorridor::optimizePath(const float* next, const float pathOptimizationRange,
|
void PathCorridor::optimizePathVisibility(const float* next, const float pathOptimizationRange,
|
||||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||||
{
|
{
|
||||||
dtAssert(m_path);
|
dtAssert(m_path);
|
||||||
|
|
||||||
@ -539,6 +539,31 @@ void PathCorridor::optimizePath(const float* next, const float pathOptimizationR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PathCorridor::optimizePathTopology(dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||||
|
{
|
||||||
|
dtAssert(m_path);
|
||||||
|
|
||||||
|
if (m_npath < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
static const int MAX_ITER = 32;
|
||||||
|
static const int MAX_RES = 32;
|
||||||
|
|
||||||
|
dtPolyRef res[MAX_RES];
|
||||||
|
int nres = 0;
|
||||||
|
navquery->initSlicedFindPath(m_path[0], m_path[m_npath-1], m_pos, m_target, filter);
|
||||||
|
navquery->updateSlicedFindPath(MAX_ITER);
|
||||||
|
dtStatus status = navquery->finalizeSlicedFindPathPartial(m_path, m_npath, res, &nres, MAX_RES);
|
||||||
|
|
||||||
|
if (status == DT_SUCCESS && nres > 0)
|
||||||
|
{
|
||||||
|
m_npath = mergeCorridor(m_path, m_npath, m_maxPath, res, nres);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void PathCorridor::movePosition(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);
|
||||||
@ -876,6 +901,7 @@ int CrowdManager::addAgent(const float* pos, const float radius, const float hei
|
|||||||
ag->height = height;
|
ag->height = height;
|
||||||
ag->collisionQueryRange = radius * 8;
|
ag->collisionQueryRange = radius * 8;
|
||||||
ag->pathOptimizationRange = radius * 30;
|
ag->pathOptimizationRange = radius * 30;
|
||||||
|
ag->topologyOptTime = 0;
|
||||||
ag->nneis = 0;
|
ag->nneis = 0;
|
||||||
|
|
||||||
dtVset(ag->dvel, 0,0,0);
|
dtVset(ag->dvel, 0,0,0);
|
||||||
@ -901,7 +927,9 @@ int CrowdManager::addAgent(const float* pos, const float radius, const float hei
|
|||||||
void CrowdManager::removeAgent(const int idx)
|
void CrowdManager::removeAgent(const int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx < MAX_AGENTS)
|
if (idx >= 0 && idx < MAX_AGENTS)
|
||||||
memset(&m_agents[idx], 0, sizeof(Agent));
|
{
|
||||||
|
m_agents[idx].active = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float* pos)
|
bool CrowdManager::requestMoveTarget(const int idx, dtPolyRef ref, const float* pos)
|
||||||
@ -1231,6 +1259,76 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery, c
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int addToOptQueue(Agent* newag, Agent** agents, const int nagents, const int maxAgents)
|
||||||
|
{
|
||||||
|
// Insert neighbour based on greatest time.
|
||||||
|
int slot = 0;
|
||||||
|
if (!nagents)
|
||||||
|
{
|
||||||
|
slot = nagents;
|
||||||
|
}
|
||||||
|
else if (newag->topologyOptTime <= agents[nagents-1]->topologyOptTime)
|
||||||
|
{
|
||||||
|
if (nagents >= maxAgents)
|
||||||
|
return nagents;
|
||||||
|
slot = nagents;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nagents; ++i)
|
||||||
|
if (newag->topologyOptTime >= agents[i]->topologyOptTime)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int tgt = i+1;
|
||||||
|
const int n = dtMin(nagents-i, maxAgents-tgt);
|
||||||
|
|
||||||
|
dtAssert(tgt+n <= maxAgents);
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
memmove(&agents[tgt], &agents[i], sizeof(Agent*)*n);
|
||||||
|
slot = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
agents[slot] = newag;
|
||||||
|
|
||||||
|
return dtMin(nagents+1, maxAgents);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrowdManager::updateTopologyOptimization(const float dt, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||||
|
{
|
||||||
|
Agent* agents[MAX_AGENTS];
|
||||||
|
int nagents = getActiveAgents(agents, MAX_AGENTS);
|
||||||
|
if (!nagents)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const float OPT_TIME_THR = 0.5f; // seconds
|
||||||
|
const int OPT_MAX_AGENTS = 1;
|
||||||
|
|
||||||
|
Agent* queue[OPT_MAX_AGENTS];
|
||||||
|
int nqueue = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nagents; ++i)
|
||||||
|
{
|
||||||
|
Agent* ag = agents[i];
|
||||||
|
ag->topologyOptTime += dt;
|
||||||
|
if (ag->topologyOptTime >= OPT_TIME_THR)
|
||||||
|
{
|
||||||
|
nqueue = addToOptQueue(ag, queue, nqueue, OPT_MAX_AGENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nqueue; ++i)
|
||||||
|
{
|
||||||
|
Agent* ag = queue[i];
|
||||||
|
ag->corridor.optimizePathTopology(navquery, filter);
|
||||||
|
ag->topologyOptTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* navquery)
|
void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* navquery)
|
||||||
{
|
{
|
||||||
m_sampleCount = 0;
|
m_sampleCount = 0;
|
||||||
@ -1251,6 +1349,10 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
|||||||
// Update async move request and path finder.
|
// Update async move request and path finder.
|
||||||
updateMoveRequest(dt, navquery, &m_filter);
|
updateMoveRequest(dt, navquery, &m_filter);
|
||||||
|
|
||||||
|
// Optimize path topology.
|
||||||
|
if (flags & CROWDMAN_OPTIMIZE_TOPO)
|
||||||
|
updateTopologyOptimization(dt, navquery, &m_filter);
|
||||||
|
|
||||||
// Register agents to proximity grid.
|
// Register agents to proximity grid.
|
||||||
m_grid.clear();
|
m_grid.clear();
|
||||||
for (int i = 0; i < nagents; ++i)
|
for (int i = 0; i < nagents; ++i)
|
||||||
@ -1283,12 +1385,12 @@ void CrowdManager::update(const float dt, unsigned int flags, dtNavMeshQuery* na
|
|||||||
|
|
||||||
// Check to see if the corner after the next corner is directly visible,
|
// Check to see if the corner after the next corner is directly visible,
|
||||||
// and short cut to there.
|
// and short cut to there.
|
||||||
if (ag->ncorners > 0)
|
if ((flags & CROWDMAN_OPTIMIZE_VIS) && ag->ncorners > 0)
|
||||||
{
|
{
|
||||||
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
|
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
|
||||||
dtVcopy(ag->opts, ag->corridor.getPos());
|
dtVcopy(ag->opts, ag->corridor.getPos());
|
||||||
dtVcopy(ag->opte, target);
|
dtVcopy(ag->opte, target);
|
||||||
ag->corridor.optimizePath(target, ag->pathOptimizationRange, navquery, &m_filter);
|
ag->corridor.optimizePathVisibility(target, ag->pathOptimizationRange, navquery, &m_filter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ CrowdTool::CrowdTool() :
|
|||||||
m_oldFlags(0),
|
m_oldFlags(0),
|
||||||
m_targetRef(0),
|
m_targetRef(0),
|
||||||
m_expandDebugDraw(false),
|
m_expandDebugDraw(false),
|
||||||
m_showLabels(true),
|
m_showLabels(false),
|
||||||
m_showCorners(false),
|
m_showCorners(false),
|
||||||
m_showTargets(false),
|
m_showTargets(false),
|
||||||
m_showCollisionSegments(false),
|
m_showCollisionSegments(false),
|
||||||
@ -103,8 +103,12 @@ CrowdTool::CrowdTool() :
|
|||||||
m_showVO(false),
|
m_showVO(false),
|
||||||
m_showOpt(false),
|
m_showOpt(false),
|
||||||
m_showGrid(false),
|
m_showGrid(false),
|
||||||
|
m_showNodes(false),
|
||||||
|
m_showPerfGraph(false),
|
||||||
m_expandOptions(true),
|
m_expandOptions(true),
|
||||||
m_anticipateTurns(true),
|
m_anticipateTurns(true),
|
||||||
|
m_optimizeVis(true),
|
||||||
|
m_optimizeTopo(true),
|
||||||
m_useVO(true),
|
m_useVO(true),
|
||||||
m_drunkMove(false),
|
m_drunkMove(false),
|
||||||
m_run(true),
|
m_run(true),
|
||||||
@ -168,6 +172,10 @@ void CrowdTool::handleMenu()
|
|||||||
if (m_expandOptions)
|
if (m_expandOptions)
|
||||||
{
|
{
|
||||||
imguiIndent();
|
imguiIndent();
|
||||||
|
if (imguiCheck("Optimize Visibility", m_optimizeVis))
|
||||||
|
m_optimizeVis = !m_optimizeVis;
|
||||||
|
if (imguiCheck("Optimize Topology", m_optimizeTopo))
|
||||||
|
m_optimizeTopo = !m_optimizeTopo;
|
||||||
if (imguiCheck("Anticipate Turns", m_anticipateTurns))
|
if (imguiCheck("Anticipate Turns", m_anticipateTurns))
|
||||||
m_anticipateTurns = !m_anticipateTurns;
|
m_anticipateTurns = !m_anticipateTurns;
|
||||||
if (imguiCheck("Use VO", m_useVO))
|
if (imguiCheck("Use VO", m_useVO))
|
||||||
@ -199,6 +207,10 @@ void CrowdTool::handleMenu()
|
|||||||
m_showOpt = !m_showOpt;
|
m_showOpt = !m_showOpt;
|
||||||
if (imguiCheck("Show Prox Grid", m_showGrid))
|
if (imguiCheck("Show Prox Grid", m_showGrid))
|
||||||
m_showGrid = !m_showGrid;
|
m_showGrid = !m_showGrid;
|
||||||
|
if (imguiCheck("Show Nodes", m_showNodes))
|
||||||
|
m_showNodes = !m_showNodes;
|
||||||
|
if (imguiCheck("Show Perf Graph", m_showPerfGraph))
|
||||||
|
m_showPerfGraph = !m_showPerfGraph;
|
||||||
imguiUnindent();
|
imguiUnindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,6 +292,10 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CrowdTool::handleStep()
|
void CrowdTool::handleStep()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrowdTool::handleToggle()
|
||||||
{
|
{
|
||||||
m_run = !m_run;
|
m_run = !m_run;
|
||||||
}
|
}
|
||||||
@ -298,6 +314,10 @@ void CrowdTool::handleUpdate(const float dt)
|
|||||||
flags |= CROWDMAN_USE_VO;
|
flags |= CROWDMAN_USE_VO;
|
||||||
if (m_drunkMove)
|
if (m_drunkMove)
|
||||||
flags |= CROWDMAN_DRUNK;
|
flags |= CROWDMAN_DRUNK;
|
||||||
|
if (m_optimizeVis)
|
||||||
|
flags |= CROWDMAN_OPTIMIZE_VIS;
|
||||||
|
if (m_optimizeTopo)
|
||||||
|
flags |= CROWDMAN_OPTIMIZE_TOPO;
|
||||||
|
|
||||||
m_crowd.update(dt, flags, m_sample->getNavMeshQuery());
|
m_crowd.update(dt, flags, m_sample->getNavMeshQuery());
|
||||||
|
|
||||||
@ -315,33 +335,76 @@ void CrowdTool::handleRender()
|
|||||||
dtNavMesh* nmesh = m_sample->getNavMesh();
|
dtNavMesh* nmesh = m_sample->getNavMesh();
|
||||||
if (!nmesh)
|
if (!nmesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
dtNavMeshQuery* navquery = m_sample->getNavMeshQuery();
|
||||||
|
|
||||||
|
if (m_showNodes)
|
||||||
|
{
|
||||||
|
if (navquery)
|
||||||
|
duDebugDrawNavMeshNodes(&dd, *navquery);
|
||||||
|
}
|
||||||
|
|
||||||
|
dd.depthMask(false);
|
||||||
|
|
||||||
|
// Draw paths
|
||||||
|
if (m_showPath)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
|
const dtPolyRef* path = ag->corridor.getPath();
|
||||||
|
const int npath = ag->corridor.getPathCount();
|
||||||
|
for (int i = 0; i < npath; ++i)
|
||||||
|
duDebugDrawNavMeshPoly(&dd, *nmesh, path[i], duRGBA(0,0,0,32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_targetRef)
|
if (m_targetRef)
|
||||||
duDebugDrawCross(&dd, m_targetPos[0],m_targetPos[1]+0.1f,m_targetPos[2], s, duRGBA(0,0,0,128), 2.0f);
|
duDebugDrawCross(&dd, m_targetPos[0],m_targetPos[1]+0.1f,m_targetPos[2], s, duRGBA(255,255,255,192), 2.0f);
|
||||||
|
|
||||||
|
// Occupancy grid.
|
||||||
|
if (m_showGrid)
|
||||||
|
{
|
||||||
|
float gridy = -FLT_MAX;
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
const float* pos = ag->corridor.getPos();
|
||||||
|
gridy = dtMax(gridy, pos[1]);
|
||||||
|
}
|
||||||
|
gridy += 1.0f;
|
||||||
|
|
||||||
|
dd.begin(DU_DRAW_QUADS);
|
||||||
|
const ProximityGrid* grid = m_crowd.getGrid();
|
||||||
|
const int* bounds = grid->getBounds();
|
||||||
|
const float cs = grid->getCellSize();
|
||||||
|
for (int y = bounds[1]; y <= bounds[3]; ++y)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dd.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trail
|
||||||
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
{
|
{
|
||||||
const Agent* ag = m_crowd.getAgent(i);
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
if (!ag->active) continue;
|
if (!ag->active) continue;
|
||||||
|
|
||||||
const float height = ag->height;
|
|
||||||
const float radius = ag->radius;
|
|
||||||
const float* pos = ag->npos;
|
const float* pos = ag->npos;
|
||||||
const float* target = ag->corridor.getTarget();
|
|
||||||
const float* vel = ag->vel;
|
|
||||||
const float* dvel = ag->dvel;
|
|
||||||
|
|
||||||
dd.depthMask(false);
|
|
||||||
|
|
||||||
if (m_showPath)
|
|
||||||
{
|
|
||||||
const dtPolyRef* path = ag->corridor.getPath();
|
|
||||||
const int npath = ag->corridor.getPathCount();
|
|
||||||
for (int i = 0; i < npath; ++i)
|
|
||||||
duDebugDrawNavMeshPoly(&dd, *nmesh, path[i], duRGBA(0,0,0,64));
|
|
||||||
}
|
|
||||||
|
|
||||||
dd.begin(DU_DRAW_LINES,3.0f);
|
dd.begin(DU_DRAW_LINES,3.0f);
|
||||||
float prev[3], preva = 1;
|
float prev[3], preva = 1;
|
||||||
dtVcopy(prev, pos);
|
dtVcopy(prev, pos);
|
||||||
@ -356,13 +419,18 @@ void CrowdTool::handleRender()
|
|||||||
dtVcopy(prev, v);
|
dtVcopy(prev, v);
|
||||||
}
|
}
|
||||||
dd.end();
|
dd.end();
|
||||||
|
|
||||||
if (m_showTargets)
|
|
||||||
{
|
|
||||||
duDebugDrawArc(&dd, pos[0], pos[1], pos[2], target[0], target[1], target[2],
|
|
||||||
0.25f, 0, 0.4f, duRGBA(0,0,0,128), 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Corners & co
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
|
const float radius = ag->radius;
|
||||||
|
const float* pos = ag->npos;
|
||||||
|
|
||||||
if (m_showCorners)
|
if (m_showCorners)
|
||||||
{
|
{
|
||||||
if (ag->ncorners)
|
if (ag->ncorners)
|
||||||
@ -372,32 +440,32 @@ void CrowdTool::handleRender()
|
|||||||
{
|
{
|
||||||
const float* va = j == 0 ? pos : &ag->cornerVerts[(j-1)*3];
|
const float* va = j == 0 ? pos : &ag->cornerVerts[(j-1)*3];
|
||||||
const float* vb = &ag->cornerVerts[j*3];
|
const float* vb = &ag->cornerVerts[j*3];
|
||||||
dd.vertex(va[0],va[1]+radius,va[2], duRGBA(128,0,0,64));
|
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,64));
|
dd.vertex(vb[0],vb[1]+radius,vb[2], duRGBA(128,0,0,192));
|
||||||
}
|
}
|
||||||
dd.end();
|
dd.end();
|
||||||
|
|
||||||
if (m_anticipateTurns)
|
if (m_anticipateTurns)
|
||||||
{
|
{
|
||||||
/* float dvel[3], pos[3];
|
/* float dvel[3], pos[3];
|
||||||
calcSmoothSteerDirection(ag->pos, ag->cornerVerts, ag->ncorners, dvel);
|
calcSmoothSteerDirection(ag->pos, ag->cornerVerts, ag->ncorners, dvel);
|
||||||
pos[0] = ag->pos[0] + dvel[0];
|
pos[0] = ag->pos[0] + dvel[0];
|
||||||
pos[1] = ag->pos[1] + dvel[1];
|
pos[1] = ag->pos[1] + dvel[1];
|
||||||
pos[2] = ag->pos[2] + dvel[2];
|
pos[2] = ag->pos[2] + dvel[2];
|
||||||
|
|
||||||
const float off = ag->radius+0.1f;
|
const float off = ag->radius+0.1f;
|
||||||
const float* tgt = &ag->cornerVerts[0];
|
const float* tgt = &ag->cornerVerts[0];
|
||||||
const float y = ag->pos[1]+off;
|
const float y = ag->pos[1]+off;
|
||||||
|
|
||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||||
|
|
||||||
dd.vertex(ag->pos[0],y,ag->pos[2], duRGBA(255,0,0,192));
|
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(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.vertex(tgt[0],y,tgt[2], duRGBA(255,0,0,192));
|
||||||
|
|
||||||
dd.end();*/
|
dd.end();*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -408,7 +476,7 @@ void CrowdTool::handleRender()
|
|||||||
duDebugDrawCross(&dd, center[0],center[1]+radius,center[2], 0.2f, duRGBA(192,0,128,255), 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->collisionQueryRange,
|
duDebugDrawCircle(&dd, center[0],center[1]+radius,center[2], ag->collisionQueryRange,
|
||||||
duRGBA(192,0,128,128), 2.0f);
|
duRGBA(192,0,128,128), 2.0f);
|
||||||
|
|
||||||
dd.begin(DU_DRAW_LINES, 3.0f);
|
dd.begin(DU_DRAW_LINES, 3.0f);
|
||||||
for (int j = 0; j < ag->boundary.getSegmentCount(); ++j)
|
for (int j = 0; j < ag->boundary.getSegmentCount(); ++j)
|
||||||
{
|
{
|
||||||
@ -421,7 +489,7 @@ void CrowdTool::handleRender()
|
|||||||
}
|
}
|
||||||
dd.end();
|
dd.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_showOpt)
|
if (m_showOpt)
|
||||||
{
|
{
|
||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||||
@ -429,6 +497,48 @@ void CrowdTool::handleRender()
|
|||||||
dd.vertex(ag->opte[0],ag->opte[1]+0.3f,ag->opte[2], duRGBA(0,128,0,192));
|
dd.vertex(ag->opte[0],ag->opte[1]+0.3f,ag->opte[2], duRGBA(0,128,0,192));
|
||||||
dd.end();
|
dd.end();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent cylinders.
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
|
const float radius = ag->radius;
|
||||||
|
const float* pos = ag->npos;
|
||||||
|
|
||||||
|
duDebugDrawCircle(&dd, pos[0], pos[1], pos[2], radius, duRGBA(0,0,0,32), 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
|
const float height = ag->height;
|
||||||
|
const float radius = ag->radius;
|
||||||
|
const float* pos = ag->npos;
|
||||||
|
|
||||||
|
duDebugDrawCylinder(&dd, pos[0]-radius, pos[1]+radius*0.1f, pos[2]-radius,
|
||||||
|
pos[0]+radius, pos[1]+height, pos[2]+radius,
|
||||||
|
duRGBA(220,220,220,128));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Velocity stuff.
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
|
const float radius = ag->radius;
|
||||||
|
const float height = ag->height;
|
||||||
|
const float* pos = ag->npos;
|
||||||
|
const float* vel = ag->vel;
|
||||||
|
const float* dvel = ag->dvel;
|
||||||
|
|
||||||
|
duDebugDrawCircle(&dd, pos[0], pos[1]+height, pos[2], radius, duRGBA(220,220,220,192), 2.0f);
|
||||||
|
|
||||||
if (m_showVO)
|
if (m_showVO)
|
||||||
{
|
{
|
||||||
@ -458,138 +568,31 @@ void CrowdTool::handleRender()
|
|||||||
}
|
}
|
||||||
|
|
||||||
duDebugDrawArrow(&dd, pos[0],pos[1]+height,pos[2],
|
duDebugDrawArrow(&dd, pos[0],pos[1]+height,pos[2],
|
||||||
pos[0]+vel[0],pos[1]+height+vel[1],pos[2]+vel[2],
|
pos[0]+dvel[0],pos[1]+height+dvel[1],pos[2]+dvel[2],
|
||||||
0.0f, 0.4f, duRGBA(0,0,0,192), 2.0f);
|
|
||||||
|
|
||||||
duDebugDrawArrow(&dd, pos[0],pos[1]+height-0.1f,pos[2],
|
|
||||||
pos[0]+dvel[0],pos[1]+height-0.1f+dvel[1],pos[2]+dvel[2],
|
|
||||||
0.0f, 0.4f, duRGBA(0,192,255,192), 1.0f);
|
0.0f, 0.4f, duRGBA(0,192,255,192), 1.0f);
|
||||||
|
|
||||||
duDebugDrawCylinderWire(&dd, pos[0]-radius, pos[1]+radius*0.1f, pos[2]-radius,
|
duDebugDrawArrow(&dd, pos[0],pos[1]+height,pos[2],
|
||||||
pos[0]+radius, pos[1]+height, pos[2]+radius,
|
pos[0]+vel[0],pos[1]+height+vel[1],pos[2]+vel[2],
|
||||||
duRGBA(0,192,255,255), 3.0f);
|
0.0f, 0.4f, duRGBA(0,0,0,192), 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Targets
|
||||||
|
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
||||||
|
{
|
||||||
|
const Agent* ag = m_crowd.getAgent(i);
|
||||||
|
if (!ag->active) continue;
|
||||||
|
|
||||||
dd.depthMask(true);
|
const float* pos = ag->npos;
|
||||||
}
|
const float* target = ag->corridor.getTarget();
|
||||||
|
|
||||||
if (m_showGrid)
|
if (m_showTargets)
|
||||||
{
|
|
||||||
float gridy = -FLT_MAX;
|
|
||||||
for (int i = 0; i < m_crowd.getAgentCount(); ++i)
|
|
||||||
{
|
{
|
||||||
const Agent* ag = m_crowd.getAgent(i);
|
duDebugDrawArc(&dd, pos[0], pos[1], pos[2], target[0], target[1], target[2],
|
||||||
if (!ag->active) continue;
|
0.25f, 0, 0.4f, duRGBA(0,0,0,128), 1.0f);
|
||||||
const float* pos = ag->corridor.getPos();
|
|
||||||
gridy = dtMax(gridy, pos[1]);
|
|
||||||
}
|
}
|
||||||
gridy += 1.0f;
|
|
||||||
|
|
||||||
dd.depthMask(false);
|
|
||||||
dd.begin(DU_DRAW_QUADS);
|
|
||||||
const ProximityGrid* grid = m_crowd.getGrid();
|
|
||||||
const int* bounds = grid->getBounds();
|
|
||||||
const float cs = grid->getCellSize();
|
|
||||||
for (int y = bounds[1]; y <= bounds[3]; ++y)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dd.end();
|
|
||||||
dd.depthMask(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < m_form.npolys; ++i)
|
|
||||||
{
|
|
||||||
duDebugDrawNavMeshPoly(&dd, *nmesh, m_form.polys[i], duRGBA(255,255,255,32));
|
|
||||||
}
|
|
||||||
|
|
||||||
dd.depthMask(false);
|
|
||||||
|
|
||||||
dd.begin(DU_DRAW_POINTS, 4.0f);
|
|
||||||
for (int i = 0; i < m_form.nsegs; ++i)
|
|
||||||
{
|
|
||||||
const FormationSeg* seg = &m_form.segs[i];
|
|
||||||
for (int j = 0; j < seg->nints-1; ++j)
|
|
||||||
{
|
|
||||||
if (seg->ints[j].inside == 0) continue;
|
|
||||||
const float u0 = seg->ints[j].u;
|
|
||||||
const float u1 = seg->ints[j+1].u;
|
|
||||||
float ia[3], ib[3];
|
|
||||||
dtVlerp(ia, seg->p,seg->q, u0);
|
|
||||||
dtVlerp(ib, seg->p,seg->q, u1);
|
|
||||||
dd.vertex(ia,duRGBA(128,0,0,192));
|
|
||||||
dd.vertex(ib,duRGBA(128,0,0,192));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dd.end();
|
|
||||||
|
|
||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
|
||||||
for (int i = 0; i < m_form.nsegs; ++i)
|
|
||||||
{
|
|
||||||
const FormationSeg* seg = &m_form.segs[i];
|
|
||||||
dd.vertex(seg->p,duRGBA(255,255,255,128));
|
|
||||||
dd.vertex(seg->q,duRGBA(255,255,255,128));
|
|
||||||
for (int j = 0; j < seg->nints-1; ++j)
|
|
||||||
{
|
|
||||||
if (seg->ints[j].inside == 0) continue;
|
|
||||||
const float u0 = seg->ints[j].u;
|
|
||||||
const float u1 = seg->ints[j+1].u;
|
|
||||||
float ia[3], ib[3];
|
|
||||||
dtVlerp(ia, seg->p,seg->q, u0);
|
|
||||||
dtVlerp(ib, seg->p,seg->q, u1);
|
|
||||||
dd.vertex(ia,duRGBA(128,0,0,192));
|
|
||||||
dd.vertex(ib,duRGBA(128,0,0,192));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dd.end();
|
|
||||||
|
|
||||||
{
|
|
||||||
const float r = m_sample->getAgentRadius();
|
|
||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
|
||||||
for (int i = 0; i < m_form.nsegs; ++i)
|
|
||||||
{
|
|
||||||
const FormationSeg* seg = &m_form.segs[i];
|
|
||||||
dd.vertex(seg->p,duRGBA(255,255,255,128));
|
|
||||||
dd.vertex(seg->q,duRGBA(255,255,255,128));
|
|
||||||
for (int j = 0; j < seg->nints-1; ++j)
|
|
||||||
{
|
|
||||||
if (seg->ints[j].inside == 0) continue;
|
|
||||||
const float u0 = seg->ints[j].u;
|
|
||||||
const float u1 = seg->ints[j+1].u;
|
|
||||||
float ia[3], ib[3];
|
|
||||||
dtVlerp(ia, seg->p,seg->q, u0);
|
|
||||||
dtVlerp(ib, seg->p,seg->q, u1);
|
|
||||||
|
|
||||||
const float spacing = r*2.5f;
|
|
||||||
float delta[3];
|
|
||||||
dtVsub(delta, ib,ia);
|
|
||||||
float d = dtVlen(delta);
|
|
||||||
int np = (int)floorf(d/spacing);
|
|
||||||
for (int k = 0; k < np; ++k)
|
|
||||||
{
|
|
||||||
float pos[3];
|
|
||||||
dtVmad(pos, ia, delta, (float)(k+0.5f)/(float)np);
|
|
||||||
dd.vertex(pos[0],pos[1]-1,pos[2],duRGBA(128,0,0,192));
|
|
||||||
dd.vertex(pos[0],pos[1]+2,pos[2],duRGBA(128,0,0,192));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dd.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dd.depthMask(true);
|
dd.depthMask(true);
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
|
void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||||
@ -622,15 +625,18 @@ void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphParams gp;
|
if (m_showPerfGraph)
|
||||||
gp.setRect(300, 10, 500, 200, 8);
|
{
|
||||||
gp.setValueRange(0.0f, 2.0f, 4, "ms");
|
GraphParams gp;
|
||||||
|
gp.setRect(300, 10, 500, 200, 8);
|
||||||
|
gp.setValueRange(0.0f, 2.0f, 4, "ms");
|
||||||
|
|
||||||
drawGraphBackground(&gp);
|
drawGraphBackground(&gp);
|
||||||
drawGraph(&gp, &m_crowdRvoTime, 0, "RVO Sampling", duRGBA(255,0,128,255));
|
drawGraph(&gp, &m_crowdRvoTime, 0, "RVO Sampling", duRGBA(255,0,128,255));
|
||||||
drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(128,255,0,255));
|
drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(128,255,0,255));
|
||||||
|
|
||||||
gp.setRect(300, 10, 500, 50, 8);
|
gp.setRect(300, 10, 500, 50, 8);
|
||||||
gp.setValueRange(0.0f, 2000.0f, 1, "0");
|
gp.setValueRange(0.0f, 2000.0f, 1, "0");
|
||||||
drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(255,255,255,255));
|
drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(255,255,255,255));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,6 +321,10 @@ void NavMeshTesterTool::handleClick(const float* /*s*/, const float* p, bool shi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NavMeshTesterTool::handleStep()
|
void NavMeshTesterTool::handleStep()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMeshTesterTool::handleToggle()
|
||||||
{
|
{
|
||||||
// TODO: merge separate to a path iterator. Use same code in recalc() too.
|
// TODO: merge separate to a path iterator. Use same code in recalc() too.
|
||||||
if (m_toolMode != TOOLMODE_PATHFIND_FOLLOW)
|
if (m_toolMode != TOOLMODE_PATHFIND_FOLLOW)
|
||||||
|
@ -132,6 +132,10 @@ void OffMeshConnectionTool::handleClick(const float* /*s*/, const float* p, bool
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffMeshConnectionTool::handleToggle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void OffMeshConnectionTool::handleStep()
|
void OffMeshConnectionTool::handleStep()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,12 @@ void Sample::handleClick(const float* s, const float* p, bool shift)
|
|||||||
m_tool->handleClick(s, p, shift);
|
m_tool->handleClick(s, p, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sample::handleToggle()
|
||||||
|
{
|
||||||
|
if (m_tool)
|
||||||
|
m_tool->handleToggle();
|
||||||
|
}
|
||||||
|
|
||||||
void Sample::handleStep()
|
void Sample::handleStep()
|
||||||
{
|
{
|
||||||
if (m_tool)
|
if (m_tool)
|
||||||
|
@ -357,10 +357,10 @@ void Sample_Debug::handleClick(const float* s, const float* p, bool shift)
|
|||||||
m_tool->handleClick(s, p, shift);
|
m_tool->handleClick(s, p, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sample_Debug::handleStep()
|
void Sample_Debug::handleToggle()
|
||||||
{
|
{
|
||||||
if (m_tool)
|
if (m_tool)
|
||||||
m_tool->handleStep();
|
m_tool->handleToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sample_Debug::handleBuild()
|
bool Sample_Debug::handleBuild()
|
||||||
|
@ -86,8 +86,10 @@ public:
|
|||||||
m_sample->setHighlightedTile(m_hitPos);
|
m_sample->setHighlightedTile(m_hitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void handleToggle() {}
|
||||||
|
|
||||||
virtual void handleStep() {}
|
virtual void handleStep() {}
|
||||||
|
|
||||||
virtual void handleUpdate(const float /*dt*/) {}
|
virtual void handleUpdate(const float /*dt*/) {}
|
||||||
|
|
||||||
virtual void handleRender()
|
virtual void handleRender()
|
||||||
|
@ -125,6 +125,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void handleToggle() {}
|
||||||
|
|
||||||
virtual void handleStep() {}
|
virtual void handleStep() {}
|
||||||
|
|
||||||
virtual void handleUpdate(const float /*dt*/) {}
|
virtual void handleUpdate(const float /*dt*/) {}
|
||||||
|
@ -204,14 +204,19 @@ int main(int /*argc*/, char** /*argv*/)
|
|||||||
else if (event.key.keysym.sym == SDLK_SPACE)
|
else if (event.key.keysym.sym == SDLK_SPACE)
|
||||||
{
|
{
|
||||||
if (sample)
|
if (sample)
|
||||||
sample->handleStep();
|
sample->handleToggle();
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.sym == SDLK_1)
|
else if (event.key.keysym.sym == SDLK_1)
|
||||||
|
{
|
||||||
|
if (sample)
|
||||||
|
sample->handleStep();
|
||||||
|
}
|
||||||
|
else if (event.key.keysym.sym == SDLK_9)
|
||||||
{
|
{
|
||||||
if (geom)
|
if (geom)
|
||||||
geom->save("geomset.txt");
|
geom->save("geomset.txt");
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.sym == SDLK_2)
|
else if (event.key.keysym.sym == SDLK_0)
|
||||||
{
|
{
|
||||||
delete geom;
|
delete geom;
|
||||||
geom = new InputGeom;
|
geom = new InputGeom;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user