| 244 | } |
| 245 | |
| 246 | bool obb_intersects_frustum(const OBB &obb, const Frustum &f) |
| 247 | { |
| 248 | const Vector3 obb_x = { obb.tm.x.x, obb.tm.x.y, obb.tm.x.z }; |
| 249 | const Vector3 obb_y = { obb.tm.y.x, obb.tm.y.y, obb.tm.y.z }; |
| 250 | const Vector3 obb_z = { obb.tm.z.x, obb.tm.z.y, obb.tm.z.z }; |
| 251 | const Vector3 obb_p = { obb.tm.t.x, obb.tm.t.y, obb.tm.t.z }; |
| 252 | |
| 253 | const Vector3 bx = obb_x * obb.half_extents.x; |
| 254 | const Vector3 by = obb_y * obb.half_extents.y; |
| 255 | const Vector3 bz = obb_z * obb.half_extents.z; |
| 256 | |
| 257 | // p3 ---- p2 Front face. |
| 258 | // | | |
| 259 | // | | |
| 260 | // p0 ---- p1 |
| 261 | const Vector3 p0 = obb_p - bx - by - bz; // This is min in OBB space. |
| 262 | const Vector3 p1 = obb_p + bx - by - bz; |
| 263 | const Vector3 p2 = obb_p + bx + by - bz; |
| 264 | const Vector3 p3 = obb_p - bx + by - bz; |
| 265 | |
| 266 | // p7 ---- p6 Back face. |
| 267 | // | | |
| 268 | // | | |
| 269 | // p4 ---- p5 |
| 270 | const Vector3 p4 = obb_p - bx - by + bz; |
| 271 | const Vector3 p5 = obb_p + bx - by + bz; |
| 272 | const Vector3 p6 = obb_p + bx + by + bz; |
| 273 | const Vector3 p7 = obb_p - bx + by + bz; // This is max in OBB space. |
| 274 | |
| 275 | for (u32 ii = 0; ii < 6; ++ii) { |
| 276 | u32 out = 0; |
| 277 | if (plane3::distance_to_point(f.planes[ii], p0) < 0.0f) |
| 278 | ++out; |
| 279 | if (plane3::distance_to_point(f.planes[ii], p1) < 0.0f) |
| 280 | ++out; |
| 281 | if (plane3::distance_to_point(f.planes[ii], p2) < 0.0f) |
| 282 | ++out; |
| 283 | if (plane3::distance_to_point(f.planes[ii], p3) < 0.0f) |
| 284 | ++out; |
| 285 | if (plane3::distance_to_point(f.planes[ii], p4) < 0.0f) |
| 286 | ++out; |
| 287 | if (plane3::distance_to_point(f.planes[ii], p5) < 0.0f) |
| 288 | ++out; |
| 289 | if (plane3::distance_to_point(f.planes[ii], p6) < 0.0f) |
| 290 | ++out; |
| 291 | if (plane3::distance_to_point(f.planes[ii], p7) < 0.0f) |
| 292 | ++out; |
| 293 | |
| 294 | if (out == 8) |
| 295 | return false; |
| 296 | } |
| 297 | |
| 298 | // Check for false positives. |
| 299 | // Compute OBB volume planes. Normals point inside the volume. |
| 300 | Plane3 obb_planes[] = |
| 301 | { |
| 302 | plane3::from_point_and_normal(p0, obb_z), // Front. |
| 303 | plane3::from_point_and_normal(p1, -obb_x), // Right. |