| 112 | } |
| 113 | |
| 114 | LosCollisionData GetLosCollision(const Vector3& origin, int roomNumber, const Vector3& dir, float dist, |
| 115 | bool collideItemBoxes, bool collideItemSpheres, bool collideStatics) |
| 116 | { |
| 117 | // FAILSAFE. |
| 118 | if (dir == Vector3::Zero) |
| 119 | { |
| 120 | TENLog("GetLosCollision(): dir is not a unit vector.", LogLevel::Warning); |
| 121 | return {}; |
| 122 | } |
| 123 | |
| 124 | auto los = LosCollisionData{}; |
| 125 | |
| 126 | auto GetRayHitPosition = [&](float hitDist) |
| 127 | { |
| 128 | return Geometry::TranslatePoint(origin, dir, hitDist); |
| 129 | }; |
| 130 | |
| 131 | auto GetHitPositionRoomNumber = [&](const Vector3& hitPos, const Vector3& basePos, int baseRoomNumber) |
| 132 | { |
| 133 | auto offset = hitPos - basePos; |
| 134 | return GetPointCollision(basePos, baseRoomNumber, offset).GetRoomNumber(); |
| 135 | }; |
| 136 | |
| 137 | auto AddItemSphereLos = [&](ItemInfo* item, int sphereID, const BoundingSphere& sphere, const Vector3& rayOrigin, const Vector3& hitPos, float hitDist) |
| 138 | { |
| 139 | auto itemSphereLos = ItemSphereLosCollisionData{}; |
| 140 | itemSphereLos.Item = item; |
| 141 | itemSphereLos.SphereID = sphereID; |
| 142 | itemSphereLos.Position = hitPos; |
| 143 | itemSphereLos.RoomNumber = GetHitPositionRoomNumber(hitPos, item->Pose.Position.ToVector3(), item->RoomNumber); |
| 144 | itemSphereLos.Distance = hitDist; |
| 145 | itemSphereLos.IsOriginContained = sphere.Contains(rayOrigin); |
| 146 | |
| 147 | los.Spheres.push_back(std::move(itemSphereLos)); |
| 148 | }; |
| 149 | |
| 150 | // 1) Collect room LOS collision. |
| 151 | los.Room = GetRoomLosCollision(origin, roomNumber, dir, dist); |
| 152 | |
| 153 | // 2) Collect item box and sphere LOS collisions. |
| 154 | if (collideItemBoxes || collideItemSpheres) |
| 155 | { |
| 156 | // Run through nearby items. |
| 157 | auto items = GetNearbyItems(los.Room.RoomNumbers); |
| 158 | for (auto* item : items) |
| 159 | { |
| 160 | // 2.1) Collect item box LOS collisions. |
| 161 | if (collideItemBoxes) |
| 162 | { |
| 163 | auto obb = item->GetObb(); |
| 164 | |
| 165 | float boxHitDist = 0.0f; |
| 166 | if (!obb.Intersects(origin, dir, boxHitDist) || boxHitDist > los.Room.Distance) |
| 167 | continue; |
| 168 | |
| 169 | auto boxHitPos = GetRayHitPosition(boxHitDist); |
| 170 | |
| 171 | // Collide clipped spheres. |
no test coverage detected