RavEngine
Loading...
Searching...
No Matches
CmUtils.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef CM_UTILS_H
30#define CM_UTILS_H
31
32#include "foundation/PxVec3.h"
33#include "foundation/PxMat33.h"
34#include "foundation/PxBounds3.h"
35#include "common/PxBase.h"
36#include "foundation/PxInlineArray.h"
37#include "foundation/PxArray.h"
38#include "foundation/PxAllocator.h"
39#include "foundation/PxMemory.h"
40
41namespace physx
42{
43namespace Cm
44{
45
46template<class DstType, class SrcType>
47PX_FORCE_INLINE PxU32 getArrayOfPointers(DstType** PX_RESTRICT userBuffer, PxU32 bufferSize, PxU32 startIndex, SrcType*const* PX_RESTRICT src, PxU32 size)
48{
49 const PxU32 remainder = PxU32(PxMax<PxI32>(PxI32(size - startIndex), 0));
50 const PxU32 writeCount = PxMin(remainder, bufferSize);
51 src += startIndex;
52 for(PxU32 i=0;i<writeCount;i++)
53 userBuffer[i] = static_cast<DstType*>(src[i]);
54 return writeCount;
55}
56
57PX_CUDA_CALLABLE PX_INLINE void transformInertiaTensor(const PxVec3& invD, const PxMat33& M, PxMat33& mIInv)
58{
59 const float axx = invD.x*M(0,0), axy = invD.x*M(1,0), axz = invD.x*M(2,0);
60 const float byx = invD.y*M(0,1), byy = invD.y*M(1,1), byz = invD.y*M(2,1);
61 const float czx = invD.z*M(0,2), czy = invD.z*M(1,2), czz = invD.z*M(2,2);
62
63 mIInv(0,0) = axx*M(0,0) + byx*M(0,1) + czx*M(0,2);
64 mIInv(1,1) = axy*M(1,0) + byy*M(1,1) + czy*M(1,2);
65 mIInv(2,2) = axz*M(2,0) + byz*M(2,1) + czz*M(2,2);
66
67 mIInv(0,1) = mIInv(1,0) = axx*M(1,0) + byx*M(1,1) + czx*M(1,2);
68 mIInv(0,2) = mIInv(2,0) = axx*M(2,0) + byx*M(2,1) + czx*M(2,2);
69 mIInv(1,2) = mIInv(2,1) = axy*M(2,0) + byy*M(2,1) + czy*M(2,2);
70}
71
72// PT: TODO: refactor this with PxBounds3 header
73PX_FORCE_INLINE PxVec3 basisExtent(const PxVec3& basis0, const PxVec3& basis1, const PxVec3& basis2, const PxVec3& extent)
74{
75 // extended basis vectors
76 const PxVec3 c0 = basis0 * extent.x;
77 const PxVec3 c1 = basis1 * extent.y;
78 const PxVec3 c2 = basis2 * extent.z;
79
80 // find combination of base vectors that produces max. distance for each component = sum of abs()
81 return PxVec3 ( PxAbs(c0.x) + PxAbs(c1.x) + PxAbs(c2.x),
82 PxAbs(c0.y) + PxAbs(c1.y) + PxAbs(c2.y),
83 PxAbs(c0.z) + PxAbs(c1.z) + PxAbs(c2.z));
84}
85
86PX_FORCE_INLINE PxBounds3 basisExtent(const PxVec3& center, const PxVec3& basis0, const PxVec3& basis1, const PxVec3& basis2, const PxVec3& extent)
87{
88 const PxVec3 w = basisExtent(basis0, basis1, basis2, extent);
89 return PxBounds3(center - w, center + w);
90}
91
92PX_FORCE_INLINE bool isValid(const PxVec3& c, const PxVec3& e)
93{
94 return (c.isFinite() && e.isFinite() && (((e.x >= 0.0f) && (e.y >= 0.0f) && (e.z >= 0.0f)) ||
95 ((e.x == -PX_MAX_BOUNDS_EXTENTS) &&
96 (e.y == -PX_MAX_BOUNDS_EXTENTS) &&
97 (e.z == -PX_MAX_BOUNDS_EXTENTS))));
98}
99
100PX_FORCE_INLINE bool isEmpty(const PxVec3& c, const PxVec3& e)
101{
102 PX_UNUSED(c);
103 PX_ASSERT(isValid(c, e));
104 return e.x<0.0f;
105}
106
107// Array with externally managed storage.
108// Allocation and resize policy are managed by the owner,
109// Very minimal functionality right now, just POD types
110
111template <typename T,
112 typename Owner,
113 typename IndexType,
114 void (Owner::*realloc)(T*& currentMem, IndexType& currentCapacity, IndexType size, IndexType requiredMinCapacity)>
116{
117public:
118 OwnedArray()
119 : mData(0)
120 , mCapacity(0)
121 , mSize(0)
122 {}
123
124 ~OwnedArray() // owner must call releaseMem before destruction
125 {
126 PX_ASSERT(mCapacity==0);
127 }
128
129 void pushBack(T& element, Owner& owner)
130 {
131 // there's a failure case if here if we push an existing element which causes a resize -
132 // a rare case not worth coding around; if you need it, copy the element then push it.
133
134 PX_ASSERT(&element<mData || &element>=mData+mSize);
135 if(mSize==mCapacity)
136 (owner.*realloc)(mData, mCapacity, mSize, IndexType(mSize+1));
137
138 PX_ASSERT(mData && mSize<mCapacity);
139 mData[mSize++] = element;
140 }
141
142 IndexType size() const
143 {
144 return mSize;
145 }
146
147 void replaceWithLast(IndexType index)
148 {
149 PX_ASSERT(index<mSize);
150 mData[index] = mData[--mSize];
151 }
152
153 T* begin() const
154 {
155 return mData;
156 }
157
158 T* end() const
159 {
160 return mData+mSize;
161 }
162
163 T& operator [](IndexType index)
164 {
165 PX_ASSERT(index<mSize);
166 return mData[index];
167 }
168
169 const T& operator [](IndexType index) const
170 {
171 PX_ASSERT(index<mSize);
172 return mData[index];
173 }
174
175 void reserve(IndexType capacity, Owner &owner)
176 {
177 if(capacity>=mCapacity)
178 (owner.*realloc)(mData, mCapacity, mSize, capacity);
179 }
180
181 void releaseMem(Owner &owner)
182 {
183 mSize = 0;
184 (owner.*realloc)(mData, mCapacity, 0, 0);
185 }
186
187private:
188 T* mData;
189 IndexType mCapacity;
190 IndexType mSize;
191
192 // just in case someone tries to use a non-POD in here
193 union FailIfNonPod
194 {
195 T t;
196 int x;
197 };
198};
199
207template<typename T>
208PX_INLINE void deletePxBase(T* object)
209{
210 if(object->getBaseFlags() & PxBaseFlag::eOWNS_MEMORY)
211 {
212 PX_DELETE(object);
213 }
214 else
215 object->~T();
216}
217
218#define PX_PADDING_8 0xcd
219#define PX_PADDING_16 0xcdcd
220#define PX_PADDING_32 0xcdcdcdcd
221
222#if PX_CHECKED
227 #define PX_NEW_SERIALIZED(v,T) \
228 void* _buf = physx::PxReflectionAllocator<T>().allocate(sizeof(T),__FILE__,__LINE__); \
229 PxMarkSerializedMemory(_buf, sizeof(T)); \
230 v = PX_PLACEMENT_NEW(_buf, T)
231
232#else
233 #define PX_NEW_SERIALIZED(v,T) v = PX_NEW(T)
234#endif
235
236template<typename T, class Alloc>
238{
239 void store(PxSerializationContext& context) const
240 {
241 if(this->mData && (this->mSize || this->capacity()))
242 context.writeData(this->mData, this->capacity()*sizeof(T));
243 }
244
246 {
247 if(this->mData && (this->mSize || this->capacity()))
248 this->mData = context.readExtraData<T>(this->capacity());
249 }
250};
251
252template<typename T, typename Alloc>
253void exportArray(const PxArray<T, Alloc>& a, PxSerializationContext& context)
254{
255 static_cast<const ArrayAccess<T, Alloc>&>(a).store(context);
256}
257
258template<typename T, typename Alloc>
260{
261 static_cast<ArrayAccess<T, Alloc>&>(a).load(context);
262}
263
264template<typename T, PxU32 N, typename Alloc>
265void exportInlineArray(const PxInlineArray<T, N, Alloc>& a, PxSerializationContext& context)
266{
267 if(!a.isInlined())
268 Cm::exportArray(a, context);
269}
270
271template<typename T, PxU32 N, typename Alloc>
272void importInlineArray(PxInlineArray<T, N, Alloc>& a, PxDeserializationContext& context)
273{
274 if(!a.isInlined())
275 Cm::importArray(a, context);
276}
277
278template<class T>
279static PX_INLINE T* reserveContainerMemory(PxArray<T>& container, PxU32 nb)
280{
281 const PxU32 maxNbEntries = container.capacity();
282 const PxU32 requiredSize = container.size() + nb;
283
284 if(requiredSize>maxNbEntries)
285 {
286 const PxU32 naturalGrowthSize = maxNbEntries ? maxNbEntries*2 : 2;
287 const PxU32 newSize = PxMax(requiredSize, naturalGrowthSize);
288 container.reserve(newSize);
289 }
290
291 T* buf = container.end();
292 container.forceSize_Unsafe(requiredSize);
293 return buf;
294}
295
296} // namespace Cm
297
298
299
300}
301
302#endif
Definition base.h:1940
Definition CmUtils.h:116
Definition PxArray.h:53
Binary deserialization context class.
Definition PxSerialFramework.h:174
Binary serialization context class.
Definition PxSerialFramework.h:99
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_INLINE
Definition PxPreprocessor.h:320
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMax(T a, T b)
The return value is the greater of the two specified values.
Definition PxMath.h:72
PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMin(T a, T b)
The return value is the lesser of the two specified values.
Definition PxMath.h:88
Definition CmUtils.h:238