1 /* Copyright Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file OBB.h
16         @author Jukka Jyl�nki
17         @brief The Oriented Bounding Box (OBB) geometry object. */
18 #pragma once
19
20 #include "../MathGeoLibFwd.h"
21 #include "../Math/float3.h"
22
23 MATH_BEGIN_NAMESPACE
24
25 /// A 3D arbitrarily oriented bounding box.
26 /** This data structure represents a box in 3D space. The local axes of this box can be arbitrarily oriented/rotated
27         with respect to the global world coordinate system. This allows OBBs to more tightly bound objects than AABBs do,
28         which always align with the world space axes. This flexibility has the drawback that the geometry tests and operations
29         involving OBBs are more costly, and representing an OBB in memory takes more space (15 floats vs 6 floats). */
30 class OBB
31 {
32 public:
33         /// The center position of this OBB.
34         /** In the local space of the OBB, the center of this OBB is at (r.x,r.y,r.z), and the OBB is an AABB with
35                 size 2*r. */
36         vec pos;
37
38         /// Stores half-sizes to x, y and z directions in the local space of this OBB. [similarOverload: pos]
39         /** These members should be positive to represent a non-degenerate OBB. */
40         vec r;
41
42         /// Specifies normalized direction vectors for the local axes. [noscript] [similarOverload: pos]
43         /** axis[0] specifies the +X direction in the local space of this OBB, axis[1] the +Y direction and axis[2]
44                 the +Z direction.
45                 The scale of these vectors is always normalized. The half-length of the OBB along its local axes is
46                 specified by the vector r.
47                 The axis vectors must always be orthonormal. Be sure to guarantee that condition holds if you
48                 directly set to this member variable. */
49         vec axis[3];
50
51         /// The default constructor does not initialize any members of this class. [opaque-qtscript]
52         /** This means that the values of the members pos, r and axis are undefined after creating a new OBB using this
53                 default constructor. Remember to assign to them before use.
54                 @see pos, r, axis. */
55         OBB() {}
56
57         /// Constructs an OBB by explicitly specifying all its member values.
58         /** @see pos, r, axis. */
59         OBB(const vec &posconst vec &rconst vec &axis0, const vec &axis1, const vec &axis2);
60
61         /// Constructs an OBB from an AABB.
62         /** Since the OBB is an AABB with arbirary rotations allowed, this conversion is exact, i.e. it does not loosen
63                 the set of points represented by the AABB. Therefore this constructor is implicit, meaning that you
64                 can directly assign an AABB to an OBB.
65                 @note Converting an OBB back to an AABB is not exact. See the MinimalEnclosingAABB() function for
66                         converting to the opposite direction.
67                 @see class AABB, SetFrom(), MinimalEnclosingAABB(). */
68         OBB(const AABB &aabb);
69
70         FORCE_INLINE static int NumFaces() { return 6; }
71         FORCE_INLINE static int NumEdges() { return 12; }
72         FORCE_INLINE static int NumVertices() { return 8; }
73
74         /// Sets this structure to a degenerate OBB that does not have any volume.
75         /** This function sets pos=(0,0,0), r = (-inf,-inf,-inf) and axis=float3x3::identity for this OBB.
76                 @note This function operates in-place. After calling this function, this OBB is degenerate.
77                 @see pos, r, axis, IsDegenerate(). */
78         void SetNegativeInfinity();
79
80         /// Sets this OBB from an AABB.
81         /** This conversion is exact, and does not loosen the volume.
82                 @note Converting an OBB back to an AABB is not exact. See the MinimalEnclosingAABB() function for
83                         converting to the opposite direction.
84                 @param aabb The axis-aligned bounding box to convert to an OBB.
85                 @see classes AABB, float3x3, float3x4, float4x4, Quat, MinimalEnclosingAABB(). */
86         void SetFrom(const AABB &aabb);
87         /** @param transform If a transformation matrix is supplied, this transformation is applied to the AABB before
88                 representing it as an oriented bounding box. The basis of this matrix is assumed to be orthogonal, which
89                 means no projection or shear is allowed. Additionally, the matrix must contain only uniform scaling. */
90         void SetFrom(const AABB &aabb, const float3x3 &transform);
91         void SetFrom(const AABB &aabb, const float3x4 &transform);
92         void SetFrom(const AABB &aabb, const float4x4 &transform);
93         void SetFrom(const AABB &aabb, const Quat &transform);
94
95         /// Sets this OBB to enclose the given sphere.
96         /** This function computes the tightest possible OBB (in terms of volume) that contains the given sphere, and stores the result in this structure.
97                 @note Since an OBB is a box, and Sphere is, well, a sphere, this conversion is not exact, but loosens the set of points in the representation.
98                 @see class Sphere, MinimalEnclosingSphere(). */
99         void SetFrom(const Sphere &sphere);
100
101 #ifdef MATH_CONTAINERLIB_SUPPORT
102         /// Sets this OBB to enclose the given polyhedron.              
103         /** This function computes the smallest OBB (in terms of volume) that contains the given polyhedron, and stores the result in this structure.
104                 @note An OBB cannot generally exactly represent a polyhedron. Converting a polyhedron to an OBB loses some features of the polyhedron.
105                 @return True if the resulting OBB is not degenerate, false otherwise. In either case, the old values of this OBB are destroyed.
106                 @see SetFromApproximate(), ToPolyhedron(). */
107         bool SetFrom(const Polyhedron &polyhedron);
108 #endif
109
110 #if 0
111         /// Sets this OBB to enclose the given point cloud.
112         /** This functions uses principal component analysis to generate an approximation of the smallest OBB that encloses the
113                 given point set. The resulting OBB will always contain all the specified points, but might not be the optimally
114                 smallest OBB in terms of volume.
115                 @see SetFrom(), ToPolyhedron(), PCAEnclosingOBB(). */
116         void SetFromApproximate(const vec *pointArray, int numPoints);
117 #endif
118
119         /// Converts this OBB to a polyhedron.
120         /** This function returns a polyhedron representation of this OBB. This conversion is exact, meaning that the returned
121                 polyhedron represents the same set of points that this OBB does.
122                 @see MinimalEnclosingAABB(), ToPBVolume(). */
123         Polyhedron ToPolyhedron() const;
124
125         /// Converts this OBB to a PBVolume.
126         /** This function returns a plane-bounded volume representation of this OBB. The conversion is exact, meaning that the
127                 returned PBVolume<6> represents exactly the same set of points that this OBB does.
128                 @see MinimalEnclosingAABB(), ToPolyhedron(). */
129         PBVolume<6> ToPBVolume() const;
130
131         /// Returns the tightest AABB that contains this OBB.
132         /** This function computes the optimal minimum volume AABB that encloses this OBB.
133                 @note Since an AABB cannot generally represent an OBB, this conversion is not exact, but the returned AABB
134                         specifies a larger volume.                      
135                 @see SetFrom(), MaximalContainedAABB(), MinimalEnclosingSphere(), MaximalContainedSphere(). */
136         AABB MinimalEnclosingAABB() const;
137
138 #if 0
139         /// Returns the largest AABB that can fit inside this OBB.
140         /** This function computes the largest AABB that can fit inside this OBB. This AABB is unique up to the center point of the
141                 AABB. The returned AABB will be centered to the center point of this OBB.
142                 @see MinimalEnclosingAABB(), MinimalEnclosingSphere(), MaximalContainedSphere(). */
143         AABB MaximalContainedAABB() const;
144 #endif
145
146         /// Returns the smallest sphere that contains this OBB.
147         /** This function computes the optimal minimum volume sphere that encloses this OBB.
148                 @see MinimalEnclosingAABB(), MaximalContainedAABB(), MaximalContainedSphere(). */
149         Sphere MinimalEnclosingSphere() const;
150
151         /// Returns the largest sphere that can fit inside this OBB. [similarOverload: MinimalEnclosingSphere]
152         /** This function computes the largest sphere that can fit inside this OBB. This sphere is unique up to the center point
153                 of the sphere. The returned sphere will be positioned to the same center point as this OBB.
154                 @see MinimalEnclosingSphere(), MaximalContainedAABB(), MaximalContainedSphere(). */
155         Sphere MaximalContainedSphere() const;
156
157         /// Returns the side lengths of this OBB in its local x, y and z directions.
158         /** @return 2*r. */
159         vec Size() const;
160
161         /// Returns the half-side lengths of this OBB in its local x, y and z directions. [similarOverload: Size]
162         /** @return r.
163                 @see r, Size(), HalfSize(). */
164         vec HalfSize() const;
165
166         /// Returns a diagonal vector of this OBB.
167         /** This vector runs from one corner of the OBB from the opposite corner.
168                 @note A box has four diagonals. This function returns the direction vector from the -X-Y-Z corner to
169                         the +X+Y+Z corner of the OBB, in the global space of this OBB. */
170         vec Diagonal() const;
171         /// Returns Diagonal()/2. [similarOverload: Diagonal].
172         /** @return A direction vector from the center of this OBB to the +X+Y+Z corner of this OBB, in global space.
173                 @see Size(), HalfSize(). */
174         vec HalfDiagonal() const;
175
176         /// Computes the transformation matrix that maps from the global (world) space of this OBB to the local space of this OBB.
177         /** In local space, the center of the OBB lies at (r.x,r.y,r.z), and the OBB is aligned along the cardinal axes, i.e. is an AABB.
178                 The local +X vector runs in the direction specified by axis[0], the +Y direction is specified by axis[1], and +Z by axis[2].
179                 The size of the OBB is 2*r.
180                 In global (world) space, the center of the OBB lies at the point given by the pos member variable.
181                 @return This global (world) to local space transform can be represented using a float3x4 matrix. This function computes
182                         and returns the matrix that maps from the world space of this OBB to the local space of this OBB.
183                 @see pos, r, axis. */
184         float3x4 WorldToLocal() const;
185
186         /// Computes the transformation matrix that maps from the local space of this OBB to the global (world) space of this OBB. [similarOverload: WorldToLocal]
187         /** This mapping is the inverse of the transform computed by WorldToLocal().
188                 @return A matrix that transforms from the local space of this OBB to the global (world) space of this OBB.
189                 @see pos, r, axis. */
190         float3x4 LocalToWorld() const;
191         
192         /// Tests if this OBB is finite.
193         /** @return True if the member variables of this OBB are valid floats and do not contain NaNs or infs, and false otherwise.
194                 @see IsDegenerate(). */
195         bool IsFinite() const;
196
197         /// Tests if this OBB is degenerate.
198         /** @return True if this OBB does not span a strictly positive volume.
199                 @note This function only checks that the axis radius member of this OBB denotes a strictly positive volume, and ignores 
200                         the position and axis direction vectors of this OBB. Be sure to check those manually for NaNs and +/-infs if that 
201                         is desired.
202                 @see r, Volume(). */
203         bool IsDegenerate() const;
204
205         /// Returns the center point of this OBB in global (world) space of this OBB.
206         /** @note The center point of this OBB in local space is always (r.x, r.y, r.z).
207                 @see pos.  */
208         vec CenterPoint() const;
209
210         /// Returns the center of mass of this OBB. [similarOverload: CenterPoint]
211         /** @note This function is identical to CenterPoint(), and is provided to ease template function implementations.
212                 @see Volume(), SurfaceArea(). */
213         vec Centroid() const return CenterPoint(); }
214
215         inline vec AnyPointFast() const return pos; }
216
217         /// Computes the volume of this OBB.
218         /** @see CenterPoint(), SurfaceArea(). */
219         float Volume() const;
220
221         /// Computes the total surface area of the faces of this OBB.
222         /** @see CenterPoint(), Volume(). */
223         float SurfaceArea() const;
224
225         /// Generates a point inside this OBB.
226         /** @param x A normalized value between [0,1]. This specifies the point position along the local x axis of the OBB.
227                 @param y A normalized value between [0,1]. This specifies the point position along the local y axis of the OBB.
228                 @param z A normalized value between [0,1]. This specifies the point position along the local z axis of the OBB.
229                 @return A point in the global space of this OBB corresponding to the parametric coordinate (x,y,z).
230                 @see Edge(), CornerPoint(), PointOnEdge(), FaceCenterPoint(), FacePoint(). */
231         vec PointInside(float x, float y, float z) const;
232
233         /// Returns an edge of this OBB.
234         /** @param edgeIndex The index of the edge line segment to get, in the range [0, 11].
235                 @todo Draw a diagram that shows which index generates which edge.
236                 @see PointInside(), CornerPoint(), PointOnEdge(), FaceCenterPoint(), FacePoint(). */
237         LineSegment Edge(int edgeIndex) const;
238
239         /// Returns a corner point of this OBB.
240         /** This function generates one of the eight corner points of this OBB.
241                 @param cornerIndex The index of the corner point to generate, in the range [0, 7].
242                  The points are returned in the order 0: ---, 1: --+, 2: -+-, 3: -++, 4: +--, 5: +-+, 6: ++-, 7: +++. (corresponding the XYZ axis directions).
243                 @todo Draw a diagram that shows which index generates which edge.
244                 @see PointInside(), Edge(), PointOnEdge(), FaceCenterPoint(), FacePoint(). */
245         vec CornerPoint(int cornerIndex) const;
246
247         /// Computes an extreme point of this OBB in the given direction.
248         /** An extreme point is a farthest point of this OBB in the given direction. Given a direction,
249                 this point is not necessarily unique.
250                 @param direction The direction vector of the direction to find the extreme point. This vector may
251                         be unnormalized, but may not be null.
252                 @return An extreme point of this OBB in the given direction. The returned point is always a
253                         corner point of this OBB.
254                 @see CornerPoint(). */
255         vec ExtremePoint(const vec &direction) const;
256         vec ExtremePoint(const vec &direction, float &projectionDistance) const;
257
258         /// Projects this OBB onto the given 1D axis direction vector.
259         /** This function collapses this OBB onto an 1D axis for the purposes of e.g. separate axis test computations.
260                 The function returns a 1D range [outMin, outMax] denoting the interval of the projection.
261                 @param direction The 1D axis to project to. This vector may be unnormalized, in which case the output
262                         of this function gets scaled by the length of this vector.
263                 @param outMin [out] Returns the minimum extent of this object along the projection axis.
264                 @param outMax [out] Returns the maximum extent of this object along the projection axis. */
265         void ProjectToAxis(const vec &direction, float &outMin, float &outMax) const;
266
267         int UniqueFaceNormals(vec *out) const;
268         int UniqueEdgeDirections(vec *out) const;
269
270         /// Returns a point on an edge of this OBB.
271         /** @param edgeIndex The index of the edge to generate a point to, in the range [0, 11]. @todo Document which index generates which one.
272                 @param u A normalized value between [0,1]. This specifies the relative distance of the point along the edge.
273                 @see PointInside(), Edge(), CornerPoint(), FaceCenterPoint(), FacePoint(). */
274         vec PointOnEdge(int edgeIndex, float u) const;
275
276         /// Returns the point at the center of the given face of this OBB.
277         /** @param faceIndex The index of the OBB face to generate the point at. The valid range is [0, 5].
278                 @todo Document which index generates which face.
279                 @see PointInside(), Edge(), CornerPoint(), PointOnEdge(), FacePoint(). */
280         vec FaceCenterPoint(int faceIndex) const;
281
282         /// Generates a point at the surface of the given face of this OBB.
283         /** @param faceIndex The index of the OBB face to generate the point at. The valid range is [0, 5].
284                 @param u A normalized value between [0, 1].
285                 @param v A normalized value between [0, 1].
286                 @todo Document which index generates which face.
287                 @see PointInside(), Edge(), CornerPoint(), PointOnEdge(), FaceCenterPoint(), FacePlane(). */
288         vec FacePoint(int faceIndex, float u, float v) const;
289
290         /// Returns the plane of the given face of this OBB.
291         /** The normal of the plane points outwards from this OBB, i.e. towards the space that
292                 is not part of the OBB.
293                 @param faceIndex The index of the face to get, in the range [0, 5].
294                 @see PointInside(), Edge(), CornerPoint(), PointOnEdge(), FaceCenterPoint(), FacePoint(). */
295         Plane FacePlane(int faceIndex) const;
296
297         /// Fills an array with all the eight corner points of this OBB.
298         /** @param outPointArray [out] The array to write the points to. Must have space for 8 elements.
299                 @see CornerPoint(), GetFacePlanes(). */
300         void GetCornerPoints(vec *outPointArray) const;
301
302         /// Fills an array with all the six planes of this OBB.
303         /** @param outPlaneArray [out] The array to write the planes to. Must have space for 6 elements.
304                 @see FacePlane(), GetCornerPoints(). */
305         void GetFacePlanes(Plane *outPlaneArray) const;
306
307         /// Finds the two extreme points along the given direction vector from the given point array.
308         /** @param dir The direction vector to project the point array to. This vector does not need to be normalized.
309                 @param pointArray [in] The list of points to process.
310                 @param numPoints The number of elements in pointArray.
311                 @param idxSmallest [out] The index of the smallest point along the given direction will be received here.
312                         This pointer may be left null, if this information is of no interest.
313                 @param idxLargest [out] The index of the largest point along the given direction will be received here.
314                         This pointer may be left null, if this information is of no interest. */
315         static void ExtremePointsAlongDirection(const vec &dir, const vec *pointArray, int numPoints, int &idxSmallest, int &idxLargest);
316
317 #if 0
318         /// Generates an OBB that encloses the given point set.
319         /** This function uses principal component analysis as the heuristics to generate the OBB. The returned OBB
320                 is not necessarily the optimal OBB that encloses the given point set.
321                 @param pointArray [in] The list of points to enclose with an OBB.
322                 @param numPoints The number of elements in the input array.
323                 @see SetFromApproximate(). */
324         static OBB PCAEnclosingOBB(const vec *pointArray, int numPoints);
325 #endif
326
327         ///\todo This function is strongly WIP! (Works, but is very very slow!)
328         static OBB OptimalEnclosingOBB(const vec *pointArray, int numPoints);
329
330         /// Generates a random point inside this OBB.
331         /** The points are distributed uniformly.
332                 @see class LCG, PointInside(), RandomPointOnSurface(), RandomPointOnEdge(), RandomCornerPoint(). */
333         vec RandomPointInside(LCG &rng) const;
334
335         /// Generates a random point on a random face of this OBB.
336         /** The points are distributed uniformly.
337                 @see class LCG, FacePoint(), RandomPointInside(), RandomPointOnEdge(), RandomCornerPoint(). */
338         vec RandomPointOnSurface(LCG &rng) const;
339
340         /// Generates a random point on a random edge of this OBB.
341         /** The points are distributed uniformly.
342                 @see class LCG, PointOnEdge(), RandomPointInside(), RandomPointOnSurface(), RandomCornerPoint(). */
343         vec RandomPointOnEdge(LCG &rng) const;
344
345         /// Picks a random corner point of this OBB.
346         /** The points are distributed uniformly.
347                 @see class LCG, CornerPoint(), RandomPointInside(), RandomPointOnSurface(), RandomPointOnEdge(). */
348         vec RandomCornerPoint(LCG &rng) const;
349
350         /// Translates this OBB in world space.
351         /** @param offset The amount of displacement to apply to this OBB, in world space coordinates.
352                 @see Scale(), Transform(). */
353         void Translate(const vec &offset);
354
355         /// Applies a uniform scale to this OBB.
356         /** This function scales this OBB structure in-place, using the given center point as the origin
357                 for the scaling operation.
358                 @param centerPoint Specifies the center of the scaling operation, in global (world) space.
359                 @param scaleFactor The uniform scale factor to apply to each global (world) space axis.
360                 @see Translate(), Transform(). */
361         void Scale(const vec &centerPoint, float scaleFactor);
362
363         /// Applies a non-uniform scale to the local axes of this OBB.
364         /** This function scales this OBB structure in-place, using the given global space center point as
365                 the origin for the scaling operation.
366                 @param centerPoint Specifies the center of the scaling operation, in global (world) space.
367                 @param scaleFactor The non-uniform scale factors to apply to each local axis of this OBB.
368                 @see Translate(), Transform(). */
369         void Scale(const vec &centerPoint, const vec &scaleFactor);
370
371         /// Applies a transformation to this OBB.
372         /** @param transform The transformation to apply to this OBB. This transformation must be affine, and
373                         must contain an orthogonal set of column vectors (may not contain shear or projection).
374                         The transformation can only contain uniform scale, and may not contain mirroring.
375                 @see Translate(), Scale(), classes float3x3, float3x4, float4x4, Quat. */
376         void Transform(const float3x3 &transform);
377         void Transform(const float3x4 &transform);
378         void Transform(const float4x4 &transform);
379         void Transform(const Quat &transform);
380
381         /// Computes the closest point inside this OBB to the given point.
382         /** If the target point lies inside this OBB, then that point is returned.
383                 @see Distance(), Contains(), Intersects().
384                 @todo Add ClosestPoint(Line/Ray/LineSegment/Plane/Triangle/Polygon/Circle/Disc/AABB/OBB/Sphere/Capsule/Frustum/Polyhedron). */
385         vec ClosestPoint(const vec &point) const;
386
387         /// Computes the distance between this OBB and the given object.
388         /** This function finds the nearest pair of points on this and the given object, and computes their distance.
389                 If the two objects intersect, or one object is contained inside the other, the returned distance is zero.
390                 @todo Add OBB::Distance(Line/Ray/LineSegment/Plane/Triangle/Polygon/Circle/Disc/AABB/OBB/Capsule/Frustum/Polyhedron).
391                 @see Contains(), Intersects(), ClosestPoint(). */
392         float Distance(const vec &point) const;
393         float Distance(const Sphere &sphere) const;
394
395         /// Tests if the given object is fully contained inside this OBB.
396         /** This function returns true if the given object lies inside this OBB, and false otherwise.
397                 @note The comparison is performed using less-or-equal, so the faces of this OBB count as being inside, but
398                         due to float inaccuracies, this cannot generally be relied upon.
399                 @todo Add Contains(Circle/Disc/Sphere/Capsule).
400                 @see Distance(), Intersects(), ClosestPoint(). */
401         bool Contains(const vec &point) const;
402         bool Contains(const LineSegment &lineSegment) const;
403         bool Contains(const AABB &aabb) const;
404         bool Contains(const OBB &obb) const;
405         bool Contains(const Triangle &triangle) const;
406         bool Contains(const Polygon &polygon) const;
407         bool Contains(const Frustum &frustum) const;
408         bool Contains(const Polyhedron &polyhedron) const;
409
410         /// Tests whether this OBB and the given object intersect.
411         /** Both objects are treated as "solid", meaning that if one of the objects is fully contained inside
412                 another, this function still returns true. (e.g. in case a line segment is contained inside this OBB,
413                 or this OBB is contained inside a Sphere, etc.)
414                 The first parameter of this function specifies the other object to test against.
415                 The OBB-OBB intersection test is from Christer Ericson's book Real-Time Collision Detection, p. 101-106.
416                 See http://realtimecollisiondetection.net/ [groupSyntax]
417                 @param obb The other oriented bounding box to test intersection with.
418                 @param epsilon The OBB-OBB test utilizes a SAT test to detect the intersection. A robust implementation requires
419                         an epsilon threshold to test that the used axes are not degenerate.
420                 @see Contains(), Distance(), ClosestPoint().
421                 @todo Add Intersects(Circle/Disc). */
422         bool Intersects(const OBB &obb, float epsilon = 1e-3f) const;
423         bool Intersects(const AABB &aabb) const;
424         bool Intersects(const Plane &plane) const;
425         /** @param dNear [out] If specified, receives the parametric distance along the line denoting where the
426                         line entered this OBB.
427                 @param dFar [out] If specified, receives the parametric distance along the line denoting where the
428                         line exited this OBB. */
429         bool Intersects(const Ray &ray, float &dNear, float &dFar) const;
430         bool Intersects(const Ray &ray) const;
431         bool Intersects(const Line &line, float &dNear, float &dFar) const;
432         bool Intersects(const Line &line) const;
433         bool Intersects(const LineSegment &lineSegment, float &dNear, float &dFar) const;
434         bool Intersects(const LineSegment &lineSegment) const;
435         /** @param closestPointOnOBB [out] If specified, receives the closest point on this OBB To the given sphere. This
436                         pointer may be null. */
437         bool Intersects(const Sphere &sphere, vec *closestPointOnOBB = 0) const;
438         bool Intersects(const Capsule &capsule) const;
439         bool Intersects(const Triangle &triangle) const;
440         bool Intersects(const Polygon &polygon) const;
441         bool Intersects(const Frustum &frustum) const;
442         bool Intersects(const Polyhedron &polyhedron) const;
443
444         /// Expands this OBB to enclose the given object. The axis directions of this OBB remain intact.
445         /** This function operates in-place. This function does not necessarily result in an OBB that is an
446                 optimal fit for the previous OBB and the given point. */
447         void Enclose(const vec &point);
448
449         /// Generates an unindexed triangle mesh representation of this OBB.
450         /** @param numFacesX The number of faces to generate along the X axis. This value must be >= 1.
451                 @param numFacesY The number of faces to generate along the Y axis. This value must be >= 1.
452                 @param numFacesZ The number of faces to generate along the Z axis. This value must be >= 1.
453                 @param outPos [out] An array of size numVertices which will receive a triangle list
454                                                         of vertex positions. Cannot be null.
455                 @param outNormal [out] An array of size numVertices which will receive vertex normals.
456                                                            If this parameter is null, vertex normals are not returned.
457                 @param outUV [out] An array of size numVertices which will receive vertex UV coordinates.
458                                                            If this parameter is null, a UV mapping is not generated.
459                 The number of vertices that outPos, outNormal and outUV must be able to contain is
460                 (x*y + x*z + y*z)*2*6. If x==y==z==1, then a total of 36 vertices are required. Call
461                 NumVerticesInTriangulation to obtain this value.
462                 @see ToPolyhedron(), ToEdgeList(), NumVerticesInTriangulation(). */
463         void Triangulate(int numFacesX, int numFacesY, int numFacesZ, vec *outPos, vec *outNormal, float2 *outUV, bool ccwIsFrontFacing) const;
464
465         /// Returns the number of vertices that the Triangulate() function will output with the given subdivision parameters.
466         /** @see Triangulate(). */
467         static int NumVerticesInTriangulation(int numFacesX, int numFacesY, int numFacesZ)
468         {
469                 return (numFacesX*numFacesY + numFacesX*numFacesZ + numFacesY*numFacesZ)*2*6;
470         }
471
472         /// Generates an edge list representation of the edges of this OBB.
473         /** @param outPos [out] An array that contains space for at least 24 vertices (NumVerticesInEdgeList()).
474                 @see Triangulate(), Edge(), NumVerticesInEdgeList(). */
475         void ToEdgeList(vec *outPos) const;
476
477         /// Returns the number of vertices that the ToEdgeList() function will output.
478         /** @see ToEdgeList(). */
479         static int NumVerticesInEdgeList()
480         {
481                 return 4*3*2;
482         }
483
484 #ifdef MATH_ENABLE_STL_SUPPORT
485         /// Returns a human-readable representation of this OBB. Most useful for debugging purposes.
486         /** The returned string specifies the center point and the half-axes of this OBB. */
487         std::string ToString() const;
488         std::string SerializeToString() const;
489
490         /// Returns a string of C++ code that can be used to construct this object. Useful for generating test cases from badly behaving objects.
491         std::string SerializeToCodeString() const;
492 #endif
493
494         static OBB FromString(const char *str, const char **outEndStr = 0);
495 #ifdef MATH_ENABLE_STL_SUPPORT
496         static OBB FromString(const std::string &str) { return FromString(str.c_str()); }
497 #endif
498
499 #ifdef MATH_QT_INTEROP
500         operator QString() const return toString(); }
501         QString toString() const return QString::fromStdString(ToString()); }
502 #endif
503
504         // Finds the set intersection of this and the given OBB.
505         /* @return This function returns the Polyhedron that is contained in both this and the given OBB. */
506 //      Polyhedron Intersection(const AABB &aabb) const;
507
508         // Finds the set intersection of this and the given OBB.
509         /* @return This function returns the Polyhedron that is contained in both this and the given OBB. */
510 //      Polyhedron Intersection(const OBB &obb) const;
511
512         // Finds the set intersection of this OBB and the given Polyhedron.
513         /* @return This function returns a Polyhedron that represents the set of points that are contained in this OBB
514                 and the given Polyhedron. */
515 //      Polyhedron Intersection(const Polyhedron &polyhedron) const;
516
517 #ifdef MATH_GRAPHICSENGINE_INTEROP
518         void Triangulate(VertexBuffer &vb, int numFacesX, int numFacesY, int numFacesZ, bool ccwIsFrontFacing) const;
519         void ToLineList(VertexBuffer &vb) const;
520 #endif
521
522         bool Equals(const OBB &rhs, float epsilon = 1e-3f) const return pos.Equals(rhs.posepsilon) && r.Equals(rhs.repsilon) && axis[0].Equals(rhs.axis[0], epsilon) && axis[1].Equals(rhs.axis[1], epsilon) && axis[2].Equals(rhs.axis[2], epsilon); }
523
524         /// Compares whether this OBB and the given OBB  are identical bit-by-bit in the underlying representation.
525         /** @note Prefer using this over e.g. memcmp, since there can be SSE-related padding in the structures. */
526         bool BitEquals(const OBB &other) const return pos.BitEquals(other.pos) && r.BitEquals(other.r) && axis[0].BitEquals(other.axis[0]) && axis[1].BitEquals(other.axis[1]) && axis[2].BitEquals(other.axis[2]); }
527 };
528
529 OBB operator *(const float3x3 &transform, const OBB &obb);
530 OBB operator *(const float3x4 &transform, const OBB &obb);
531 OBB operator *(const float4x4 &transform, const OBB &obb);
532 OBB operator *(const Quat &transform, const OBB &obb);
533
534 #ifdef MATH_QT_INTEROP
535 Q_DECLARE_METATYPE(OBB)
536 Q_DECLARE_METATYPE(OBB*)
537 #endif
538
539 #ifdef MATH_ENABLE_STL_SUPPORT
540 std::ostream &operator <<(std::ostream &o, const OBB &obb);
541 #endif
542
543 MATH_END_NAMESPACE

Go back to previous page