LCOV - code coverage report
Current view: top level - source/maths - BoundingBoxAligned.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 29 32 90.6 %
Date: 2023-01-19 00:18:29 Functions: 9 10 90.0 %

          Line data    Source code
       1             : /* Copyright (C) 2021 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : /*
      19             :  * Axis-aligned bounding box
      20             :  */
      21             : 
      22             : #ifndef INCLUDED_BOUND
      23             : #define INCLUDED_BOUND
      24             : 
      25             : #include "maths/Vector3D.h"
      26             : #include "graphics/ShaderProgramPtr.h"
      27             : 
      28             : class CFrustum;
      29             : class CMatrix3D;
      30             : class CBoundingBoxOriented;
      31             : 
      32             : // Basic axis aligned bounding box (AABB) class
      33             : class CBoundingBoxAligned
      34             : {
      35             : public:
      36             :     static const CBoundingBoxAligned EMPTY;
      37             : 
      38         400 :     CBoundingBoxAligned() { SetEmpty(); }
      39          34 :     CBoundingBoxAligned(const CVector3D& min, const CVector3D& max)
      40          34 :     {
      41          34 :         m_Data[0] = min;
      42          34 :         m_Data[1] = max;
      43          34 :     }
      44             : 
      45             :     /**
      46             :      * Transforms these bounds according to the specified transformation matrix @p m, and writes the axis-aligned bounds
      47             :      * of that result to @p result.
      48             :      */
      49             :     void Transform(const CMatrix3D& m, CBoundingBoxAligned& result) const;
      50             : 
      51             :     /**
      52             :      * Transform these bounds using the matrix @p transform, and write out the result as an oriented (i.e. non-axis-aligned) box.
      53             :      * The difference with @ref Transform(const CMatrix3D&, CBoundingBoxAligned&) is that that method is equivalent to first
      54             :      * computing this result, and then taking the axis-aligned bounding boxes from the result again.
      55             :      */
      56             :     void Transform(const CMatrix3D& m, CBoundingBoxOriented& result) const;
      57             : 
      58             :     /**
      59             :      * Translates these bounds by @p v, and writes the result to @p result.
      60             :      */
      61           1 :     void Translate(const CVector3D& v, CBoundingBoxAligned& result) const
      62             :     {
      63           1 :         result.m_Data[0] = m_Data[0] + v;
      64           1 :         result.m_Data[1] = m_Data[1] + v;
      65           1 :     }
      66             : 
      67        1572 :     CVector3D& operator[](int index) { return m_Data[index]; }
      68         516 :     const CVector3D& operator[](int index) const { return m_Data[index]; }
      69             : 
      70             :     void SetEmpty();
      71             :     bool IsEmpty() const;
      72             : 
      73      296015 :     void Extend(const CVector3D& min, const CVector3D& max)
      74             :     {
      75      296015 :         if (min.X < m_Data[0].X) m_Data[0].X = min.X;
      76      296015 :         if (min.Y < m_Data[0].Y) m_Data[0].Y = min.Y;
      77      296015 :         if (min.Z < m_Data[0].Z) m_Data[0].Z = min.Z;
      78      296015 :         if (max.X > m_Data[1].X) m_Data[1].X = max.X;
      79      296015 :         if (max.Y > m_Data[1].Y) m_Data[1].Y = max.Y;
      80      296015 :         if (max.Z > m_Data[1].Z) m_Data[1].Z = max.Z;
      81      296015 :     }
      82             : 
      83             :     // operator+=: extend this bound to include given bound
      84           1 :     CBoundingBoxAligned& operator+=(const CBoundingBoxAligned& b)
      85             :     {
      86           1 :         Extend(b.m_Data[0], b.m_Data[1]);
      87           1 :         return *this;
      88             :     }
      89             : 
      90             :     // operator+=: extend this bound to include given point
      91      296014 :     CBoundingBoxAligned& operator+=(const CVector3D& pt)
      92             :     {
      93      296014 :         Extend(pt, pt);
      94      296014 :         return *this;
      95             :     }
      96             : 
      97             :     /**
      98             :      * Check if a given ray intersects this AABB.
      99             :      * See also Real-Time Rendering, Third Edition by T. Akenine-Moller, p. 741--742.
     100             :      *
     101             :      * @param[in] origin Origin of the ray.
     102             :      * @param[in] dir Direction vector of the ray, defining the positive direction of the ray. Must be of unit length.
     103             :      * @param[out] tmin,tmax distance in the positive direction from the origin of the ray to the entry and exit points in
     104             :      *  the bounding box. If the origin is inside the box, then this is counted as an intersection and one of @p tMin and @p tMax may be negative.
     105             :      *
     106             :      * @return true if the ray originating in @p origin and with unit direction vector @p dir intersects this AABB, false otherwise.
     107             :      */
     108             :     bool RayIntersect(const CVector3D& origin, const CVector3D& dir, float& tmin, float& tmax) const;
     109             : 
     110             :     bool IsPointInside(const CVector3D& point) const;
     111             : 
     112             :     // return the volume of this bounding box
     113           0 :     float GetVolume() const
     114             :     {
     115           0 :         CVector3D v = m_Data[1] - m_Data[0];
     116           0 :         return (std::max(v.X, 0.0f) * std::max(v.Y, 0.0f) * std::max(v.Z, 0.0f));
     117             :     }
     118             : 
     119             :     // return the center of this bounding box
     120           3 :     void GetCenter(CVector3D& center) const
     121             :     {
     122           3 :         center = (m_Data[0] + m_Data[1]) * 0.5f;
     123           3 :     }
     124             : 
     125             :     /**
     126             :      * Expand the bounding box by the given amount in every direction.
     127             :      */
     128             :     void Expand(float amount);
     129             : 
     130             :     /**
     131             :      * IntersectFrustumConservative: Approximate the intersection of this bounds object
     132             :      * with the given frustum. The bounds object is overwritten with the results.
     133             :      *
     134             :      * The approximation is conservative in the sense that the result will always contain
     135             :      * the actual intersection, but it may be larger than the intersection itself.
     136             :      * The result will always be fully contained within the original bounds.
     137             :      *
     138             :      * @note While not in the spirit of this function's purpose, a no-op would be a correct
     139             :      * implementation of this function.
     140             :      * @note If this bound is empty, the result is the empty bound.
     141             :      *
     142             :      * @param frustum the frustum to intersect with
     143             :      */
     144             :     void IntersectFrustumConservative(const CFrustum& frustum);
     145             : 
     146             :     /**
     147             :      * Construct a CFrustum that describes the same volume as this bounding box.
     148             :      * Only valid for non-empty bounding boxes - check IsEmpty() first.
     149             :      */
     150             :     CFrustum ToFrustum() const;
     151             : 
     152             : private:
     153             :     // Holds the minimal and maximal coordinate points in m_Data[0] and m_Data[1], respectively.
     154             :     CVector3D m_Data[2];
     155             : };
     156             : 
     157             : #endif // INCLUDED_BOUND

Generated by: LCOV version 1.13