More robust path iteration code.

This commit is contained in:
Mikko Mononen 2010-02-12 13:04:55 +00:00
parent 668484eb14
commit 5ade5a3052
16 changed files with 2480 additions and 420 deletions

View File

@ -158,7 +158,11 @@ inline float vperp2D(const float* u, const float* v)
inline float triArea2D(const float* a, const float* b, const float* c)
{
return ((b[0]*a[2] - a[0]*b[2]) + (c[0]*b[2] - b[0]*c[2]) + (a[0]*c[2] - c[0]*a[2])) * 0.5f;
const float abx = b[0] - a[0];
const float abz = b[2] - a[2];
const float acx = c[0] - a[0];
const float acz = c[2] - a[2];
return acx*abz - abx*acz;
}
inline bool checkOverlapBox(const unsigned short amin[3], const unsigned short amax[3],

View File

@ -1353,6 +1353,14 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
return straightPathSize;
}
// If starting really close the portal, advance.
if (i == 0)
{
float t;
if (distancePtSegSqr2D(portalApex, left, right, t) < (0.001*0.001f))
continue;
}
}
else
{

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>ActivePerspectiveName</key>
<string>Debug</string>
<string>Project</string>
<key>AllowedModules</key>
<array>
<dict>
@ -281,14 +281,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>30</integer>
<integer>21</integer>
<integer>50</integer>
<integer>44</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 188}, {358, 643}}</string>
<string>{{0, 334}, {358, 643}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -304,6 +304,8 @@
<string>MainColumn</string>
<real>358</real>
</array>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
@ -314,12 +316,14 @@
<key>Dock</key>
<array>
<dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>RecastMeshDetail.cpp</string>
<string>NavMeshTesterTool.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -327,18 +331,16 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>RecastMeshDetail.cpp</string>
<string>NavMeshTesterTool.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6B324E59112563F300EBD2FD</string>
<string>6B324F471125894D00EBD2FD</string>
<key>history</key>
<array>
<string>6B8DE70D10B01BBF00DF20FB</string>
<string>6BBB883C10EA9B6F008FEA1F</string>
<string>6BB7FDC010F37703006DA0A6</string>
<string>6BB7FDC110F37703006DA0A6</string>
<string>6B69739F10FFCA4500984788</string>
<string>6BCF341A1105EC43009445BF</string>
<string>6BF7BE1F110F0792002B3F46</string>
<string>6BF7C0E511116E74002B3F46</string>
@ -347,54 +349,56 @@
<string>6BF7C2761112BE4F002B3F46</string>
<string>6BF7C2851112C348002B3F46</string>
<string>6BF7C36E1112EB25002B3F46</string>
<string>6BF7C37D1113026E002B3F46</string>
<string>6BF7C394111316AD002B3F46</string>
<string>6BF7C395111316AD002B3F46</string>
<string>6BF7C3CC11131F26002B3F46</string>
<string>6BF7C4641115C514002B3F46</string>
<string>6BF7C4831115C7C4002B3F46</string>
<string>6BF7C5F91116F346002B3F46</string>
<string>6BF7C6591117142A002B3F46</string>
<string>6BF7C67D1117163B002B3F46</string>
<string>6BF7C69B11172159002B3F46</string>
<string>6B324A7C111BF65400EBD2FD</string>
<string>6B324ACA111C00D700EBD2FD</string>
<string>6B324AE6111C07AB00EBD2FD</string>
<string>6B324AEA111C0D9700EBD2FD</string>
<string>6B324AFB111C0F2700EBD2FD</string>
<string>6B324B1F111C10C700EBD2FD</string>
<string>6B324B49111C1AC800EBD2FD</string>
<string>6B324B4F111C1AC800EBD2FD</string>
<string>6B324B50111C1AC800EBD2FD</string>
<string>6B324B51111C1AC800EBD2FD</string>
<string>6B324B52111C1AC800EBD2FD</string>
<string>6B324B71111C1C4F00EBD2FD</string>
<string>6B324B7A111C1C8200EBD2FD</string>
<string>6B324BBB111C4C2B00EBD2FD</string>
<string>6B324C45111C5C5A00EBD2FD</string>
<string>6B324C92111C604500EBD2FD</string>
<string>6B324CC3111C6F6300EBD2FD</string>
<string>6B324CF9111C7B0900EBD2FD</string>
<string>6B324CFA111C7B0900EBD2FD</string>
<string>6B324D0A111C7C1700EBD2FD</string>
<string>6B324D0F1121C78000EBD2FD</string>
<string>6B324D101121C78000EBD2FD</string>
<string>6B324D501121D61A00EBD2FD</string>
<string>6B324D511121D61A00EBD2FD</string>
<string>6B324D641121DE7A00EBD2FD</string>
<string>6B324DC911254B2E00EBD2FD</string>
<string>6B324E071125554800EBD2FD</string>
<string>6B324E181125566A00EBD2FD</string>
<string>6B324E191125566A00EBD2FD</string>
<string>6B324E201125568100EBD2FD</string>
<string>6B324E2B1125598400EBD2FD</string>
<string>6B324E2C1125598400EBD2FD</string>
<string>6B324E3B11255BA700EBD2FD</string>
<string>6B324E3C11255BA700EBD2FD</string>
<string>6B324E4111255DB700EBD2FD</string>
<string>6B324E4911255F5B00EBD2FD</string>
<string>6B324E4D11255FE100EBD2FD</string>
<string>6B324E4E11255FE100EBD2FD</string>
<string>6B324E6D11256D1000EBD2FD</string>
<string>6B324E6E11256D1000EBD2FD</string>
<string>6B324E7011256D1000EBD2FD</string>
<string>6B324E7111256D1000EBD2FD</string>
<string>6B324E7311256D1000EBD2FD</string>
<string>6B324E7411256D1000EBD2FD</string>
<string>6B324E7511256D1000EBD2FD</string>
<string>6B324EE51125799900EBD2FD</string>
<string>6B324F1311257F9A00EBD2FD</string>
<string>6B324F1511257F9A00EBD2FD</string>
<string>6B324F1E1125818400EBD2FD</string>
<string>6B324F1F1125818400EBD2FD</string>
<string>6B324F201125818400EBD2FD</string>
<string>6B324F211125818400EBD2FD</string>
<string>6B324F221125818400EBD2FD</string>
<string>6B324F2E112584FB00EBD2FD</string>
<string>6B324F3A1125891F00EBD2FD</string>
<string>6B324F3B1125891F00EBD2FD</string>
<string>6B324F3C1125891F00EBD2FD</string>
<string>6B324F3D1125891F00EBD2FD</string>
<string>6B324F3E1125891F00EBD2FD</string>
</array>
<key>prevStack</key>
<array>
@ -402,13 +406,11 @@
<string>6BBB87E510EA97CC008FEA1F</string>
<string>6BBB883F10EA9B6F008FEA1F</string>
<string>6BBB885510EA9ECC008FEA1F</string>
<string>6BBB889D10EAA094008FEA1F</string>
<string>6BB7FDC710F37703006DA0A6</string>
<string>6BB7FDDA10F37703006DA0A6</string>
<string>6BB7FE1A10F37CF7006DA0A6</string>
<string>6BB7FE2110F37CF7006DA0A6</string>
<string>6BB7FE5410F3817A006DA0A6</string>
<string>6BB7FF2410F4D699006DA0A6</string>
<string>6BB7FF9610F4E8E2006DA0A6</string>
<string>6BB700C310FA3AB1006DA0A6</string>
<string>6B6973A210FFCA4500984788</string>
@ -425,7 +427,6 @@
<string>6BF7C10E11116E74002B3F46</string>
<string>6BF7C16E11119D8F002B3F46</string>
<string>6BF7C1E51111BD81002B3F46</string>
<string>6BF7C1F21111C0A6002B3F46</string>
<string>6BF7C15711119BB4002B3F46</string>
<string>6BF7C30C1112D8C1002B3F46</string>
<string>6BF7C39C111316AD002B3F46</string>
@ -435,19 +436,14 @@
<string>6BF7C52F1115FA3B002B3F46</string>
<string>6BF7C11111116E74002B3F46</string>
<string>6BF7C6801117163B002B3F46</string>
<string>6BF7C6A411172253002B3F46</string>
<string>6B324A7E111BF65400EBD2FD</string>
<string>6B324AA8111BF92500EBD2FD</string>
<string>6B324AA9111BF92500EBD2FD</string>
<string>6B324AB6111BFEFD00EBD2FD</string>
<string>6B324ACD111C00D700EBD2FD</string>
<string>6B324ACE111C00D700EBD2FD</string>
<string>6B324AD0111C00D700EBD2FD</string>
<string>6B324AD1111C00D700EBD2FD</string>
<string>6B324AD2111C00D700EBD2FD</string>
<string>6B324AD3111C00D700EBD2FD</string>
<string>6B324AD4111C00D700EBD2FD</string>
<string>6B324AD5111C00D700EBD2FD</string>
<string>6B324AD7111C00D700EBD2FD</string>
<string>6B324AE8111C07AB00EBD2FD</string>
<string>6B324AEE111C0D9700EBD2FD</string>
@ -470,7 +466,6 @@
<string>6B324B35111C153D00EBD2FD</string>
<string>6B324B37111C153D00EBD2FD</string>
<string>6B324B3A111C153D00EBD2FD</string>
<string>6B324B55111C1AC800EBD2FD</string>
<string>6B324B56111C1AC800EBD2FD</string>
<string>6B324B57111C1AC800EBD2FD</string>
<string>6B324B5C111C1AC800EBD2FD</string>
@ -489,7 +484,6 @@
<string>6B324B7D111C1C8200EBD2FD</string>
<string>6B324B82111C1CF000EBD2FD</string>
<string>6B324BBD111C4C2B00EBD2FD</string>
<string>6B324BC1111C4C2B00EBD2FD</string>
<string>6B324C21111C5B8D00EBD2FD</string>
<string>6B324C23111C5B8D00EBD2FD</string>
<string>6B324C25111C5B8D00EBD2FD</string>
@ -503,33 +497,20 @@
<string>6B324C59111C5D1400EBD2FD</string>
<string>6B324C61111C5D1400EBD2FD</string>
<string>6B324C71111C5DDC00EBD2FD</string>
<string>6B324C79111C5E7C00EBD2FD</string>
<string>6B324C80111C5EF800EBD2FD</string>
<string>6B324CA4111C6DD400EBD2FD</string>
<string>6B324CA5111C6DD400EBD2FD</string>
<string>6B324CB7111C6EEA00EBD2FD</string>
<string>6B324CB8111C6EEA00EBD2FD</string>
<string>6B324CB9111C6EEA00EBD2FD</string>
<string>6B324CBA111C6EEA00EBD2FD</string>
<string>6B324CBE111C6F3C00EBD2FD</string>
<string>6B324CC5111C6F6300EBD2FD</string>
<string>6B324CD0111C759F00EBD2FD</string>
<string>6B324CD1111C759F00EBD2FD</string>
<string>6B324CDE111C789800EBD2FD</string>
<string>6B324CE1111C789800EBD2FD</string>
<string>6BF7C678111715D1002B3F46</string>
<string>6B324CF4111C7A9800EBD2FD</string>
<string>6B324CF5111C7A9800EBD2FD</string>
<string>6B324CFF111C7B0900EBD2FD</string>
<string>6B324D00111C7B0900EBD2FD</string>
<string>6B324D02111C7B0900EBD2FD</string>
<string>6B324D0B111C7C1700EBD2FD</string>
<string>6B324D0C111C7C1700EBD2FD</string>
<string>6B324D121121C78000EBD2FD</string>
<string>6B324D131121C78000EBD2FD</string>
<string>6B324D141121C78000EBD2FD</string>
<string>6B324D151121C78000EBD2FD</string>
<string>6B324D231121CD0C00EBD2FD</string>
<string>6B324D281121CD2000EBD2FD</string>
<string>6B324D321121CDAF00EBD2FD</string>
<string>6B324D3B1121CFCF00EBD2FD</string>
@ -556,16 +537,10 @@
<string>6B324D97112542DA00EBD2FD</string>
<string>6B324DD011254E0400EBD2FD</string>
<string>6B324DE51125511B00EBD2FD</string>
<string>6B324E0B1125554800EBD2FD</string>
<string>6B324E0C1125554800EBD2FD</string>
<string>6B324E0D1125554800EBD2FD</string>
<string>6B324E0E1125554800EBD2FD</string>
<string>6B324E0F1125554800EBD2FD</string>
<string>6B324E101125554800EBD2FD</string>
<string>6B324E14112555CF00EBD2FD</string>
<string>6B324E1B1125566A00EBD2FD</string>
<string>6B324E221125568100EBD2FD</string>
<string>6B324E301125598400EBD2FD</string>
<string>6B324E311125598400EBD2FD</string>
<string>6B324E321125598400EBD2FD</string>
<string>6B324E331125598400EBD2FD</string>
@ -574,7 +549,32 @@
<string>6B324E3E11255BA700EBD2FD</string>
<string>6B324E3F11255BA700EBD2FD</string>
<string>6B324E4311255DB700EBD2FD</string>
<string>6B324E4F11255FE100EBD2FD</string>
<string>6B324E7C11256D1000EBD2FD</string>
<string>6B324E7D11256D1000EBD2FD</string>
<string>6B324E7E11256D1000EBD2FD</string>
<string>6B324E8011256D1000EBD2FD</string>
<string>6B324E8211256D1000EBD2FD</string>
<string>6B324E8311256D1000EBD2FD</string>
<string>6B324E8611256D1000EBD2FD</string>
<string>6B324E8711256D1000EBD2FD</string>
<string>6B324E8811256D1000EBD2FD</string>
<string>6B324E8911256D1000EBD2FD</string>
<string>6B324ED41125770F00EBD2FD</string>
<string>6B324EE91125799900EBD2FD</string>
<string>6B324EEA1125799900EBD2FD</string>
<string>6B324F1711257F9A00EBD2FD</string>
<string>6B324F251125818400EBD2FD</string>
<string>6B324F261125818400EBD2FD</string>
<string>6B324F271125818400EBD2FD</string>
<string>6B324F281125818400EBD2FD</string>
<string>6B324F291125818400EBD2FD</string>
<string>6B324F31112584FB00EBD2FD</string>
<string>6B324F3F1125891F00EBD2FD</string>
<string>6B324F401125891F00EBD2FD</string>
<string>6B324F411125891F00EBD2FD</string>
<string>6B324F421125891F00EBD2FD</string>
<string>6B324F431125891F00EBD2FD</string>
<string>6B324F441125891F00EBD2FD</string>
</array>
</dict>
<key>SplitCount</key>
@ -588,16 +588,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {876, 497}}</string>
<string>{{0, 0}, {876, 514}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>497pt</string>
<string>514pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>159pt</string>
<string>142pt</string>
<key>Tabs</key>
<array>
<dict>
@ -627,7 +629,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {876, 72}}</string>
<string>{{10, 27}, {876, 192}}</string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
@ -665,7 +667,9 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {876, 132}}</string>
<string>{{10, 27}, {876, 115}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
@ -748,14 +752,12 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {1256, 193}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
<string>{{0, 0}, {1256, 132}}</string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>193pt</string>
<string>132pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -774,8 +776,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {628, 121}}</string>
<string>{{628, 0}, {628, 121}}</string>
<string>{{0, 0}, {628, 82}}</string>
<string>{{628, 0}, {628, 82}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@ -790,8 +792,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {1256, 121}}</string>
<string>{{0, 121}, {1256, 342}}</string>
<string>{{0, 0}, {1256, 82}}</string>
<string>{{0, 82}, {1256, 442}}</string>
</array>
</dict>
</dict>
@ -811,7 +813,7 @@
<key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>Frame</key>
<string>{{0, 198}, {1256, 463}}</string>
<string>{{0, 137}, {1256, 524}}</string>
<key>PBXDebugSessionStackFrameViewKey</key>
<dict>
<key>DebugVariablesTableConfiguration</key>
@ -824,17 +826,13 @@
<real>398</real>
</array>
<key>Frame</key>
<string>{{628, 0}, {628, 121}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
<string>{{628, 0}, {628, 82}}</string>
</dict>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Proportion</key>
<string>463pt</string>
<string>524pt</string>
</dict>
</array>
<key>Name</key>

View File

@ -45,6 +45,7 @@ public:
virtual void reset();
virtual void handleMenu();
virtual void handleClick(const float* p, bool shift);
virtual void handleStep();
virtual void handleRender();
virtual void handleRenderOverlay(double* proj, double* model, int* view);
};

