source: ps/trunk/source/maths/BoundingBoxAligned.h@ 22372

Last change on this file since 22372 was 22372, checked in by Vladislav Belov, 5 years ago

Cleanups BoundingBoxAxisAligned and fixes coding styles a bit.

Reviewed By: wraitii
Differential Revision: https://code.wildfiregames.com/D1951

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/* Copyright (C) 2019 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
28class CFrustum;
29class CMatrix3D;
30class CBoundingBoxOriented;
31
32// Basic axis aligned bounding box (AABB) class
33class CBoundingBoxAligned
34{
35public:
36 static const CBoundingBoxAligned EMPTY;
37
38 CBoundingBoxAligned() { SetEmpty(); }
39 CBoundingBoxAligned(const CVector3D& min, const CVector3D& max)
40 {
41 m_Data[0] = min;
42 m_Data[1] = max;
43 }
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 void Translate(const CVector3D& v, CBoundingBoxAligned& result) const
62 {
63 result.m_Data[0] = m_Data[0] + v;
64 result.m_Data[1] = m_Data[1] + v;
65 }
66
67 CVector3D& operator[](int index) { return m_Data[index]; }
68 const CVector3D& operator[](int index) const { return m_Data[index]; }
69
70 void SetEmpty();
71 bool IsEmpty() const;
72
73 void Extend(const CVector3D& min, const CVector3D& max)
74 {
75 if (min.X < m_Data[0].X) m_Data[0].X = min.X;
76 if (min.Y < m_Data[0].Y) m_Data[0].Y = min.Y;
77 if (min.Z < m_Data[0].Z) m_Data[0].Z = min.Z;
78 if (max.X > m_Data[1].X) m_Data[1].X = max.X;
79 if (max.Y > m_Data[1].Y) m_Data[1].Y = max.Y;
80 if (max.Z > m_Data[1].Z) m_Data[1].Z = max.Z;
81 }
82
83 // operator+=: extend this bound to include given bound
84 CBoundingBoxAligned& operator+=(const CBoundingBoxAligned& b)
85 {
86 Extend(b.m_Data[0], b.m_Data[1]);
87 return *this;
88 }
89
90 // operator+=: extend this bound to include given point
91 CBoundingBoxAligned& operator+=(const CVector3D& pt)
92 {
93 Extend(pt, pt);
94 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 // return the volume of this bounding box
111 float GetVolume() const
112 {
113 CVector3D v = m_Data[1] - m_Data[0];
114 return (std::max(v.X, 0.0f) * std::max(v.Y, 0.0f) * std::max(v.Z, 0.0f));
115 }
116
117 // return the center of this bounding box
118 void GetCenter(CVector3D& center) const
119 {
120 center = (m_Data[0] + m_Data[1]) * 0.5f;
121 }
122
123 /**
124 * Expand the bounding box by the given amount in every direction.
125 */
126 void Expand(float amount);
127
128 /**
129 * IntersectFrustumConservative: Approximate the intersection of this bounds object
130 * with the given frustum. The bounds object is overwritten with the results.
131 *
132 * The approximation is conservative in the sense that the result will always contain
133 * the actual intersection, but it may be larger than the intersection itself.
134 * The result will always be fully contained within the original bounds.
135 *
136 * @note While not in the spirit of this function's purpose, a no-op would be a correct
137 * implementation of this function.
138 * @note If this bound is empty, the result is the empty bound.
139 *
140 * @param frustum the frustum to intersect with
141 */
142 void IntersectFrustumConservative(const CFrustum& frustum);
143
144 /**
145 * Construct a CFrustum that describes the same volume as this bounding box.
146 * Only valid for non-empty bounding boxes - check IsEmpty() first.
147 */
148 CFrustum ToFrustum() const;
149
150 /**
151 * Render the surfaces of the bound object as triangles.
152 */
153 void Render(CShaderProgramPtr& shader) const;
154
155 /**
156 * Render the outline of the bound object as lines.
157 */
158 void RenderOutline(CShaderProgramPtr& shader) const;
159
160private:
161 // Holds the minimal and maximal coordinate points in m_Data[0] and m_Data[1], respectively.
162 CVector3D m_Data[2];
163};
164
165#endif // INCLUDED_BOUND
Note: See TracBrowser for help on using the repository browser.