| 224 | } |
| 225 | |
| 226 | dtStatus dtNavMeshQuery::findRandomPoint(const dtQueryFilter* filter, float (*frand)(), |
| 227 | dtPolyRef* randomRef, float* randomPt) const |
| 228 | { |
| 229 | dtAssert(m_nav); |
| 230 | |
| 231 | if (!filter || !frand || !randomRef || !randomPt) |
| 232 | return DT_FAILURE | DT_INVALID_PARAM; |
| 233 | |
| 234 | // Randomly pick one tile. Assume that all tiles cover roughly the same area. |
| 235 | const dtMeshTile* tile = 0; |
| 236 | float tsum = 0.0f; |
| 237 | for (int i = 0; i < m_nav->getMaxTiles(); i++) |
| 238 | { |
| 239 | const dtMeshTile* t = m_nav->getTile(i); |
| 240 | if (!t || !t->header) continue; |
| 241 | |
| 242 | // Choose random tile using reservoi sampling. |
| 243 | const float area = 1.0f; // Could be tile area too. |
| 244 | tsum += area; |
| 245 | const float u = frand(); |
| 246 | if (u*tsum <= area) |
| 247 | tile = t; |
| 248 | } |
| 249 | if (!tile) |
| 250 | return DT_FAILURE; |
| 251 | |
| 252 | // Randomly pick one polygon weighted by polygon area. |
| 253 | const dtPoly* poly = 0; |
| 254 | dtPolyRef polyRef = 0; |
| 255 | const dtPolyRef base = m_nav->getPolyRefBase(tile); |
| 256 | |
| 257 | float areaSum = 0.0f; |
| 258 | for (int i = 0; i < tile->header->polyCount; ++i) |
| 259 | { |
| 260 | const dtPoly* p = &tile->polys[i]; |
| 261 | // Do not return off-mesh connection polygons. |
| 262 | if (p->getType() != DT_POLYTYPE_GROUND) |
| 263 | continue; |
| 264 | // Must pass filter |
| 265 | const dtPolyRef ref = base | (dtPolyRef)i; |
| 266 | if (!filter->passFilter(ref, tile, p)) |
| 267 | continue; |
| 268 | |
| 269 | // Calc area of the polygon. |
| 270 | float polyArea = 0.0f; |
| 271 | for (int j = 2; j < p->vertCount; ++j) |
| 272 | { |
| 273 | const float* va = &tile->verts[p->verts[0]*3]; |
| 274 | const float* vb = &tile->verts[p->verts[j-1]*3]; |
| 275 | const float* vc = &tile->verts[p->verts[j]*3]; |
| 276 | polyArea += dtTriArea2D(va,vb,vc); |
| 277 | } |
| 278 | |
| 279 | // Choose random polygon weighted by area, using reservoi sampling. |
| 280 | areaSum += polyArea; |
| 281 | const float u = frand(); |
| 282 | if (u*areaSum <= polyArea) |
| 283 | { |
nothing calls this directly
no test coverage detected