View File

@ -64,6 +64,15 @@ class NavMeshTesterTool : public SampleTool
float m_distanceToWall;
bool m_sposSet;
bool m_eposSet;
int m_pathIterNum;
const dtPolyRef* m_pathIterPolys;
int m_pathIterPolyCount;
float m_prevIterPos[3], m_iterPos[3], m_steerPos[3], m_targetPos[3];
static const int MAX_STEER_POINTS = 10;
float m_steerPoints[MAX_STEER_POINTS*3];
int m_steerPointCount;
public:
NavMeshTesterTool();
@ -74,6 +83,7 @@ public:
virtual void reset();
virtual void handleMenu();
virtual void handleClick(const float* p, bool shift);
virtual void handleStep();
virtual void handleRender();
virtual void handleRenderOverlay(double* proj, double* model, int* view);

View File

@ -40,6 +40,7 @@ public:
virtual void reset();
virtual void handleMenu();
virtual void handleClick(const float* p, bool shift);
virtual void handleStep();
virtual void handleRender();
virtual void handleRenderOverlay(double* proj, double* model, int* view);
};

View File

@ -75,6 +75,7 @@ struct SampleTool
virtual void handleClick(const float* p, bool shift) = 0;
virtual void handleRender() = 0;
virtual void handleRenderOverlay(double* proj, double* model, int* view) = 0;
virtual void handleStep() = 0;
};
@ -111,6 +112,7 @@ public:
virtual void handleTools();
virtual void handleDebugMode();
virtual void handleClick(const float* p, bool shift);
virtual void handleStep();
virtual void handleRender();
virtual void handleRenderOverlay(double* proj, double* model, int* view);
virtual void handleMeshChanged(class InputGeom* geom);

