LCOV - code coverage report
Current view: top level - rbc/shapes - Ellipsoid.hpp (source / functions) Coverage Total Hit
Test: coverage_clean.info Lines: 0.0 % 18 0
Test Date: 2026-03-30 03:13:12 Functions: 0.0 % 2 0

            Line data    Source code
       1              : #pragma once
       2              : #include <math3d/math3d.hpp>
       3              : #include "rbc/AABB.hpp"
       4              : 
       5              : namespace rbc
       6              : {
       7              :     // ── Ellipsoid ─────────────────────────────────────────────────────────────
       8              :     // Axis-aligned ellipsoid in local space; rotation handled by m3d::tf.
       9              :     struct Ellipsoid
      10              :     {
      11              :         m3d::vec3 half_extents; // semi-axes (a, b, c) along local X, Y, Z
      12              : 
      13              :         Ellipsoid() : half_extents(0.5, 0.5, 0.5) {}
      14              :         explicit Ellipsoid(const m3d::vec3 &half_extents) : half_extents(half_extents) {}
      15              : 
      16              :         inline bool operator==(const Ellipsoid &o) const { return half_extents == o.half_extents; }
      17              :         inline bool operator!=(const Ellipsoid &o) const { return !(*this == o); }
      18              :     };
      19              : 
      20              :     // ── Support function ──────────────────────────────────────────────────────
      21              :     // For x²/a² + y²/b² + z²/c² ≤ 1, maximise d·x via Lagrange multipliers:
      22              :     //   p_k = a_k² · d_k  /  sqrt( a_x²·d_x² + a_y²·d_y² + a_z²·d_z² )
      23            0 :     inline m3d::vec3 support(const Ellipsoid &e, const m3d::vec3 &dir)
      24              :     {
      25            0 :         const m3d::vec3 &a = e.half_extents;
      26            0 :         const m3d::vec3 scaled(a.x * a.x * dir.x,
      27            0 :                                a.y * a.y * dir.y,
      28            0 :                                a.z * a.z * dir.z);
      29            0 :         const m3d::scalar denom = m3d::sqrt(a.x * a.x * dir.x * dir.x +
      30            0 :                                             a.y * a.y * dir.y * dir.y +
      31            0 :                                             a.z * a.z * dir.z * dir.z);
      32            0 :         if (denom < m3d::EPSILON)
      33            0 :             return m3d::vec3(a.x, 0.0, 0.0);
      34            0 :         return scaled / denom;
      35              :     }
      36              : 
      37              :     inline m3d::scalar compute_volume(const Ellipsoid &e)
      38              :     {
      39              :         return (4.0 / 3.0) * m3d::PI * e.half_extents.x * e.half_extents.y * e.half_extents.z;
      40              :     }
      41              : 
      42              :     // Ixx = (2/5)·m·(b² + c²), cyclic.
      43              :     inline m3d::smat3 compute_inertia_tensor(const Ellipsoid &e)
      44              :     {
      45              :         const m3d::scalar mass = compute_volume(e);
      46              :         const m3d::scalar ax2 = e.half_extents.x * e.half_extents.x;
      47              :         const m3d::scalar ay2 = e.half_extents.y * e.half_extents.y;
      48              :         const m3d::scalar az2 = e.half_extents.z * e.half_extents.z;
      49              :         return m3d::smat3(
      50              :             (2.0 / 5.0) * mass * (ay2 + az2),
      51              :             (2.0 / 5.0) * mass * (ax2 + az2),
      52              :             (2.0 / 5.0) * mass * (ax2 + ay2),
      53              :             0.0, 0.0, 0.0);
      54              :     }
      55              : 
      56              :     // ── Tight AABB for a rotated ellipsoid ────────────────────────────────────
      57              :     // World-space half-extent along axis i:
      58              :     //   extent_i = sqrt( R[0][i]²·ax² + R[1][i]²·ay² + R[2][i]²·az² )
      59              :     // (Same derivation as Box but with sqrt of sum-of-squares instead of sum of |.|.)
      60            0 :     inline AABB compute_aabb(const Ellipsoid &e, const m3d::tf &tf)
      61              :     {
      62            0 :         const m3d::mat3 R = m3d::mat3_cast(tf.rot);
      63            0 :         const m3d::vec3 &a = e.half_extents;
      64              :         const m3d::vec3 extent(
      65            0 :             m3d::sqrt(R[0][0] * R[0][0] * a.x * a.x + R[1][0] * R[1][0] * a.y * a.y + R[2][0] * R[2][0] * a.z * a.z),
      66            0 :             m3d::sqrt(R[0][1] * R[0][1] * a.x * a.x + R[1][1] * R[1][1] * a.y * a.y + R[2][1] * R[2][1] * a.z * a.z),
      67            0 :             m3d::sqrt(R[0][2] * R[0][2] * a.x * a.x + R[1][2] * R[1][2] * a.y * a.y + R[2][2] * R[2][2] * a.z * a.z));
      68            0 :         return {tf.pos - extent, tf.pos + extent};
      69              :     }
      70              : } // namespace rbc
        

Generated by: LCOV version 2.0-1