| 1186 | } |
| 1187 | |
| 1188 | bool NavMesh::createCoverPoints() |
| 1189 | { |
| 1190 | if(!nm || !isServerObject()) |
| 1191 | return false; |
| 1192 | |
| 1193 | SimSet *set = NULL; |
| 1194 | if(Sim::findObject(mCoverSet, set)) |
| 1195 | { |
| 1196 | set->deleteAllObjects(); |
| 1197 | } |
| 1198 | else |
| 1199 | { |
| 1200 | set = new SimGroup(); |
| 1201 | if(set->registerObject(mCoverSet)) |
| 1202 | { |
| 1203 | getGroup()->addObject(set); |
| 1204 | } |
| 1205 | else |
| 1206 | { |
| 1207 | delete set; |
| 1208 | set = getGroup(); |
| 1209 | } |
| 1210 | } |
| 1211 | |
| 1212 | dtNavMeshQuery *query = dtAllocNavMeshQuery(); |
| 1213 | if(!query || dtStatusFailed(query->init(nm, 1))) |
| 1214 | return false; |
| 1215 | |
| 1216 | dtQueryFilter f; |
| 1217 | |
| 1218 | // Iterate over all polys in our navmesh. |
| 1219 | const int MAX_SEGS = 6; |
| 1220 | for(U32 i = 0; i < nm->getMaxTiles(); ++i) |
| 1221 | { |
| 1222 | const dtMeshTile* tile = ((const dtNavMesh*)nm)->getTile(i); |
| 1223 | if(!tile->header) continue; |
| 1224 | const dtPolyRef base = nm->getPolyRefBase(tile); |
| 1225 | for(U32 j = 0; j < tile->header->polyCount; ++j) |
| 1226 | { |
| 1227 | const dtPolyRef ref = base | j; |
| 1228 | float segs[MAX_SEGS*6]; |
| 1229 | int nsegs = 0; |
| 1230 | query->getPolyWallSegments(ref, &f, segs, NULL, &nsegs, MAX_SEGS); |
| 1231 | for(int segIDx = 0; segIDx < nsegs; ++segIDx) |
| 1232 | { |
| 1233 | const float* sa = &segs[segIDx *6]; |
| 1234 | const float* sb = &segs[segIDx *6+3]; |
| 1235 | Point3F a = RCtoDTS(sa), b = RCtoDTS(sb); |
| 1236 | F32 len = (b - a).len(); |
| 1237 | if(len < mWalkableRadius * 2) |
| 1238 | continue; |
| 1239 | Point3F edge = b - a; |
| 1240 | edge.normalize(); |
| 1241 | // Number of points to try placing - for now, one at each end. |
| 1242 | U32 pointCount = (len > mWalkableRadius * 4) ? 2 : 1; |
| 1243 | for(U32 pointIDx = 0; pointIDx < pointCount; pointIDx++) |
| 1244 | { |
| 1245 | MatrixF mat; |
no test coverage detected