View File

@ -39,9 +39,14 @@
// Returns true if 'c' is left of line 'a'-'b'.
inline bool left(const float* a, const float* b, const float* c)
{
return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]) < 0;
{
const float u1 = b[0] - a[0];
const float v1 = b[2] - a[2];
const float u2 = c[0] - a[0];
const float v2 = c[2] - a[2];
return u1 * v2 - v1 * u2 < 0;
}
// Returns true if 'a' is more lower-left than 'b'.
inline bool cmppt(const float* a, const float* b)
{
@ -225,6 +230,10 @@ void ConvexVolumeTool::handleClick(const float* p, bool shift)
}
void ConvexVolumeTool::handleStep()
{
}
void ConvexVolumeTool::handleRender()
{
DebugDrawGL dd;

View File

@ -46,6 +46,51 @@ inline bool inRange(const float* v1, const float* v2, const float r, const float
return (dx*dx + dz*dz) < r*r && fabsf(dy) < h;
}
static bool getSteerTarget(dtNavMesh* navMesh, const float* startPos, const float* endPos,
const float minTargetDist,
const dtPolyRef* path, const int pathSize,
float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef,
float* outPoints = 0, int* outPointCount = 0)
{
// Find steer target.
static const int MAX_STEER_POINTS = 3;
float steerPath[MAX_STEER_POINTS*3];
unsigned char steerPathFlags[MAX_STEER_POINTS];
dtPolyRef steerPathPolys[MAX_STEER_POINTS];
int nsteerPath = navMesh->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, MAX_STEER_POINTS);
if (!nsteerPath)
return false;
if (outPoints && outPointCount)
{
*outPointCount = nsteerPath;
for (int i = 0; i < nsteerPath; ++i)
vcopy(&outPoints[i*3], &steerPath[i*3]);
}
// Find vertex far enough to steer to.
int ns = 0;
while (ns < nsteerPath)
{
// Stop at Off-Mesh link or when point is further than slop away.
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
!inRange(&steerPath[ns*3], startPos, minTargetDist, 1000.0f))
break;
ns++;
}
// Failed to find good point to steer to.
if (ns >= nsteerPath)
return false;
vcopy(steerPos, &steerPath[ns*3]);
steerPosFlag = steerPathFlags[ns];
steerPosRef = steerPathPolys[ns];
return true;
}
NavMeshTesterTool::NavMeshTesterTool() :
m_sample(0),
@ -58,7 +103,9 @@ NavMeshTesterTool::NavMeshTesterTool() :
m_nsmoothPath(0),
m_distanceToWall(0),
m_sposSet(false),
m_eposSet(false)
m_eposSet(false),
m_pathIterNum(0),
m_steerPointCount(0)
{
m_filter.includeFlags = SAMPLE_POLYFLAGS_ALL;
m_filter.excludeFlags = 0;
@ -220,6 +267,153 @@ void NavMeshTesterTool::handleClick(const float* p, bool shift)
recalc();
}
void NavMeshTesterTool::handleStep()
{
// TODO: merge separate to a path iterator. Use same code in recalc() too.
if (m_toolMode != TOOLMODE_PATHFIND_ITER)
return;
if (!m_sposSet || !m_eposSet || !m_startRef || !m_endRef)
return;
static const float STEP_SIZE = 0.5f;
static const float SLOP = 0.01f;
if (m_pathIterNum == 0)
{
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
m_nsmoothPath = 0;
m_pathIterPolys = m_polys;
m_pathIterPolyCount = m_npolys;
if (m_pathIterPolyCount)
{
// Iterate over the path to find smooth path on the detail mesh surface.
m_navMesh->closestPointOnPolyBoundary(m_startRef, m_spos, m_iterPos);
m_navMesh->closestPointOnPolyBoundary(m_pathIterPolys[m_pathIterPolyCount-1], m_epos, m_targetPos);
m_nsmoothPath = 0;
vcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos);
m_nsmoothPath++;
}
}
vcopy(m_prevIterPos, m_iterPos);
m_pathIterNum++;
if (!m_pathIterPolyCount)
return;
if (m_nsmoothPath >= MAX_SMOOTH)
return;
// Move towards target a small advancement at a time until target reached or
// when ran out of memory to store the path.
// Find location to steer towards.
float steerPos[3];
unsigned char steerPosFlag;
dtPolyRef steerPosRef;
if (!getSteerTarget(m_navMesh, m_iterPos, m_targetPos, SLOP,
m_pathIterPolys, m_pathIterPolyCount, steerPos, steerPosFlag, steerPosRef,
m_steerPoints, &m_steerPointCount))
return;
vcopy(m_steerPos, steerPos);
bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) ? true : false;
bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ? true : false;
// Find movement delta.
float delta[3], len;
vsub(delta, steerPos, m_iterPos);
len = sqrtf(vdot(delta,delta));
// If the steer target is end of path or off-mesh link, do not move past the location.
if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
len = 1;
else
len = STEP_SIZE / len;
float moveTgt[3];
vmad(moveTgt, m_iterPos, delta, len);
// Move
float result[3];
int n = m_navMesh->moveAlongPathCorridor(m_iterPos, moveTgt, result, m_pathIterPolys, m_pathIterPolyCount);
float h = 0;
m_navMesh->getPolyHeight(m_pathIterPolys[n], result, &h);
result[1] = h;
// Shrink path corridor if advanced.
if (n)
{
m_pathIterPolys += n;
m_pathIterPolyCount -= n;
}
// Update position.
vcopy(m_iterPos, result);
// Handle end of path and off-mesh links when close enough.
if (endOfPath && inRange(m_iterPos, steerPos, SLOP, 1.0f))
{
// Reached end of path.
vcopy(m_iterPos, m_targetPos);
if (m_nsmoothPath < MAX_SMOOTH)
{
vcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos);
m_nsmoothPath++;
}
return;
}
else if (offMeshConnection && inRange(m_iterPos, steerPos, SLOP, 1.0f))
{
// Reached off-mesh connection.
float startPos[3], endPos[3];
// Advance the path up to and over the off-mesh connection.
dtPolyRef prevRef = 0, polyRef = m_pathIterPolys[0];
while (m_pathIterPolyCount && polyRef != steerPosRef)
{
prevRef = polyRef;
polyRef = m_pathIterPolys[0];
m_pathIterPolys++;
m_pathIterPolyCount--;
}
// Handle the connection.
if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))
{
if (m_nsmoothPath < MAX_SMOOTH)
{
vcopy(&m_smoothPath[m_nsmoothPath*3], startPos);
m_nsmoothPath++;
// Hack to make the dotted path not visible during off-mesh connection.
if (m_nsmoothPath & 1)
{
vcopy(&m_smoothPath[m_nsmoothPath*3], startPos);
m_nsmoothPath++;
}
}
// Move position at the other side of the off-mesh link.
vcopy(m_iterPos, endPos);
float h;
m_navMesh->getPolyHeight(m_pathIterPolys[0], m_iterPos, &h);
m_iterPos[1] = h;
}
}
// Store results.
if (m_nsmoothPath < MAX_SMOOTH)
{
vcopy(&m_smoothPath[m_nsmoothPath*3], m_iterPos);
m_nsmoothPath++;
}
}
void NavMeshTesterTool::reset()
{
m_startRef = 0;
@ -232,42 +426,6 @@ void NavMeshTesterTool::reset()
m_distanceToWall = 0;
}
static bool getSteerTarget(dtNavMesh* navMesh, const float* startPos, const float* endPos,
const float minTargetDist,
const dtPolyRef* path, const int pathSize,
float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef)
{
// Find steer target.
static const int MAX_STEER_POINTS = 3;
float steerPath[MAX_STEER_POINTS*3];
unsigned char steerPathFlags[MAX_STEER_POINTS];
dtPolyRef steerPathPolys[MAX_STEER_POINTS];
int nsteerPath = navMesh->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, MAX_STEER_POINTS);
if (!nsteerPath)
return false;
// Find vertex far enough to steer to.
int ns = 0;
while (ns < nsteerPath)
{
// Stop at Off-Mesh link or when point is further than slop away.
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
!inRange(&steerPath[ns*3], startPos, minTargetDist, 1000.0f))
break;
ns++;
}
// Failed to find good point to steer to.
if (ns >= nsteerPath)
return false;
vcopy(steerPos, &steerPath[ns*3]);
steerPosFlag = steerPathFlags[ns];
steerPosRef = steerPathPolys[ns];
return true;
}
void NavMeshTesterTool::recalc()
{
@ -286,6 +444,7 @@ void NavMeshTesterTool::recalc()
if (m_toolMode == TOOLMODE_PATHFIND_ITER)
{
m_pathIterNum = 0;
if (m_sposSet && m_eposSet && m_startRef && m_endRef)
{
#ifdef DUMP_REQS
@ -567,6 +726,37 @@ void NavMeshTesterTool::handleRender()
dd.vertex(m_smoothPath[i*3], m_smoothPath[i*3+1]+0.1f, m_smoothPath[i*3+2], pathCol);
dd.end();
}
if (m_pathIterNum)
{
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_pathIterPolys[0], duRGBA(255,255,255,128));
dd.begin(DU_DRAW_LINES, 1.0f);
const unsigned int prevCol = duRGBA(255,192,0,220);
const unsigned int curCol = duRGBA(255,255,255,220);
const unsigned int steerCol = duRGBA(0,192,255,220);
dd.vertex(m_prevIterPos[0],m_prevIterPos[1]-0.3f,m_prevIterPos[2], prevCol);
dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], prevCol);
dd.vertex(m_iterPos[0],m_iterPos[1]-0.3f,m_iterPos[2], curCol);
dd.vertex(m_iterPos[0],m_iterPos[1]+0.3f,m_iterPos[2], curCol);
dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], prevCol);
dd.vertex(m_iterPos[0],m_iterPos[1]+0.3f,m_iterPos[2], prevCol);
dd.vertex(m_prevIterPos[0],m_prevIterPos[1]+0.3f,m_prevIterPos[2], steerCol);
dd.vertex(m_steerPos[0],m_steerPos[1]+0.3f,m_steerPos[2], steerCol);
for (int i = 0; i < m_steerPointCount-1; ++i)
{
dd.vertex(m_steerPoints[i*3+0],m_steerPoints[i*3+1]+0.2f,m_steerPoints[i*3+2], duDarkenColor(steerCol));
dd.vertex(m_steerPoints[(i+1)*3+0],m_steerPoints[(i+1)*3+1]+0.2f,m_steerPoints[(i+1)*3+2], duDarkenColor(steerCol));
}
dd.end();
}
}
else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
{

View File

@ -132,6 +132,10 @@ void OffMeshConnectionTool::handleClick(const float* p, bool shift)
}
void OffMeshConnectionTool::handleStep()
{
}
void OffMeshConnectionTool::handleRender()
{
DebugDrawGL dd;

View File

@ -205,6 +205,12 @@ void Sample::handleClick(const float* p, bool shift)
m_tool->handleClick(p, shift);
}
void Sample::handleStep()
{
if (m_tool)
m_tool->handleStep();
}
bool Sample::handleBuild()
{
return true;

View File

@ -85,6 +85,8 @@ public:
m_sample->setHighlightedTile(m_hitPos);
}
virtual void handleStep() {}
virtual void handleRender()
{
if (m_hitPosSet)

View File

@ -123,6 +123,8 @@ public:
m_sample->buildTile(m_hitPos);
}
}
virtual void handleStep() {}
virtual void handleRender()
{

View File

@ -256,6 +256,11 @@ int main(int argc, char *argv[])
showTestCases = true;
scanDirectory("Tests", ".txt", files);
}
else if (event.key.keysym.sym == SDLK_SPACE)
{
if (sample)
sample->handleStep();
}
else if (event.key.keysym.sym == SDLK_1)
{
if (geom)