RavEngine
Loading...
Searching...
No Matches
PxMetaDataCompare.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 PX_METADATACOMPARE_H
30#define PX_METADATACOMPARE_H
31#include "PxMetaDataObjects.h"
32#include "foundation/PxInlineArray.h"
33
34//Implement a basic equality comparison system based on the meta data system.
35//if you implement a particular areequal specialized to exactly your type
36//before including this file it will be called in preference to the completely
37//generic one shown here.
38
39
40//If you don't care about the failure prop name you are welcome to pass in 'null',
41template<typename TBaseObjType>
42bool areEqual( const TBaseObjType& lhs, const TBaseObjType& rhs, const char** outFailurePropName );
43//We don't have the ability right now to handle these types.
44inline bool areEqual( const PxAggregate&, const PxAggregate& ) { return true; }
45inline bool areEqual( const PxSimulationFilterShader&, const PxSimulationFilterShader& ) { return true; }
46inline bool areEqual( const PxSimulationFilterCallback&, const PxSimulationFilterCallback& ) { return true; }
47inline bool areEqual( const PxConvexMesh&, const PxConvexMesh& ) { return true; }
48inline bool areEqual( const PxTriangleMesh&, const PxTriangleMesh& ) { return true; }
49inline bool areEqual( const PxTetrahedronMesh&, const PxTetrahedronMesh&) { return true; }
50inline bool areEqual( const PxParticleSystemGeometry&, const PxParticleSystemGeometry&) { return true; }
51inline bool areEqual( const PxBVH33TriangleMesh&, const PxBVH33TriangleMesh& ) { return true; }
52inline bool areEqual( const PxBVH34TriangleMesh&, const PxBVH34TriangleMesh& ) { return true; }
53inline bool areEqual( const PxHeightField&, const PxHeightField& ) { return true; }
54inline bool areEqual( const void* inLhs, const void* inRhs ) { return inLhs == inRhs; }
55inline bool areEqual( void* inLhs, void* inRhs ) { return inLhs == inRhs; }
56
57//Operators are copied, so this object needs to point
58//to the important data rather than reference or own it.
59template<typename TBaseObjType>
61{
62 bool* mVal;
63 const TBaseObjType* mLhs;
64 const TBaseObjType* mRhs;
65 const char** mFailurePropName;
66
67 EqualityOp( bool& inVal, const TBaseObjType& inLhs, const TBaseObjType& inRhs, const char*& inFailurePropName )
68 : mVal( &inVal )
69 , mLhs( &inLhs )
70 , mRhs( &inRhs )
71 , mFailurePropName( &inFailurePropName )
72 {
73 }
74
75 bool hasFailed() { return *mVal == false; }
76 //Ensure failure propagates the result a ways.
77 void update( bool inResult, const char* inName )
78 {
79 *mVal = *mVal && inResult;
80 if ( hasFailed() )
81 *mFailurePropName = inName;
82 }
83
84 //ignore any properties pointering back to the scene.
85 template<PxU32 TKey, typename TObjType>
86 void operator()( const PxReadOnlyPropertyInfo<TKey, TObjType, PxScene*> & inProp, PxU32 ) {}
87
88 template<PxU32 TKey, typename TObjType>
89 void operator()( const PxReadOnlyPropertyInfo<TKey, TObjType, const PxScene*> & inProp, PxU32 ) {}
90
91 //ignore any properties pointering back to the impl.
92 template<PxU32 TKey, typename TObjType>
93 void operator()(const PxReadOnlyPropertyInfo<TKey, TObjType, void*> & inProp, PxU32) {}
94
95 template<PxU32 TKey, typename TObjType>
96 void operator()(const PxReadOnlyPropertyInfo<TKey, TObjType, const void*> & inProp, PxU32) {}
97
98 //ignore all of these properties because they just point back to the 'this' object and cause
99 //a stack overflow.
100
101 //Children is unnecessary and articulation points back to the source.
102 void operator()( const PxReadOnlyCollectionPropertyInfo<PxPropertyInfoName::PxArticulationLink_Children, PxArticulationLink, PxArticulationLink* >& inProp, PxU32 ) {}
103 void operator()( const PxReadOnlyCollectionPropertyInfo<PxPropertyInfoName::PxRigidActor_Constraints, PxRigidActor, PxConstraint* >& inProp, PxU32 ){}
104 void operator()( const PxReadOnlyCollectionPropertyInfo<PxPropertyInfoName::PxAggregate_Actors, PxAggregate, PxActor* >& inProp, PxU32 ) {}
105
106 template<PxU32 TKey, typename TObjType, typename TGetPropType>
107 void operator()( const PxBufferCollectionPropertyInfo<TKey, TObjType, TGetPropType> & inProp, PxU32 )
108 {
109
110 }
111
112
113 template<PxU32 TKey, typename TObjType, typename TGetPropType>
114 void operator()( const PxReadOnlyPropertyInfo<TKey, TObjType, TGetPropType> & inProp, PxU32 )
115 {
116 if ( hasFailed() )
117 return;
118 TGetPropType lhs( inProp.get( mLhs ) );
119 TGetPropType rhs( inProp.get( mRhs ) );
120 update( areEqual( lhs, rhs, NULL ), inProp.mName );
121 }
122
123 template<PxU32 TKey, typename TObjType, typename TPropType>
124 void operator()( const PxRangePropertyInfo<TKey, TObjType, TPropType> & inProp, PxU32 )
125 {
126 if ( hasFailed() )
127 return;
128 TPropType lhsl, lhsr, rhsl, rhsr;
129 inProp.get( mLhs, lhsl, lhsr );
130 inProp.get( mRhs, rhsl, rhsr );
131 update( areEqual( lhsl, rhsl, NULL ), inProp.mName );
132 update( areEqual( lhsr, rhsr, NULL ), inProp.mName );
133 }
134
135 //Indexed properties where we don't know the range of index types are ignored
136 template<PxU32 TKey, typename TObjType, typename TIndexType, typename TPropType>
137 void compareIndex( const PxIndexedPropertyInfo<TKey, TObjType, TIndexType, TPropType> &, bool ) {}
138
139 template<PxU32 TKey, typename TObjType, typename TIndexType, typename TPropType>
140 void compareIndex( const PxIndexedPropertyInfo<TKey, TObjType, TIndexType, TPropType> &inProp, const PxU32ToName* inNames )
141 {
142 for ( const PxU32ToName* theName = inNames;
143 theName->mName != NULL && !hasFailed();
144 ++theName )
145 {
146 TIndexType theIndex( static_cast<TIndexType>( theName->mValue ) );
147 update( areEqual( inProp.get( mLhs, theIndex ), inProp.get( mRhs, theIndex ), NULL ), inProp.mName );
148 }
149 }
150
151 template<PxU32 TKey, typename TObjType, typename TIndexType, typename TPropType>
152 void operator()( const PxIndexedPropertyInfo<TKey, TObjType, TIndexType, TPropType> & inProp, PxU32 )
153 {
154 if ( hasFailed() )
155 return;
156 compareIndex( inProp, PxEnumTraits<TIndexType>().NameConversion );
157 }
158
159 template<PxU32 TKey, typename TObjType, typename TCollectionType>
160 void operator()( const PxReadOnlyCollectionPropertyInfo<TKey, TObjType, TCollectionType> & inProp, PxU32 )
161 {
162 if ( hasFailed() )
163 return;
166 PxU32 size = inProp.size( mLhs );
167 if ( size != inProp.size( mRhs ) )
168 update( false, inProp.mName );
169 else
170 {
171 lhsArray.resize( size );
172 rhsArray.resize( size );
173 inProp.get( mLhs, lhsArray.begin(), size );
174 inProp.get( mRhs, rhsArray.begin(), size );
175 for ( PxU32 idx =0; idx < size && !hasFailed(); ++idx )
176 update( areEqual( lhsArray[idx], rhsArray[idx], NULL ), inProp.mName );
177 }
178 }
179
180 //Filtered collections where we can't know the range of filter values are ignored.
181 template<PxU32 TKey, typename TObjType, typename TFilterType, typename TCollectionType>
182 void compare( const PxReadOnlyFilteredCollectionPropertyInfo< TKey, TObjType, TFilterType, TCollectionType >&, bool ) {}
183
184 template<PxU32 TKey, typename TObjType, typename TFilterType, typename TCollectionType>
185 void compare( const PxReadOnlyFilteredCollectionPropertyInfo< TKey, TObjType, TFilterType, TCollectionType >& inProp, const PxU32ToName* inNames )
186 {
187 //Exaustively compare all items.
190 for ( const PxU32ToName* theName = inNames;
191 theName->mName != NULL && !hasFailed();
192 ++theName )
193 {
194 TFilterType theFilter( static_cast<TFilterType>( theName->mValue ) );
195 PxU32 size = inProp.size( mLhs, theFilter );
196 if ( size != inProp.size( mRhs, theFilter ) )
197 update( false, inProp.mName );
198 else
199 {
200 lhsArray.resize( size );
201 rhsArray.resize( size );
202 inProp.get( mLhs, theFilter, lhsArray.begin(), size );
203 inProp.get( mRhs, theFilter, rhsArray.begin(), size );
204 for ( PxU32 idx =0; idx < size && !hasFailed(); ++idx )
205 update( areEqual( lhsArray[idx], rhsArray[idx], NULL ), inProp.mName );
206 }
207 }
208 }
209
210 template<PxU32 TKey, typename TObjType, typename TFilterType, typename TCollectionType>
211 void operator()( const PxReadOnlyFilteredCollectionPropertyInfo< TKey, TObjType, TFilterType, TCollectionType >& inProp, PxU32 )
212 {
213 if ( hasFailed() ) return;
214 compare( inProp, PxEnumTraits<TFilterType>().NameConversion );
215 }
216
217 template<typename TGeometryType, typename TPropertyType>
218 void compareGeometry( const TPropertyType& inProp )
219 {
220 TGeometryType lhs;
221 TGeometryType rhs;
222 bool lsuc = inProp.getGeometry( mLhs, lhs );
223 bool rsuc = inProp.getGeometry( mRhs, rhs );
224 if ( !( lsuc && rsuc ) )
225 update( false, inProp.mName );
226 else
227 update( areEqual( lhs, rhs, NULL ), inProp.mName );
228 }
229
230 void operator()( const PxShapeGeomProperty& inProp, PxU32 )
231 {
232 if ( hasFailed() )
233 return;
234 PxGeometryType::Enum lhsType( inProp.getGeometryType( mLhs ) );
235 PxGeometryType::Enum rhsType( inProp.getGeometryType( mRhs ) );
236 if ( lhsType != rhsType )
237 update( false, inProp.mName );
238 else
239 {
240 switch( lhsType )
241 {
242 case PxGeometryType::eSPHERE: compareGeometry<PxSphereGeometry>(inProp); break;
243 case PxGeometryType::ePLANE: compareGeometry<PxPlaneGeometry>(inProp); break;
244 case PxGeometryType::eCAPSULE: compareGeometry<PxCapsuleGeometry>(inProp); break;
245 case PxGeometryType::eBOX: compareGeometry<PxBoxGeometry>(inProp); break;
246 case PxGeometryType::eCONVEXMESH: compareGeometry<PxConvexMeshGeometry>(inProp); break;
247 case PxGeometryType::eTETRAHEDRONMESH: compareGeometry<PxTetrahedronMeshGeometry>(inProp); break;
248 case PxGeometryType::ePARTICLESYSTEM: compareGeometry<PxParticleSystemGeometry>(inProp); break;
249 case PxGeometryType::eTRIANGLEMESH: compareGeometry<PxTriangleMeshGeometry>(inProp); break;
250 case PxGeometryType::eHEIGHTFIELD: compareGeometry<PxHeightFieldGeometry>(inProp); break;
251 default: PX_ASSERT( false ); break;
252 }
253 }
254 }
255};
256
257inline bool areEqual( const char* lhs, const char* rhs, const char**, const PxUnknownClassInfo& )
258{
259 if ( lhs && rhs ) return Pxstrcmp( lhs, rhs ) == 0;
260 if ( lhs || rhs ) return false;
261 return true;
262}
263
264inline bool areEqual( PxReal inLhs, PxReal inRhs )
265{
266 return PxAbs( inLhs - inRhs ) < 1e-5f;
267}
268
269inline bool areEqual( PxVec3& lhs, PxVec3& rhs )
270{
271 return areEqual( lhs.x, rhs.x )
272 && areEqual( lhs.y, rhs.y )
273 && areEqual( lhs.z, rhs.z );
274}
275
276inline bool areEqual( const PxVec3& lhs, const PxVec3& rhs )
277{
278 return areEqual( lhs.x, rhs.x )
279 && areEqual( lhs.y, rhs.y )
280 && areEqual( lhs.z, rhs.z );
281}
282
283inline bool areEqual( const PxVec4& lhs, const PxVec4& rhs )
284{
285 return areEqual( lhs.x, rhs.x )
286 && areEqual( lhs.y, rhs.y )
287 && areEqual( lhs.z, rhs.z )
288 && areEqual( lhs.w, rhs.w );
289}
290
291inline bool areEqual( const PxQuat& lhs, const PxQuat& rhs )
292{
293 return areEqual( lhs.x, rhs.x )
294 && areEqual( lhs.y, rhs.y )
295 && areEqual( lhs.z, rhs.z )
296 && areEqual( lhs.w, rhs.w );
297}
298
299
300inline bool areEqual( const PxTransform& lhs, const PxTransform& rhs )
301{
302 return areEqual(lhs.p, rhs.p) && areEqual(lhs.q, rhs.q);
303}
304
305
306inline bool areEqual( const PxBounds3& inLhs, const PxBounds3& inRhs )
307{
308 return areEqual(inLhs.minimum,inRhs.minimum)
309 && areEqual(inLhs.maximum,inRhs.maximum);
310}
311
312inline bool areEqual( const PxMetaDataPlane& lhs, const PxMetaDataPlane& rhs )
313{
314 return areEqual( lhs.normal.x, rhs.normal.x )
315 && areEqual( lhs.normal.y, rhs.normal.y )
316 && areEqual( lhs.normal.z, rhs.normal.z )
317 && areEqual( lhs.distance, rhs.distance );
318}
319
320template<typename TBaseObjType>
321inline bool areEqual( const TBaseObjType& lhs, const TBaseObjType& rhs )
322{
323 return lhs == rhs;
324}
325
326//If we don't know the class type, we must result in == operator
327template<typename TBaseObjType>
328inline bool areEqual( const TBaseObjType& lhs, const TBaseObjType& rhs, const char**, const PxUnknownClassInfo& )
329{
330 return areEqual( lhs, rhs );
331}
332
333//If we don't know the class type, we must result in == operator
334template<typename TBaseObjType, typename TTraitsType>
335inline bool areEqual( const TBaseObjType& lhs, const TBaseObjType& rhs, const char** outFailurePropName, const TTraitsType& )
336{
337 const char* theFailureName = NULL;
338 bool result = true;
339 static int i = 0;
340 ++i;
341 visitAllProperties<TBaseObjType>( EqualityOp<TBaseObjType>( result, lhs, rhs, theFailureName ) );
342 if ( outFailurePropName != NULL && theFailureName )
343 *outFailurePropName = theFailureName;
344 return result;
345}
346
347
348template<typename TBaseObjType>
349inline bool areEqualPointerCheck( const TBaseObjType& lhs, const TBaseObjType& rhs, const char** outFailurePropName, int )
350{
351 return areEqual( lhs, rhs, outFailurePropName, PxClassInfoTraits<TBaseObjType>().Info );
352}
353
354inline bool areEqualPointerCheck( const void* lhs, const void* rhs, const char**, bool )
355{
356 return lhs == rhs;
357}
358
359inline bool areEqualPointerCheck( const char* lhs, const char* rhs, const char** outFailurePropName, bool )
360{
361 bool bRet = true;
362 if ( lhs && rhs ) bRet = Pxstrcmp( lhs, rhs ) == 0;
363 else if ( lhs || rhs ) bRet = false;
364
365 return bRet;
366}
367
368inline bool areEqualPointerCheck( void* lhs, void* rhs, const char**, bool )
369{
370 return lhs == rhs;
371}
372
373template<typename TBaseObjType>
374inline bool areEqualPointerCheck( const TBaseObjType& lhs, const TBaseObjType& rhs, const char** outFailurePropName, bool )
375{
376 if ( lhs && rhs )
377 return areEqual( *lhs, *rhs, outFailurePropName );
378 if ( lhs || rhs )
379 return false;
380 return true;
381}
382
383template < typename Tp >
384struct is_pointer { static const int val = 0; };
385
386template < typename Tp >
387struct is_pointer<Tp*> { static const bool val = true; };
388
389
390template<typename TBaseObjType>
391inline bool areEqual( const TBaseObjType& lhs, const TBaseObjType& rhs, const char** outFailurePropName )
392{
393 return areEqualPointerCheck( lhs, rhs, outFailurePropName, is_pointer<TBaseObjType>::val );
394}
395
396#endif
PX_NOINLINE void resize(const uint32_t size, const T &a=T())
Definition PxArray.h:637
PX_FORCE_INLINE ConstIterator begin() const
Definition PxArray.h:176
Definition PxInlineArray.h:43
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
Definition PxMetaDataCompare.h:61
Definition PxMetaDataCompare.h:384