| 275 | } |
| 276 | |
| 277 | RoomLosCollisionData GetRoomLosCollision(const Vector3& origin, int roomNumber, const Vector3& dir, float dist, bool collideBridges) |
| 278 | { |
| 279 | constexpr auto PORTAL_THRESHOLD = 0.001f; |
| 280 | |
| 281 | // FAILSAFE. |
| 282 | if (dir == Vector3::Zero) |
| 283 | { |
| 284 | TENLog("GetRoomLosCollision(): Direction is not a unit vector.", LogLevel::Warning); |
| 285 | return {}; |
| 286 | } |
| 287 | |
| 288 | auto roomLos = RoomLosCollisionData{}; |
| 289 | |
| 290 | // 1) Define ray. |
| 291 | auto ray = Ray(origin, dir); |
| 292 | float rayDist = dist; |
| 293 | int rayRoomNumber = roomNumber; |
| 294 | |
| 295 | // 2) Traverse rooms. |
| 296 | bool traversePortal = true; |
| 297 | while (traversePortal) |
| 298 | { |
| 299 | auto closestTri = std::optional<CollisionTriangleData>(); |
| 300 | float closestDist = rayDist; |
| 301 | int portalRoomNumber = NO_VALUE; |
| 302 | |
| 303 | // 2.1) Clip room. |
| 304 | const auto& room = g_Level.Rooms[rayRoomNumber]; |
| 305 | auto meshColl = room.CollisionMesh.GetCollision(ray, closestDist); |
| 306 | if (meshColl.has_value()) |
| 307 | { |
| 308 | closestTri = meshColl->Triangle; |
| 309 | closestDist = meshColl->Distance; |
| 310 | } |
| 311 | |
| 312 | // 2.2) Clip doors. |
| 313 | auto doorItemNumbers = room.Doors.GetBoundedIds(ray, closestDist); |
| 314 | for (int doorItemNumber : doorItemNumbers) |
| 315 | { |
| 316 | const auto& doorItem = g_Level.Items[doorItemNumber]; |
| 317 | const auto& door = GetDoorObject(doorItem); |
| 318 | |
| 319 | auto doorMeshColl = door.CollisionMesh.GetCollision(ray, closestDist); |
| 320 | if (doorMeshColl.has_value()) |
| 321 | { |
| 322 | closestTri = doorMeshColl->Triangle; |
| 323 | closestDist = doorMeshColl->Distance; |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | // 2.3) Clip bridge (if applicable). |
| 328 | if (collideBridges) |
| 329 | { |
| 330 | // Run through neighbor rooms. |
| 331 | for (int neighborRoomNumber : room.NeighborRoomNumbers) |
| 332 | { |
| 333 | const auto& neighborRoom = g_Level.Rooms[neighborRoomNumber]; |
| 334 | |