RavEngine
Loading...
Searching...
No Matches
SnXmlVisitorReader.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 SN_XML_VISITOR_READER_H
30#define SN_XML_VISITOR_READER_H
31
32#include "foundation/PxArray.h"
33#include "foundation/PxUtilities.h"
34#include "RepXMetaDataPropertyVisitor.h"
35#include "SnPxStreamOperators.h"
36#include "SnXmlMemoryPoolStreams.h"
37#include "SnXmlReader.h"
38#include "SnXmlImpl.h"
39#include "SnXmlMemoryAllocator.h"
40#include "SnXmlStringToType.h"
41
42namespace physx { namespace Sn {
43
44
45 inline PxU32 findEnumByName( const char* inName, const PxU32ToName* inTable )
46 {
47 for ( PxU32 idx = 0; inTable[idx].mName != NULL; ++idx )
48 {
49 if ( physx::Pxstricmp( inTable[idx].mName, inName ) == 0 )
50 return inTable[idx].mValue;
51 }
52 return 0;
53 }
54
55 PX_INLINE void stringToFlagsType( const char* strData, XmlMemoryAllocator& alloc, PxU32& ioType, const PxU32ToName* inTable )
56 {
57 if ( inTable == NULL )
58 return;
59 ioType = 0;
60 if ( strData && *strData)
61 {
62 //Destructively parse the string to get out the different flags.
63 char* theValue = const_cast<char*>( copyStr( &alloc, strData ) );
64 char* theMarker = theValue;
65 char* theNext = theValue;
66 while( theNext && *theNext )
67 {
68 ++theNext;
69 if( *theNext == '|' )
70 {
71 *theNext = 0;
72 ++theNext;
73 ioType |= static_cast< PxU32 > ( findEnumByName( theMarker, inTable ) );
74 theMarker = theNext;
75 }
76 }
77 if ( theMarker && *theMarker )
78 ioType |= static_cast< PxU32 > ( findEnumByName( theMarker, inTable ) );
79 alloc.deallocate( reinterpret_cast<PxU8*>( theValue ) );
80 }
81 }
82
83 template<typename TDataType>
84 PX_INLINE void stringToEnumType( const char* strData, TDataType& ioType, const PxU32ToName* inTable )
85 {
86 ioType = static_cast<TDataType>( findEnumByName( strData, inTable ) );
87 }
88
89 template<typename TDataType>
90 PX_INLINE bool readProperty( XmlReader& inReader, const char* pname, TDataType& ioType )
91 {
92 const char* value;
93 if ( inReader.read( pname, value ) )
94 {
95 stringToType( value, ioType );
96 return true;
97 }
98 return false;
99 }
100
101 template<typename TObjType>
102 inline TObjType* findReferencedObject( PxCollection& collection, PxSerialObjectId id)
103 {
104 PX_ASSERT(id > 0);
105 TObjType* outObject = static_cast<TObjType*>(const_cast<PxBase*>(collection.find(id)));
106 if (outObject == NULL)
107 {
108 PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
109 "PxSerialization::createCollectionFromXml: "
110 "Reference to ID %d cannot be resolved. Make sure externalRefs collection is specified if required and "
111 "check Xml file for completeness.",
112 id);
113 }
114 return outObject;
115 }
116
117 template<typename TObjType>
118 inline bool readReference( XmlReader& inReader, PxCollection& collection, TObjType*& outObject )
119 {
120 PxSerialObjectId theId;
121 const char* theValue = inReader.getCurrentItemValue();
122 strto( theId, theValue );
123 if( theId == 0)
124 {
125 // the NULL pointer is a valid pointer if the input id is 0
126 outObject = NULL;
127 return true;
128 }
129 else
130 {
131 outObject = findReferencedObject<TObjType>(collection, theId);
132 return outObject != NULL;
133 }
134 }
135
136 template<typename TObjType>
137 inline bool readReference( XmlReader& inReader, PxCollection& inCollection, const char* pname, TObjType*& outObject )
138 {
139 outObject = NULL;
140 PxSerialObjectId theId = 0;
141 if (readProperty ( inReader, pname, theId ) && theId )
142 {
143 outObject = findReferencedObject<TObjType>(inCollection, theId);
144 }
145 // the NULL pointer is a valid pointer if the input id is 0
146 return (outObject != NULL) || 0 == theId;
147 }
148
149 template<typename TEnumType, typename TStorageType>
150 inline bool readFlagsProperty( XmlReader& reader, XmlMemoryAllocator& allocator, const char* pname, const PxU32ToName* inConversions, PxFlags<TEnumType,TStorageType>& outFlags )
151 {
152 const char* value;
153 if ( reader.read( pname, value ) )
154 {
155 PxU32 tempValue = 0;
156 stringToFlagsType( value, allocator, tempValue, inConversions );
157 outFlags = PxFlags<TEnumType,TStorageType>(PxTo16(tempValue) );
158 return true;
159 }
160 return false;
161 }
162
163 template<typename TObjType, typename TReaderType, typename TInfoType>
164 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, TInfoType& info);
165 template<typename TObjType, typename TReaderType>
166 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj);
167
168 template<typename TReaderType, typename TGeomType>
169 inline PxGeometry* parseGeometry( TReaderType& reader, TGeomType& /*inGeom*/)
170 {
171 PxAllocatorCallback& inAllocator = reader.mAllocator.getAllocator();
172
173 TGeomType* shape = PX_PLACEMENT_NEW((inAllocator.allocate(sizeof(TGeomType), "parseGeometry", __FILE__, __LINE__ )), TGeomType);
174 PxClassInfoTraits<TGeomType> info;
175 readComplexObj( reader, shape);
176 return shape;
177 }
178
179
180 template<typename TReaderType>
181 inline void parseShape( TReaderType& visitor, PxGeometry*& outResult, PxArray<PxMaterial*>& outMaterials)
182 {
183 XmlReader& theReader( visitor.mReader );
184 PxCollection& collection = visitor.mCollection;
185 visitor.pushCurrentContext();
186 if ( visitor.gotoTopName() )
187 {
188 visitor.pushCurrentContext();
189 if ( visitor.gotoChild( "Materials" ) )
190 {
191 for( bool matSuccess = visitor.gotoFirstChild(); matSuccess;
192 matSuccess = visitor.gotoNextSibling() )
193 {
194 PxMaterial* material = NULL;
195 if(!readReference<PxMaterial>( theReader, collection, material ))
196 visitor.mHadError = true;
197 if ( material )
198 outMaterials.pushBack( material );
199 }
200 }
201 visitor.popCurrentContext();
202 visitor.pushCurrentContext();
203
204 PxPlaneGeometry plane;
205 PxHeightFieldGeometry heightField;
206 PxSphereGeometry sphere;
207 PxTriangleMeshGeometry mesh;
208 PxConvexMeshGeometry convex;
209 PxBoxGeometry box;
210 PxCapsuleGeometry capsule;
211 if ( visitor.gotoChild( "Geometry" ) )
212 {
213 if ( visitor.gotoFirstChild() )
214 {
215 const char* geomTypeName = visitor.getCurrentItemName();
216
217 if ( physx::Pxstricmp( geomTypeName, "PxSphereGeometry" ) == 0 ) outResult = parseGeometry(visitor, sphere);
218 else if ( physx::Pxstricmp( geomTypeName, "PxPlaneGeometry" ) == 0 ) outResult = parseGeometry(visitor, plane);
219 else if ( physx::Pxstricmp( geomTypeName, "PxCapsuleGeometry" ) == 0 ) outResult = parseGeometry(visitor, capsule);
220 else if ( physx::Pxstricmp( geomTypeName, "PxBoxGeometry" ) == 0 ) outResult = parseGeometry(visitor, box);
221 else if ( physx::Pxstricmp( geomTypeName, "PxConvexMeshGeometry" ) == 0 ) outResult = parseGeometry(visitor, convex);
222 else if ( physx::Pxstricmp( geomTypeName, "PxTriangleMeshGeometry" ) == 0 ) outResult = parseGeometry(visitor, mesh);
223 else if ( physx::Pxstricmp( geomTypeName, "PxHeightFieldGeometry" ) == 0 ) outResult = parseGeometry(visitor, heightField);
224 else
225 PX_ASSERT( false );
226 }
227 }
228 visitor.popCurrentContext();
229 }
230 visitor.popCurrentContext();
231
232 return;
233 }
234
235 template<typename TReaderType, typename TObjType>
236 inline void readShapesProperty( TReaderType& visitor, TObjType* inObj, const PxRigidActorShapeCollection* inProp = NULL, bool isSharedShape = false )
237 {
238 PX_UNUSED(isSharedShape);
239 PX_UNUSED(inProp);
240
241 XmlReader& theReader( visitor.mReader );
242 PxCollection& collection( visitor.mCollection );
243
244 visitor.pushCurrentContext();
245 if ( visitor.gotoTopName() )
246 {
247 //uggh working around the shape collection api.
248 //read out materials and geometry
249 for ( bool success = visitor.gotoFirstChild(); success;
250 success = visitor.gotoNextSibling() )
251 {
252 if( 0 == physx::Pxstricmp( visitor.getCurrentItemName(), "PxShapeRef" ) )
253 {
254 PxShape* shape = NULL;
255 if(!readReference<PxShape>( theReader, collection, shape ))
256 visitor.mHadError = true;
257 if(shape)
258 inObj->attachShape( *shape );
259 }
260 else
261 {
262 PxArray<PxMaterial*> materials;
263 PxGeometry* geometry = NULL;
264 parseShape( visitor, geometry, materials);
265 PxShape* theShape = NULL;
266 if ( materials.size() )
267 {
268 theShape = visitor.mArgs.physics.createShape( *geometry, materials.begin(), PxTo16(materials.size()), true );
269 if ( theShape )
270 {
271 readComplexObj( visitor, theShape );
272
273 if(theShape)
274 {
275 inObj->attachShape(*theShape);
276 collection.add( *theShape );
277 }
278 }
279 }
280
281 switch(geometry->getType())
282 {
283 case PxGeometryType::eSPHERE :
284 static_cast<PxSphereGeometry*>(geometry)->~PxSphereGeometry();
285 break;
286 case PxGeometryType::ePLANE :
287 static_cast<PxPlaneGeometry*>(geometry)->~PxPlaneGeometry();
288 break;
289 case PxGeometryType::eCAPSULE :
290 static_cast<PxCapsuleGeometry*>(geometry)->~PxCapsuleGeometry();
291 break;
292 case PxGeometryType::eBOX :
293 static_cast<PxBoxGeometry*>(geometry)->~PxBoxGeometry();
294 break;
295 case PxGeometryType::eCONVEXMESH :
296 static_cast<PxConvexMeshGeometry*>(geometry)->~PxConvexMeshGeometry();
297 break;
298 case PxGeometryType::eTRIANGLEMESH :
299 static_cast<PxTriangleMeshGeometry*>(geometry)->~PxTriangleMeshGeometry();
300 break;
301 case PxGeometryType::eHEIGHTFIELD :
302 static_cast<PxHeightFieldGeometry*>(geometry)->~PxHeightFieldGeometry();
303 break;
304 case PxGeometryType::eTETRAHEDRONMESH :
305 static_cast<PxTetrahedronMeshGeometry*>(geometry)->~PxTetrahedronMeshGeometry();
306 break;
307 case PxGeometryType::ePARTICLESYSTEM:
308 static_cast<PxParticleSystemGeometry*>(geometry)->~PxParticleSystemGeometry();
309 break;
310 case PxGeometryType::eHAIRSYSTEM:
311 static_cast<PxHairSystemGeometry*>(geometry)->~PxHairSystemGeometry();
312 break;
313 case PxGeometryType::eCUSTOM :
314 static_cast<PxCustomGeometry*>(geometry)->~PxCustomGeometry();
315 break;
316
319 PX_ASSERT(0);
320 }
321 visitor.mAllocator.getAllocator().deallocate(geometry);
322 }
323 }
324 }
325 visitor.popCurrentContext();
326 }
327
329 {
330 bool mValid;
331 ReaderNameStackEntry( const char* nm, bool valid ) : NameStackEntry(nm), mValid(valid) {}
332 };
333
335
336 template<typename TObjType>
338 {
339
340 protected:
342 public:
343 TReaderNameStack& mNames;
344 PxProfileArray<PxU32>& mContexts;
346 XmlReader& mReader;
347 TObjType* mObj;
348 XmlMemoryAllocator& mAllocator;
349 PxCollection& mCollection;
350 bool mValid;
351 bool& mHadError;
352
353 RepXVisitorReaderBase( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, TObjType* obj
354 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& hadError )
355 : mNames( names )
356 , mContexts( contexts )
357 , mArgs( args )
358 , mReader( reader )
359 , mObj( obj )
360 , mAllocator( alloc )
361 , mCollection( collection )
362 , mValid( true )
363 , mHadError(hadError)
364 {
365 }
367 : mNames( other.mNames )
368 , mContexts( other.mContexts )
369 , mArgs( other.mArgs )
370 , mReader( other.mReader )
371 , mObj( other.mObj )
372 , mAllocator( other.mAllocator )
373 , mCollection( other.mCollection )
374 , mValid( other.mValid )
375 , mHadError( other.mHadError )
376 {
377 }
378
379
380 void pushName( const char* name )
381 {
382 gotoTopName();
383 mNames.pushBack( ReaderNameStackEntry( name, mValid ) );
384 }
385 void pushBracketedName( const char* name ) { pushName( name ); }
386 void popName()
387 {
388 if ( mNames.size() )
389 {
390 if ( mNames.back().mOpen && mNames.back().mValid )
391 mReader.leaveChild();
392 mNames.popBack();
393 }
394 mValid =true;
395 if ( mNames.size() && mNames.back().mValid == false )
396 mValid = false;
397 }
398
399 void pushCurrentContext()
400 {
401 mContexts.pushBack( static_cast<PxU32>( mNames.size() ) );
402 }
403 void popCurrentContext()
404 {
405 if ( mContexts.size() )
406 {
407 PxU32 depth = mContexts.back();
408 PX_ASSERT( mNames.size() >= depth );
409 while( mNames.size() > depth )
410 popName();
411 mContexts.popBack();
412 }
413 }
414
415 bool updateLastEntryAfterOpen()
416 {
417 mNames.back().mValid = mValid;
418 mNames.back().mOpen = mValid;
419 return mValid;
420 }
421
422 bool gotoTopName()
423 {
424 if ( mNames.size() && mNames.back().mOpen == false )
425 {
426 if ( mValid )
427 mValid = mReader.gotoChild( mNames.back().mName );
428 updateLastEntryAfterOpen();
429 }
430 return mValid;
431 }
432
433 bool isValid() const { return mValid; }
434
435 bool gotoChild( const char* name )
436 {
437 pushName( name );
438 return gotoTopName();
439 }
440
441 bool gotoFirstChild()
442 {
443 pushName( "__child" );
444 if ( mValid ) mValid = mReader.gotoFirstChild();
445 return updateLastEntryAfterOpen();
446 }
447
448 bool gotoNextSibling()
449 {
450 bool retval = mValid;
451 if ( mValid ) retval = mReader.gotoNextSibling();
452 return retval;
453 }
454
455 const char* getCurrentItemName() { if (mValid ) return mReader.getCurrentItemName(); return ""; }
456
457 const char* topName() const
458 {
459 if ( mNames.size() ) return mNames.back().mName;
460 PX_ASSERT( false );
461 return "bad__repx__name";
462 }
463
464 const char* getCurrentValue()
465 {
466 const char* value = NULL;
467 if ( isValid() && mReader.read( topName(), value ) )
468 return value;
469 return NULL;
470 }
471
472 template<typename TDataType>
473 bool readProperty(TDataType& outType)
474 {
475 const char* value = getCurrentValue();
476 if ( value && *value )
477 {
478 stringToType( value, outType );
479 return true;
480 }
481 return false;
482 }
483
484 template<typename TDataType>
485 bool readExtendedIndexProperty(TDataType& outType)
486 {
487 const char* value = mReader.getCurrentItemValue();
488 if ( value && *value )
489 {
490 stringToType( value, outType );
491 return true;
492 }
493 return false;
494 }
495
496
497 template<typename TRefType>
498 bool readReference(TRefType*& outRef)
499 {
500 return physx::Sn::readReference<TRefType>( mReader, mCollection, topName(), outRef );
501 }
502
503 inline bool readProperty(const char*& outProp )
504 {
505 outProp = "";
506 const char* value = getCurrentValue();
507 if ( value && *value && mArgs.stringTable )
508 {
509 outProp = mArgs.stringTable->allocateStr( value );
510 return true;
511 }
512 return false;
513 }
514
515 inline bool readProperty(PxConvexMesh*& outProp )
516 {
517 return readReference<PxConvexMesh>( outProp );
518 }
519
520 inline bool readProperty(PxTriangleMesh*& outProp )
521 {
522 return readReference<PxTriangleMesh>( outProp );
523 }
524 inline bool readProperty(PxBVH33TriangleMesh*& outProp )
525 {
526 return readReference<PxBVH33TriangleMesh>( outProp );
527 }
528 inline bool readProperty(PxBVH34TriangleMesh*& outProp )
529 {
530 return readReference<PxBVH34TriangleMesh>( outProp );
531 }
532
533 inline bool readProperty(PxHeightField*& outProp )
534 {
535 return readReference<PxHeightField>( outProp );
536 }
537
538 inline bool readProperty( PxRigidActor *& outProp )
539 {
540 return readReference<PxRigidActor>( outProp );
541 }
542
543 template<typename TAccessorType>
544 void simpleProperty( PxU32 /*key*/, TAccessorType& inProp )
545 {
546 typedef typename TAccessorType::prop_type TPropertyType;
547 TPropertyType value;
548 if ( readProperty( value ) )
549 inProp.set( mObj, value );
550 }
551
552 template<typename TAccessorType>
553 void enumProperty( PxU32 /*key*/, TAccessorType& inProp, const PxU32ToName* inConversions )
554 {
555 typedef typename TAccessorType::prop_type TPropertyType;
556 const char* strVal = getCurrentValue();
557 if ( strVal && *strVal )
558 {
559 TPropertyType pval;
560 stringToEnumType( strVal, pval, inConversions );
561 inProp.set( mObj, pval );
562 }
563 }
564
565 template<typename TAccessorType>
566 void flagsProperty( PxU32 /*key*/, const TAccessorType& inProp, const PxU32ToName* inConversions )
567 {
568 typedef typename TAccessorType::prop_type TPropertyType;
569 typedef typename TPropertyType::InternalType TInternalType;
570
571 const char* strVal = getCurrentValue();
572 if ( strVal && *strVal )
573 {
574 PxU32 tempValue = 0;
575 stringToFlagsType( strVal, mAllocator, tempValue, inConversions );
576 inProp.set( mObj, TPropertyType(TInternalType( tempValue )));
577 }
578 }
579
580 template<typename TAccessorType, typename TInfoType>
581 void complexProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo )
582 {
583 typedef typename TAccessorType::prop_type TPropertyType;
584 if ( gotoTopName() )
585 {
586 TPropertyType propVal = inProp.get( mObj );
587 readComplexObj( *this, &propVal, inInfo );
588 inProp.set( mObj, propVal );
589 }
590 }
591
592 template<typename TAccessorType, typename TInfoType>
593 void bufferCollectionProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo )
594 {
595 typedef typename TAccessorType::prop_type TPropertyType;
597
598 this->pushCurrentContext();
599 if ( this->gotoTopName() )
600 {
601 for ( bool success = this->gotoFirstChild(); success;
602 success = this->gotoNextSibling() )
603 {
604 TPropertyType propVal;
605 readComplexObj( *this, &propVal, inInfo );
606 theData.pushBack(propVal);
607 }
608 }
609 this->popCurrentContext();
610
611 inProp.set( mObj, theData.begin(), theData.size() );
612
613 }
614
615 template<typename TAccessorType, typename TInfoType>
616 void extendedIndexedProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo )
617 {
618 typedef typename TAccessorType::prop_type TPropertyType;
619
620 this->pushCurrentContext();
621 if ( this->gotoTopName() )
622 {
623 PxU32 index = 0;
624 for ( bool success = this->gotoFirstChild(); success;
625 success = this->gotoNextSibling() )
626 {
627 TPropertyType propVal;
628 readComplexObj( *this, &propVal, inInfo );
629 inProp.set(mObj, index, propVal);
630 ++index;
631 }
632 }
633 this->popCurrentContext();
634 }
635
636 template<typename TAccessorType, typename TInfoType>
637 void PxFixedSizeLookupTableProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo )
638 {
639 typedef typename TAccessorType::prop_type TPropertyType;
640 const_cast<TAccessorType&>(inProp).clear( mObj );
641
642 this->pushCurrentContext();
643 if ( this->gotoTopName() )
644 {
645 for ( bool success = this->gotoFirstChild(); success;
646 success = this->gotoNextSibling() )
647 {
648 TPropertyType propXVal;
649 readComplexObj( *this, &propXVal, inInfo );
650
651 if(this->gotoNextSibling())
652 {
653 TPropertyType propYVal;
654 readComplexObj( *this, &propYVal, inInfo );
655 const_cast<TAccessorType&>(inProp).addPair(mObj, propXVal, propYVal);
656 }
657 }
658 }
659 this->popCurrentContext();
660 }
661
662 void handleShapes( const PxRigidActorShapeCollection& inProp )
663 {
664 physx::Sn::readShapesProperty( *this, mObj, &inProp );
665 }
666
667 void handleRigidActorGlobalPose(const PxRigidActorGlobalPosePropertyInfo& inProp)
668 {
669 PxArticulationLink* link = mObj->template is<PxArticulationLink>();
670 bool isReducedCoordinateLink = (link != NULL);
671 if (!isReducedCoordinateLink)
672 {
674 simpleProperty(PxPropertyInfoName::PxRigidActor_GlobalPose, theAccessor);
675 }
676 }
677 };
678
679 template<typename TObjType>
680 struct RepXVisitorReader : public RepXVisitorReaderBase<TObjType>
681 {
682 RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, TObjType* obj
683 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret)
684 : RepXVisitorReaderBase<TObjType>( names, contexts, args, reader, obj, alloc, collection, ret)
685 {
686 }
689 {
690 }
691 };
692
693 // Specialized template to load dynamic rigid, to determine the kinematic state first
694 template<>
696 {
698 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret)
699 : RepXVisitorReaderBase<PxRigidDynamic>( names, contexts, args, reader, obj, alloc, collection, ret)
700 {
701 }
704 {
705 }
706
707 void handleShapes( const PxRigidActorShapeCollection& inProp )
708 {
709 // Need to read the parental actor to check if actor is kinematic
710 // in that case we need to apply the kinematic flag before a shape is set
711 XmlReaderWriter* parentReader = static_cast<XmlReaderWriter*>(mReader.getParentReader());
712 if(mObj)
713 {
714 const char* value;
715 if (parentReader->read( "RigidBodyFlags", value ))
716 {
717 if(strstr(value, "eKINEMATIC"))
718 {
719 mObj->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
720 }
721 }
722 }
723 physx::Sn::readShapesProperty( *this, mObj, &inProp );
724 parentReader->release();
725 }
726
727
728 template<typename TAccessorType>
729 void simpleProperty( PxU32 /*key*/, TAccessorType& inProp )
730 {
731 typedef typename TAccessorType::prop_type TPropertyType;
732 TPropertyType value;
733 if (readProperty(value))
734 {
735 // If the rigid body is kinematic, we cannot set the LinearVelocity or AngularVelocity
736 const bool kinematic = (mObj->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC);
737 if(kinematic && (inProp.mProperty.mKey == PxPropertyInfoName::PxRigidDynamic_LinearVelocity || inProp.mProperty.mKey == PxPropertyInfoName::PxRigidDynamic_AngularVelocity))
738 return;
739
740 inProp.set(mObj, value );
741 }
742 }
743 private:
745 };
746
747 template<>
749 {
751 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret )
752 : RepXVisitorReaderBase<PxShape>( names, contexts, args, reader, obj, alloc, collection, ret )
753 {
754 }
757 {
758 }
759 void handleShapeMaterials( const PxShapeMaterialsProperty& ) //these were handled during construction.
760 {
761 }
762 void handleGeomProperty( const PxShapeGeomProperty& )
763 {
764 }
765 private:
767 };
768
769 template<>
770 struct RepXVisitorReader<PxArticulationLink> : public RepXVisitorReaderBase<PxArticulationLink>
771 {
773 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret )
774 : RepXVisitorReaderBase<PxArticulationLink>( names, contexts, args, reader, obj, alloc, collection, ret )
775 {
776 }
779 {
780 }
781 void handleIncomingJoint( const TIncomingJointPropType& prop )
782 {
783 pushName( "Joint" );
784 if ( gotoTopName() )
785 {
786
787 PxArticulationJointReducedCoordinate* theJoint = static_cast<PxArticulationJointReducedCoordinate*>((prop.get(mObj)));
788 readComplexObj(*this, theJoint);
789 //Add joint to PxCollection, since PxArticulation requires PxArticulationLink and joint.
790 mCollection.add(*theJoint);
791
792 }
793 popName();
794 }
795
796 private:
798 };
799
800 template<typename ArticulationType>
801 inline void readProperty( RepXVisitorReaderBase<ArticulationType>& inSerializer, ArticulationType* inObj, const PxArticulationLinkCollectionProp&)
802 {
803 PxProfileAllocatorWrapper theWrapper( inSerializer.mAllocator.getAllocator() );
804 PxCollection& collection( inSerializer.mCollection );
805
806 TArticulationLinkLinkMap linkRemapMap( theWrapper );
807 inSerializer.pushCurrentContext();
808 if( inSerializer.gotoTopName() )
809 {
810 for ( bool links = inSerializer.gotoFirstChild();
811 links != false;
812 links = inSerializer.gotoNextSibling() )
813 {
814 //Need enough information to create the link...
815 PxSerialObjectId theParentPtr = 0;
816 const PxArticulationLink* theParentLink = NULL;
817 if ( inSerializer.mReader.read( "Parent", theParentPtr ) )
818 {
819 const TArticulationLinkLinkMap::Entry* theRemappedParent( linkRemapMap.find( theParentPtr ) );
820 //If we have a valid at write time, we had better have a valid parent at read time.
821 PX_ASSERT( theRemappedParent );
822 theParentLink = theRemappedParent->second;
823 }
824 PxArticulationLink* newLink = inObj->createLink( const_cast<PxArticulationLink*>( theParentLink ), PxTransform(PxIdentity) );
825 PxSerialObjectId theIdPtr = 0;
826 inSerializer.mReader.read( "Id", theIdPtr );
827
828 linkRemapMap.insert( theIdPtr, newLink );
829 readComplexObj( inSerializer, newLink );
830
831 //Add link to PxCollection, since PxArticulation requires PxArticulationLink and joint.
832 collection.add( *newLink, theIdPtr );
833 }
834 }
835 inSerializer.popCurrentContext();
836 }
837
838 template<>
839 struct RepXVisitorReader<PxArticulationReducedCoordinate> : public RepXVisitorReaderBase<PxArticulationReducedCoordinate>
840 {
842 , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret)
843 : RepXVisitorReaderBase<PxArticulationReducedCoordinate>(names, contexts, args, reader, obj, alloc, collection, ret)
844 {}
847 {}
848
849 void handleArticulationLinks(const PxArticulationLinkCollectionProp& inProp)
850 {
851 physx::Sn::readProperty(*this, mObj, inProp);
852 }
853 };
854
855 template<typename TObjType, typename TInfoType>
856 inline bool readAllProperties( PxRepXInstantiationArgs args, TReaderNameStack& names, PxProfileArray<PxU32>& contexts, XmlReader& reader, TObjType* obj, XmlMemoryAllocator& alloc, PxCollection& collection, TInfoType& info )
857 {
858 bool hadError = false;
859 RepXVisitorReader<TObjType> theReader( names, contexts, args, reader, obj, alloc, collection, hadError);
861 info.visitBaseProperties( theOp );
862 info.visitInstanceProperties( theOp );
863 return !hadError;
864 }
865
866
867 template<typename TObjType>
868 inline bool readAllProperties( PxRepXInstantiationArgs args, XmlReader& reader, TObjType* obj, XmlMemoryAllocator& alloc, PxCollection& collection )
869 {
870 PxProfileAllocatorWrapper wrapper( alloc.getAllocator() );
871 TReaderNameStack names( wrapper );
872 PxProfileArray<PxU32> contexts( wrapper );
874 return readAllProperties( args, names, contexts, reader, obj, alloc, collection, info.Info );
875 }
876
877 template<typename TObjType, typename TReaderType, typename TInfoType>
878 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, TInfoType& info)
879 {
880 if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info ))
881 oldVisitor.mHadError = true;
882 }
883
884 template<typename TObjType, typename TReaderType, typename TInfoType>
885 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, const TInfoType& info)
886 {
887 if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info ))
888 oldVisitor.mHadError = true;
889 }
890
891 template<typename TObjType, typename TReaderType>
892 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, const PxUnknownClassInfo& /*info*/)
893 {
894 const char* value = oldVisitor.mReader.getCurrentItemValue();
895 if ( value && *value )
896 {
897 stringToType( value, *inObj );
898 return;
899 }
900 oldVisitor.mHadError = true;
901 }
902
903 template<typename TObjType, typename TReaderType>
904 inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj)
905 {
906 PxClassInfoTraits<TObjType> info;
907 if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info.Info ))
908 oldVisitor.mHadError = true;
909 }
910
911} }
912
913#endif
PX_FORCE_INLINE uint32_t size() const
Definition PxArray.h:242
PX_FORCE_INLINE ConstIterator begin() const
Definition PxArray.h:176
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE T popBack()
Definition PxArray.h:311
PX_FORCE_INLINE const T & back() const
Definition PxArray.h:224
A joint between two links in an articulation.
Definition PxArticulationJointReducedCoordinate.h:49
A tree structure of bodies connected by joints that is treated as a unit by the dynamics solver....
Definition PxArticulationReducedCoordinate.h:448
A triangle mesh containing the PxMeshMidPhase::eBVH33 structure.
Definition PxTriangleMesh.h:308
A triangle mesh containing the PxMeshMidPhase::eBVH34 structure.
Definition PxTriangleMesh.h:324
Collection class for serialization.
Definition PxCollection.h:104
virtual void add(PxBase &object, PxSerialObjectId id=PX_SERIAL_OBJECT_ID_INVALID)=0
Adds a PxBase object to the collection.
A convex mesh.
Definition PxConvexMesh.h:83
A height field class.
Definition PxHeightField.h:84
Definition PxInlineArray.h:43
Definition PxBasicTemplates.h:67
PxRigidActor represents a base class shared between dynamic and static rigid bodies in the physics SD...
Definition PxRigidActor.h:53
PxRigidDynamic represents a dynamic rigid simulation object in the physics SDK.
Definition PxRigidDynamic.h:82
Abstract class for collision shapes.
Definition PxShape.h:146
virtual const char * allocateStr(const char *inSrc)=0
Allocate a new string.
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
A triangle mesh, also called a 'polygon soup'.
Definition PxTriangleMesh.h:118
Definition SnXmlMemoryAllocator.h:37
Definition SnXmlReader.h:78
Definition SnXmlReader.h:42
virtual const char * getCurrentItemName()=0
virtual bool gotoNextSibling()=0
virtual bool read(const char *inName, const char *&outData)=0
virtual const char * getCurrentItemValue()=0
virtual bool leaveChild()=0
virtual XmlReader * getParentReader()=0
virtual bool gotoFirstChild()=0
virtual bool gotoChild(const char *inName)=0
PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation &PX_CALL_CONV PxGetFoundation()
Retrieves the Foundation SDK after it has been created.
Definition FdFoundation.cpp:279
#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
PxU64 PxSerialObjectId
ID type for PxBase objects in a PxCollection.
Definition PxSerialFramework.h:61
Definition PxMetaDataObjects.h:575
Definition PxMetaDataObjects.h:478
@ eINVALID_PARAMETER
method called with invalid parameter(s)
Definition PxErrors.h:62
@ eGEOMETRY_COUNT
internal use only!
Definition PxGeometry.h:65
@ eINVALID
internal use only!
Definition PxGeometry.h:66
Definition PxMetaDataObjects.h:173
Definition PxMetaDataObjects.h:149
Arguments required to instantiate a serializable object from RepX.
Definition PxRepXSimpleType.h:83
Definition RepXMetaDataPropertyVisitor.h:37
Definition PxMetaDataObjects.h:559
@ eKINEMATIC
Enables kinematic mode for the actor.
Definition PxRigidBody.h:74
Definition PxMetaDataObjects.h:520
Definition PxMetaDataObjects.h:540
Definition PxMetaDataObjects.h:124
Definition RepXMetaDataPropertyVisitor.h:84
Definition SnXmlImpl.h:233
Definition SnXmlVisitorReader.h:329
Definition SnXmlVisitorReader.h:338
Definition SnXmlVisitorReader.h:681
Helper struct to encapsulate the user allocator callback Useful for array and hash templates.
Definition PxProfileAllocatorWrapper.h:46
Helper struct to encapsulate the array.
Definition PxProfileAllocatorWrapper.h:152
Helper struct to encapsulate the array.
Definition PxProfileAllocatorWrapper.h:171