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#include "common/PxSerializer.h"
31#include "PxPhysics.h"
32#include "PxPhysicsSerialization.h"
33#include "PxArticulationLink.h"
34
35#include "SnSerializationRegistry.h"
36#include "ExtSerialization.h"
37#include "CmCollection.h"
38#include "PsFoundation.h"
39#include "PsString.h"
40
41using namespace physx;
42
43namespace
44{
45 class CollectionSorter : public PxProcessPxBaseCallback
46 {
47 typedef Ps::Pair<PxBase*, PxSerialObjectId> Object;
48
49 class Element
50 {
51 public:
52 Object object;
53 Ps::Array<PxU32> children;
54 bool isFinished;
55
56 Element(PxBase* obj = NULL) : object(obj, PX_SERIAL_OBJECT_ID_INVALID), isFinished(false) {}
57 };
58
59 public:
60 CollectionSorter(Cm::Collection& collection, Sn::SerializationRegistry& sr, bool isRepx) : mCollection(collection), mSr(sr), mIsRepx(isRepx) {}
61 virtual ~CollectionSorter(){}
62
63 void process(PxBase& base)
64 {
65 addChild(base: &base);
66 //ArticulationLink is not a repx serializer, so should require Articulation here
67 if( mIsRepx && PxConcreteType::eARTICULATION_LINK == base.getConcreteType() )
68 {
69 PxArticulationLink* link = static_cast<PxArticulationLink*>(&base);
70 PxBase* a = reinterpret_cast<PxBase*>(&link->getArticulation());
71 if(mCurElement->object.first != a ) //don't require itself
72 addChild(base: a);
73 }
74 }
75
76 void sort()
77 {
78 Element element;
79 PxU32 i;
80
81 PxU32 nbObject = mCollection.internalGetNbObjects();
82 const Cm::Collection::ObjectToIdMap::Entry* objectdatas = mCollection.internalGetObjects();
83 for( i = 0; i < nbObject; ++i )
84 {
85 element.object.first = objectdatas[i].first;
86 element.object.second = objectdatas[i].second;
87 mObjToIdMap.insert(k: objectdatas[i].first, v: mElements.size());
88 mElements.pushBack(a: element);
89 }
90
91 for( i = 0; i < nbObject; ++i )
92 {
93 mCurElement = &mElements[i];
94 const PxSerializer* serializer = mSr.getSerializer(type: mCurElement->object.first->getConcreteType());
95 PX_ASSERT(serializer);
96 serializer->requiresObjects(*mCurElement->object.first, *this);
97 }
98
99 for( i = 0; i < nbObject; ++i )
100 {
101 if( mElements[i].isFinished )
102 continue;
103
104 AddElement(e&: mElements[i]);
105 }
106
107 mCollection.mObjects.clear();
108 for(Ps::Array<Object>::Iterator o = mSorted.begin(); o != mSorted.end(); ++o )
109 {
110 mCollection.internalAdd(s: o->first, id: o->second);
111 }
112 }
113
114 void AddElement(Element& e)
115 {
116 if( !e.isFinished )
117 {
118 for( Ps::Array<PxU32>::Iterator child = e.children.begin(); child != e.children.end(); ++child )
119 {
120 AddElement(e&: mElements[*child]);
121 }
122 mSorted.pushBack(a: e.object);
123 e.isFinished = true;
124 }
125 }
126
127 private:
128 PX_INLINE void addChild(PxBase* base)
129 {
130 PX_ASSERT(mCurElement);
131 const Ps::HashMap<PxBase*, PxU32>::Entry* entry = mObjToIdMap.find(k: base);
132 if(entry)
133 mCurElement->children.pushBack(a: entry->second);
134 }
135
136 CollectionSorter& operator=(const CollectionSorter&);
137 Ps::HashMap<PxBase*, PxU32> mObjToIdMap;
138 Ps::Array<Element> mElements;
139 Cm::Collection& mCollection;
140 Sn::SerializationRegistry& mSr;
141 Ps::Array<Object> mSorted;
142 Element* mCurElement;
143 bool mIsRepx;
144 };
145}
146
147namespace physx { namespace Sn {
148
149SerializationRegistry::SerializationRegistry(PxPhysics& physics)
150 : mPhysics(physics)
151{
152 PxRegisterPhysicsSerializers(sr&: *this);
153 Ext::RegisterExtensionsSerializers(sr&: *this);
154
155 registerBinaryMetaDataCallback(callback: PxGetPhysicsBinaryMetaData);
156 registerBinaryMetaDataCallback(callback: Ext::GetExtensionsBinaryMetaData);
157}
158
159SerializationRegistry::~SerializationRegistry()
160{
161 PxUnregisterPhysicsSerializers(sr&: *this);
162 Ext::UnregisterExtensionsSerializers(sr&: *this);
163
164 if(mSerializers.size() > 0)
165 {
166 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
167 messageFmt: "PxSerializationRegistry::release(): some registered PxSerializer instances were not unregistered");
168 }
169
170 if(mRepXSerializers.size() > 0)
171 {
172 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
173 messageFmt: "PxSerializationRegistry::release(): some registered PxRepXSerializer instances were not unregistered");
174 }
175}
176
177void SerializationRegistry::registerSerializer(PxType type, PxSerializer& serializer)
178{
179 if(mSerializers.find(k: type))
180 {
181 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
182 messageFmt: "PxSerializationRegistry::registerSerializer: Type %d has already been registered", type);
183 }
184
185 mSerializers.insert(k: type, v: &serializer);
186}
187
188PxSerializer* SerializationRegistry::unregisterSerializer(PxType type)
189{
190 const SerializerMap::Entry* e = mSerializers.find(k: type);
191 PxSerializer* s = e ? e->second : NULL;
192
193 if(!mSerializers.erase(k: type))
194 {
195 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
196 messageFmt: "PxSerializationRegistry::unregisterSerializer: failed to find PxSerializer instance for type %d", type);
197 }
198 return s;
199}
200
201const PxSerializer* SerializationRegistry::getSerializer(PxType type) const
202{
203 const SerializerMap::Entry* e = mSerializers.find(k: type);
204#if PX_CHECKED
205 if (!e)
206 {
207 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
208 "PxSerializationRegistry::getSerializer: failed to find PxSerializer instance for type %d", type);
209 }
210#endif
211 return e ? e->second : NULL;
212}
213
214PxType SerializationRegistry::getSerializerType(PxU32 index) const
215{
216 PX_ASSERT(index < mSerializers.size());
217 return mSerializers.getEntries()[index].first;
218}
219
220const char* SerializationRegistry::getSerializerName(PxU32 index) const
221{
222 PX_ASSERT(index < mSerializers.size());
223 return mSerializers.getEntries()[index].second->getConcreteTypeName();
224}
225
226void SerializationRegistry::registerBinaryMetaDataCallback(PxBinaryMetaDataCallback callback)
227{
228 mMetaDataCallbacks.pushBack(a: callback);
229}
230
231void SerializationRegistry::getBinaryMetaData(PxOutputStream& stream) const
232{
233 for(PxU32 i = 0; i < mMetaDataCallbacks.size(); i++)
234 {
235 mMetaDataCallbacks[i](stream);
236 }
237}
238
239void SerializationRegistry::registerRepXSerializer(PxType type, PxRepXSerializer& serializer)
240{
241 if(mRepXSerializers.find(k: type))
242 {
243 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
244 messageFmt: "PxSerializationRegistry::registerRepXSerializer: Type %d has already been registered", type);
245 }
246
247 mRepXSerializers.insert(k: type, v: &serializer);
248}
249
250PxRepXSerializer* SerializationRegistry::getRepXSerializer(const char* typeName) const
251{
252 SerializationRegistry* sr = const_cast<SerializationRegistry*>(this);
253 for( RepXSerializerMap::Iterator iter = sr->mRepXSerializers.getIterator(); !iter.done(); ++iter)
254 {
255 if ( physx::shdfnd::stricmp( str1: iter->second->getTypeName(), str2: typeName ) == 0 )
256 return iter->second;
257 }
258 return NULL;
259}
260
261PxRepXSerializer* SerializationRegistry::unregisterRepXSerializer(PxType type)
262{
263 const RepXSerializerMap::Entry* e = mRepXSerializers.find(k: type);
264 PxRepXSerializer* s = e ? e->second : NULL;
265
266 if(!mRepXSerializers.erase(k: type))
267 {
268 shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__,
269 messageFmt: "PxSerializationRegistry::unregisterRepXSerializer: failed to find PxRepXSerializer instance for type %d", type);
270 }
271 return s;
272}
273
274void sortCollection(Cm::Collection& collection, SerializationRegistry& sr, bool isRepx)
275{
276 CollectionSorter sorter(collection, sr, isRepx);
277 sorter.sort();
278}
279
280} // Sn
281
282PxSerializationRegistry* PxSerialization::createSerializationRegistry(PxPhysics& physics)
283{
284 return PX_NEW(Sn::SerializationRegistry)(physics);
285}
286
287} // physx
288
289

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtquick3dphysics/src/3rdparty/PhysX/source/physxextensions/src/serialization/SnSerializationRegistry.cpp