1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
11// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
12
13
14#ifndef PX_PHYSICS_GEOMETRYHELPERS
15#define PX_PHYSICS_GEOMETRYHELPERS
16/** \addtogroup geomutils
17@{
18*/
19
20#include "common/PxPhysXCommonConfig.h"
21#include "PxGeometry.h"
22#include "PxBoxGeometry.h"
23#include "PxSphereGeometry.h"
24#include "PxCapsuleGeometry.h"
25#include "PxPlaneGeometry.h"
26#include "PxConvexMeshGeometry.h"
27#include "PxTriangleMeshGeometry.h"
28#include "PxHeightFieldGeometry.h"
29#include "foundation/PxPlane.h"
30#include "foundation/PxTransform.h"
31#include "foundation/PxUnionCast.h"
32
33#ifndef PX_DOXYGEN
34namespace physx
35{
36#endif
37
38/**
39\brief Geometry holder class
40
41This class contains enough space to hold a value of any PxGeometry subtype.
42
43Its principal use is as a convenience class to allow geometries to be returned polymorphically
44from functions. See PxShape::getGeometry();
45*/
46
47PX_ALIGN_PREFIX(4)
48class PxGeometryHolder
49{
50public:
51 PX_FORCE_INLINE PxGeometryType::Enum getType() const
52 {
53 return any().getType();
54 }
55
56 PX_FORCE_INLINE PxGeometry& any()
57 {
58 return *PxUnionCast<PxGeometry*>(&bytes.geometry);
59 }
60
61 PX_FORCE_INLINE const PxGeometry& any() const
62 {
63 return *PxUnionCast<const PxGeometry*>(&bytes.geometry);
64 }
65
66 PX_FORCE_INLINE PxSphereGeometry& sphere()
67 {
68 return get<PxSphereGeometry, PxGeometryType::eSPHERE>();
69 }
70
71 PX_FORCE_INLINE const PxSphereGeometry& sphere() const
72 {
73 return get<const PxSphereGeometry, PxGeometryType::eSPHERE>();
74 }
75
76 PX_FORCE_INLINE PxPlaneGeometry& plane()
77 {
78 return get<PxPlaneGeometry, PxGeometryType::ePLANE>();
79 }
80
81 PX_FORCE_INLINE const PxPlaneGeometry& plane() const
82 {
83 return get<const PxPlaneGeometry, PxGeometryType::ePLANE>();
84 }
85
86
87 PX_FORCE_INLINE PxCapsuleGeometry& capsule()
88 {
89 return get<PxCapsuleGeometry, PxGeometryType::eCAPSULE>();
90 }
91
92 PX_FORCE_INLINE const PxCapsuleGeometry& capsule() const
93 {
94 return get<const PxCapsuleGeometry, PxGeometryType::eCAPSULE>();
95 }
96
97
98 PX_FORCE_INLINE PxBoxGeometry& box()
99 {
100 return get<PxBoxGeometry, PxGeometryType::eBOX>();
101 }
102
103 PX_FORCE_INLINE const PxBoxGeometry& box() const
104 {
105 return get<const PxBoxGeometry, PxGeometryType::eBOX>();
106 }
107
108 PX_FORCE_INLINE PxConvexMeshGeometry& convexMesh()
109 {
110 return get<PxConvexMeshGeometry, PxGeometryType::eCONVEXMESH>();
111 }
112
113 PX_FORCE_INLINE const PxConvexMeshGeometry& convexMesh() const
114 {
115 return get<const PxConvexMeshGeometry, PxGeometryType::eCONVEXMESH>();
116 }
117
118
119 PX_FORCE_INLINE PxTriangleMeshGeometry& triangleMesh()
120 {
121 return get<PxTriangleMeshGeometry, PxGeometryType::eTRIANGLEMESH>();
122 }
123
124 PX_FORCE_INLINE const PxTriangleMeshGeometry& triangleMesh() const
125 {
126 return get<const PxTriangleMeshGeometry, PxGeometryType::eTRIANGLEMESH>();
127 }
128
129 PX_FORCE_INLINE PxHeightFieldGeometry& heightField()
130 {
131 return get<PxHeightFieldGeometry, PxGeometryType::eHEIGHTFIELD>();
132 }
133
134 PX_FORCE_INLINE const PxHeightFieldGeometry& heightField() const
135 {
136 return get<const PxHeightFieldGeometry, PxGeometryType::eHEIGHTFIELD>();
137 }
138
139 PX_FORCE_INLINE void storeAny(const PxGeometry& geometry)
140 {
141 switch(geometry.getType())
142 {
143 case PxGeometryType::eSPHERE: put<PxSphereGeometry>(geometry); break;
144 case PxGeometryType::ePLANE: put<PxPlaneGeometry>(geometry); break;
145 case PxGeometryType::eCAPSULE: put<PxCapsuleGeometry>(geometry); break;
146 case PxGeometryType::eBOX: put<PxBoxGeometry>(geometry); break;
147 case PxGeometryType::eCONVEXMESH: put<PxConvexMeshGeometry>(geometry); break;
148 case PxGeometryType::eTRIANGLEMESH: put<PxTriangleMeshGeometry>(geometry); break;
149 case PxGeometryType::eHEIGHTFIELD: put<PxHeightFieldGeometry>(geometry); break;
150 case PxGeometryType::eGEOMETRY_COUNT:
151 case PxGeometryType::eINVALID:
152 default:
153 PX_ASSERT(0);
154 }
155 }
156
157 private:
158 template<typename T> void put(const PxGeometry& geometry)
159 {
160 static_cast<T&>(any()) = static_cast<const T&>(geometry);
161 }
162
163
164 template<typename T, PxGeometryType::Enum type> T& get()
165 {
166 PX_ASSERT(getType() == type);
167 return static_cast<T&>(any());
168 }
169
170 template<typename T, PxGeometryType::Enum type> T& get() const
171 {
172 PX_ASSERT(getType() == type);
173 return static_cast<T&>(any());
174 }
175
176
177 union {
178 PxU8 geometry[sizeof(PxGeometry)];
179 PxU8 box[sizeof(PxBoxGeometry)];
180 PxU8 sphere[sizeof(PxSphereGeometry)];
181 PxU8 capsule[sizeof(PxCapsuleGeometry)];
182 PxU8 plane[sizeof(PxPlaneGeometry)];
183 PxU8 convex[sizeof(PxConvexMeshGeometry)];
184 PxU8 mesh[sizeof(PxTriangleMeshGeometry)];
185 PxU8 heightfield[sizeof(PxHeightFieldGeometry)];
186 } bytes;
187}
188PX_ALIGN_SUFFIX(4);
189
190
191
192
193#ifndef PX_DOXYGEN
194} // namespace physx
195#endif
196
197/** @} */
198#endif
199