| 369 | } |
| 370 | |
| 371 | bool GenerateTile(NavMesh* navMesh, NavMeshRuntime* runtime, int32 x, int32 y, BoundingBox& tileBoundsNavMesh, const Matrix& worldToNavMesh, float tileSize, rcConfig& config, Task* task) |
| 372 | { |
| 373 | rcContext context; |
| 374 | context.enableLog(false); |
| 375 | int32 layer = 0; |
| 376 | |
| 377 | // Expand tile bounds by a certain margin |
| 378 | const float tileBorderSize = (1.0f + (float)config.borderSize) * config.cs; |
| 379 | tileBoundsNavMesh.Minimum -= tileBorderSize; |
| 380 | tileBoundsNavMesh.Maximum += tileBorderSize; |
| 381 | |
| 382 | *(Float3*)&config.bmin = tileBoundsNavMesh.Minimum; |
| 383 | *(Float3*)&config.bmax = tileBoundsNavMesh.Maximum; |
| 384 | |
| 385 | rcHeightfield* heightfield = rcAllocHeightfield(); |
| 386 | if (!heightfield) |
| 387 | { |
| 388 | LOG(Warning, "Could not generate navmesh: Out of memory for heightfield."); |
| 389 | return true; |
| 390 | } |
| 391 | SCOPE_EXIT{ rcFreeHeightField(heightfield); }; |
| 392 | if (!rcCreateHeightfield(&context, *heightfield, config.width, config.height, config.bmin, config.bmax, config.cs, config.ch)) |
| 393 | { |
| 394 | LOG(Warning, "Could not generate navmesh: Could not create solid heightfield."); |
| 395 | return true; |
| 396 | } |
| 397 | |
| 398 | Array<OffMeshLink> offMeshLinks; |
| 399 | Array<Modifier> modifiers; |
| 400 | { |
| 401 | PROFILE_CPU_NAMED("RasterizeGeometry"); |
| 402 | NavSceneRasterizer rasterizer(navMesh, tileBoundsNavMesh, worldToNavMesh, &context, &config, heightfield, &offMeshLinks, &modifiers); |
| 403 | |
| 404 | // Collect actors to rasterize |
| 405 | Array<Actor*> actors; |
| 406 | { |
| 407 | PROFILE_CPU_NAMED("CollectActors"); |
| 408 | ScopeLock lock(Level::ScenesLock); |
| 409 | for (Scene* scene : Level::Scenes) |
| 410 | { |
| 411 | for (Actor* actor : scene->Navigation.Actors) |
| 412 | { |
| 413 | BoundingBox actorBoxNavMesh; |
| 414 | BoundingBox::Transform(actor->GetBox(), rasterizer.WorldToNavMesh, actorBoxNavMesh); |
| 415 | if (actorBoxNavMesh.Intersects(rasterizer.TileBoundsNavMesh) && |
| 416 | actor->IsActiveInHierarchy() && |
| 417 | EnumHasAllFlags(actor->GetStaticFlags(), StaticFlags::Navigation)) |
| 418 | { |
| 419 | actors.Add(actor); |
| 420 | } |
| 421 | } |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | // Rasterize actors |
| 426 | for (Actor* actor : actors) |
| 427 | { |
| 428 | rasterizer.Rasterize(actor); |
no test coverage detected