1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29
30#ifndef GU_BOX_H
31#define GU_BOX_H
32
33/** \addtogroup geomutils
34@{
35*/
36
37#include "foundation/PxTransform.h"
38#include "foundation/PxMat33.h"
39#include "common/PxPhysXCommonConfig.h"
40#include "CmPhysXCommon.h"
41#include "CmScaling.h"
42
43namespace physx
44{
45namespace Gu
46{
47 class Capsule;
48
49 PX_PHYSX_COMMON_API void computeOBBPoints(PxVec3* PX_RESTRICT pts, const PxVec3& center, const PxVec3& extents, const PxVec3& base0, const PxVec3& base1, const PxVec3& base2);
50
51
52 /**
53 \brief Represents an oriented bounding box.
54
55 As a center point, extents(radii) and a rotation. i.e. the center of the box is at the center point,
56 the box is rotated around this point with the rotation and it is 2*extents in width, height and depth.
57 */
58
59 /**
60 Box geometry
61
62 The rot member describes the world space orientation of the box.
63 The center member gives the world space position of the box.
64 The extents give the local space coordinates of the box corner in the positive octant.
65 Dimensions of the box are: 2*extent.
66 Transformation to world space is: worldPoint = rot * localPoint + center
67 Transformation to local space is: localPoint = T(rot) * (worldPoint - center)
68 Where T(M) denotes the transpose of M.
69 */
70#if PX_VC
71 #pragma warning(push)
72 #pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class
73#endif
74 class PX_PHYSX_COMMON_API Box
75 {
76 public:
77 /**
78 \brief Constructor
79 */
80 PX_FORCE_INLINE Box()
81 {
82 }
83
84 /**
85 \brief Constructor
86
87 \param origin Center of the OBB
88 \param extent Extents/radii of the obb.
89 \param base rotation to apply to the obb.
90 */
91 //! Construct from center, extent and rotation
92 PX_FORCE_INLINE Box(const PxVec3& origin, const PxVec3& extent, const PxMat33& base) : rot(base), center(origin), extents(extent)
93 {}
94
95 //! Copy constructor
96 PX_FORCE_INLINE Box(const Box& other) : rot(other.rot), center(other.center), extents(other.extents)
97 {}
98
99 /**
100 \brief Destructor
101 */
102 PX_FORCE_INLINE ~Box()
103 {
104 }
105
106 //! Assignment operator
107 PX_FORCE_INLINE const Box& operator=(const Box& other)
108 {
109 rot = other.rot;
110 center = other.center;
111 extents = other.extents;
112 return *this;
113 }
114
115 /**
116 \brief Setups an empty box.
117 */
118 PX_INLINE void setEmpty()
119 {
120 center = PxVec3(0);
121 extents = PxVec3(-PX_MAX_REAL, -PX_MAX_REAL, -PX_MAX_REAL);
122 rot = PxMat33(PxIdentity);
123 }
124
125 /**
126 \brief Checks the box is valid.
127
128 \return true if the box is valid
129 */
130 PX_INLINE bool isValid() const
131 {
132 // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
133 if(extents.x < 0.0f) return false;
134 if(extents.y < 0.0f) return false;
135 if(extents.z < 0.0f) return false;
136 return true;
137 }
138
139/////////////
140 PX_FORCE_INLINE void setAxes(const PxVec3& axis0, const PxVec3& axis1, const PxVec3& axis2)
141 {
142 rot.column0 = axis0;
143 rot.column1 = axis1;
144 rot.column2 = axis2;
145 }
146
147 PX_FORCE_INLINE PxVec3 rotate(const PxVec3& src) const
148 {
149 return rot * src;
150 }
151
152 PX_FORCE_INLINE PxVec3 rotateInv(const PxVec3& src) const
153 {
154 return rot.transformTranspose(other: src);
155 }
156
157 PX_FORCE_INLINE PxVec3 transform(const PxVec3& src) const
158 {
159 return rot * src + center;
160 }
161
162 PX_FORCE_INLINE PxTransform getTransform() const
163 {
164 return PxTransform(center, PxQuat(rot));
165 }
166
167 PX_INLINE PxVec3 computeAABBExtent() const
168 {
169 const PxReal a00 = PxAbs(a: rot[0][0]);
170 const PxReal a01 = PxAbs(a: rot[0][1]);
171 const PxReal a02 = PxAbs(a: rot[0][2]);
172
173 const PxReal a10 = PxAbs(a: rot[1][0]);
174 const PxReal a11 = PxAbs(a: rot[1][1]);
175 const PxReal a12 = PxAbs(a: rot[1][2]);
176
177 const PxReal a20 = PxAbs(a: rot[2][0]);
178 const PxReal a21 = PxAbs(a: rot[2][1]);
179 const PxReal a22 = PxAbs(a: rot[2][2]);
180
181 const PxReal ex = extents.x;
182 const PxReal ey = extents.y;
183 const PxReal ez = extents.z;
184
185 return PxVec3( a00 * ex + a10 * ey + a20 * ez,
186 a01 * ex + a11 * ey + a21 * ez,
187 a02 * ex + a12 * ey + a22 * ez);
188 }
189
190 /**
191 Computes the obb points.
192 \param pts [out] 8 box points
193 */
194 PX_FORCE_INLINE void computeBoxPoints(PxVec3* PX_RESTRICT pts) const
195 {
196 Gu::computeOBBPoints(pts, center, extents, base0: rot.column0, base1: rot.column1, base2: rot.column2);
197 }
198
199 void create(const Gu::Capsule& capsule);
200
201 PxMat33 rot;
202 PxVec3 center;
203 PxVec3 extents;
204 };
205 PX_COMPILE_TIME_ASSERT(sizeof(Gu::Box) == 60);
206
207 //! A padded version of Gu::Box, to safely load its data using SIMD
208 class BoxPadded : public Box
209 {
210 public:
211 PX_FORCE_INLINE BoxPadded() {}
212 PX_FORCE_INLINE ~BoxPadded() {}
213 PxU32 padding;
214 };
215 PX_COMPILE_TIME_ASSERT(sizeof(Gu::BoxPadded) == 64);
216
217 //! Transforms a shape space AABB to a vertex space AABB (conservative).
218 PX_FORCE_INLINE void computeVertexSpaceAABB(Gu::Box& vertexSpaceOBB, const PxBounds3& worldBounds, const PxTransform& world2Shape, const Cm::FastVertex2ShapeScaling& scaling, bool idtScaleMesh)
219 {
220 PX_ASSERT(!worldBounds.isEmpty());
221 const PxBounds3 boundsInMesh = PxBounds3::transformFast(transform: world2Shape, bounds: worldBounds); // transform bounds from world to shape (excluding mesh scale)
222
223 vertexSpaceOBB.rot = PxMat33(PxIdentity);
224 if(idtScaleMesh)
225 {
226 vertexSpaceOBB.center = boundsInMesh.getCenter();
227 vertexSpaceOBB.extents = boundsInMesh.getExtents();
228 }
229 else
230 {
231 const PxBounds3 bounds = PxBounds3::basisExtent(center: scaling.getShape2VertexSkew() * boundsInMesh.getCenter(), basis: scaling.getShape2VertexSkew(), extent: boundsInMesh.getExtents());
232 vertexSpaceOBB.center = bounds.getCenter();
233 vertexSpaceOBB.extents = bounds.getExtents();
234 }
235 }
236
237#if PX_VC
238 #pragma warning(pop)
239#endif
240
241}
242
243}
244
245/** @} */
246#endif
247

source code of qtquick3dphysics/src/3rdparty/PhysX/source/geomutils/include/GuBox.h