| 901 | } |
| 902 | |
| 903 | void BuildDirtyBounds(Scene* scene, NavMesh* navMesh, const BoundingBox& dirtyBounds, bool rebuild) |
| 904 | { |
| 905 | const float tileSize = GetTileSize(); |
| 906 | NavMeshRuntime* runtime = navMesh->GetRuntime(); |
| 907 | Matrix worldToNavMesh; |
| 908 | Matrix::RotationQuaternion(runtime->Properties.Rotation, worldToNavMesh); |
| 909 | |
| 910 | // Align dirty bounds to tile size |
| 911 | BoundingBox dirtyBoundsNavMesh; |
| 912 | BoundingBox::Transform(dirtyBounds, worldToNavMesh, dirtyBoundsNavMesh); |
| 913 | dirtyBoundsNavMesh.Minimum = Float3::Floor(dirtyBoundsNavMesh.Minimum / tileSize) * tileSize; |
| 914 | dirtyBoundsNavMesh.Maximum = Float3::Ceil(dirtyBoundsNavMesh.Maximum / tileSize) * tileSize; |
| 915 | |
| 916 | // Calculate tiles range for the given navigation dirty bounds (aligned to tiles size) |
| 917 | const Int3 tilesMin(dirtyBoundsNavMesh.Minimum / tileSize); |
| 918 | const Int3 tilesMax(dirtyBoundsNavMesh.Maximum / tileSize); |
| 919 | const int32 tilesXZ = (tilesMax.X - tilesMin.X) * (tilesMax.Z - tilesMin.Z); |
| 920 | |
| 921 | { |
| 922 | PROFILE_CPU_NAMED("Prepare"); |
| 923 | runtime->Locker.Lock(); |
| 924 | |
| 925 | // Prepare scene data and navmesh |
| 926 | rebuild |= Math::NotNearEqual(navMesh->Data.TileSize, tileSize); |
| 927 | if (rebuild) |
| 928 | { |
| 929 | runtime->Locker.Unlock(); |
| 930 | CancelNavMeshTileBuildTasks(runtime); |
| 931 | runtime->Locker.Lock(); |
| 932 | |
| 933 | // Remove all tiles from navmesh runtime |
| 934 | runtime->RemoveTiles(navMesh); |
| 935 | runtime->SetTileSize(tileSize); |
| 936 | runtime->EnsureCapacity(tilesXZ); |
| 937 | |
| 938 | // Remove all tiles from navmesh data |
| 939 | navMesh->Data.TileSize = tileSize; |
| 940 | navMesh->Data.Tiles.Clear(); |
| 941 | navMesh->Data.Tiles.EnsureCapacity(tilesXZ); |
| 942 | navMesh->IsDataDirty = true; |
| 943 | } |
| 944 | else |
| 945 | { |
| 946 | // Ensure to have enough memory for tiles |
| 947 | runtime->EnsureCapacity(tilesXZ); |
| 948 | } |
| 949 | |
| 950 | runtime->Locker.Unlock(); |
| 951 | } |
| 952 | |
| 953 | // Initialize nav mesh configuration |
| 954 | rcConfig config; |
| 955 | InitConfig(config, navMesh); |
| 956 | |
| 957 | // Generate all tiles that intersect with the navigation volume bounds |
| 958 | { |
| 959 | PROFILE_CPU_NAMED("StartBuildingTiles"); |
| 960 |
no test coverage detected