aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp')
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp433
1 files changed, 433 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp
new file mode 100644
index 00000000..15edeb46
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp
@@ -0,0 +1,433 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysicsAPI.h"
+#include "PxConstraintExt.h"
+#include "PxPhysicsVersion.h"
+#include "PsFoundation.h"
+#include "PxMetaData.h"
+#include "SnConvX.h"
+#include "SnSerializationRegistry.h"
+#include "SnSerialUtils.h"
+#include "ExtSerialization.h"
+#include "PxSerializer.h"
+#include "CmCollection.h"
+
+using namespace physx;
+using namespace Sn;
+
+namespace
+{
+ struct RequiresCallback : public PxProcessPxBaseCallback
+ {
+ RequiresCallback(physx::PxCollection& c) : collection(c) {}
+ void process(PxBase& base)
+ {
+ if(!collection.contains(base))
+ collection.add(base);
+ }
+
+ PxCollection& collection;
+ PX_NOCOPY(RequiresCallback)
+ };
+
+ struct CompleteCallback : public PxProcessPxBaseCallback
+ {
+ CompleteCallback(physx::PxCollection& r, physx::PxCollection& c, const physx::PxCollection* e) :
+ requires(r), complete(c), external(e) {}
+ void process(PxBase& base)
+ {
+ if(complete.contains(base) || (external && external->contains(base)))
+ return;
+ if(!requires.contains(base))
+ requires.add(base);
+ }
+
+ PxCollection& requires;
+ PxCollection& complete;
+ const PxCollection* external;
+ PX_NOCOPY(CompleteCallback)
+ };
+
+ void getRequiresCollection(PxCollection& requires, PxCollection& collection, PxCollection& complete, const PxCollection* external, PxSerializationRegistry& sr, bool followJoints)
+ {
+ CompleteCallback callback(requires, complete, external);
+ for (PxU32 i = 0; i < collection.getNbObjects(); ++i)
+ {
+ PxBase& s = collection.getObject(i);
+ const PxSerializer* serializer = sr.getSerializer(s.getConcreteType());
+ PX_ASSERT(serializer);
+ serializer->requires(s, callback);
+
+ if(followJoints)
+ {
+ PxRigidActor* actor = s.is<PxRigidActor>();
+ if(actor)
+ {
+ Ps::Array<PxConstraint*> objects(actor->getNbConstraints());
+ actor->getConstraints(objects.begin(), objects.size());
+
+ for(PxU32 j=0;j<objects.size();j++)
+ {
+ PxU32 typeId;
+ PxJoint* joint = reinterpret_cast<PxJoint*>(objects[j]->getExternalReference(typeId));
+ if(typeId == PxConstraintExtIDs::eJOINT)
+ {
+ const PxSerializer* sj = sr.getSerializer(joint->getConcreteType());
+ PX_ASSERT(sj);
+ sj->requires(*joint, callback);
+ if(!requires.contains(*joint))
+ requires.add(*joint);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool PxSerialization::isSerializable(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalReferences)
+{
+ PxCollection* subordinateCollection = PxCreateCollection();
+ PX_ASSERT(subordinateCollection);
+
+ for(PxU32 i = 0; i < collection.getNbObjects(); ++i)
+ {
+ PxBase& s = collection.getObject(i);
+ const PxSerializer* serializer = sr.getSerializer(s.getConcreteType());
+ PX_ASSERT(serializer);
+ if(serializer->isSubordinate())
+ subordinateCollection->add(s);
+
+ if(externalReferences)
+ {
+ PxSerialObjectId id = collection.getId(s);
+ if(id != PX_SERIAL_OBJECT_ID_INVALID)
+ {
+ PxBase* object = externalReferences->find(id);
+ if(object && (object != &s))
+ {
+ subordinateCollection->release();
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: Reference id %" PX_PRIu64 " used both in current collection and in externalReferences. "
+ "Please use unique identifiers.", id);
+ return false;
+ }
+ }
+ }
+ }
+
+ PxCollection* requiresCollection = PxCreateCollection();
+ PX_ASSERT(requiresCollection);
+
+ RequiresCallback requiresCallback0(*requiresCollection);
+
+ for (PxU32 i = 0; i < collection.getNbObjects(); ++i)
+ {
+ PxBase& s = collection.getObject(i);
+ const PxSerializer* serializer = sr.getSerializer(s.getConcreteType());
+ PX_ASSERT(serializer);
+ serializer->requires(s, requiresCallback0);
+
+ Cm::Collection* cmRequiresCollection = static_cast<Cm::Collection*>(requiresCollection);
+
+ for(PxU32 j = 0; j < cmRequiresCollection->getNbObjects(); ++j)
+ {
+ PxBase& s0 = cmRequiresCollection->getObject(j);
+
+ if(subordinateCollection->contains(s0))
+ {
+ subordinateCollection->remove(s0);
+ continue;
+ }
+
+ bool requiredIsInCollection = collection.contains(s0);
+ if(!requiredIsInCollection)
+ {
+ if(externalReferences)
+ {
+ if(!externalReferences->contains(s0))
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: Object of type %s references a missing object of type %s. "
+ "The missing object needs to be added to either the current collection or the externalReferences collection.",
+ s.getConcreteTypeName(), s0.getConcreteTypeName());
+ }
+ else if(externalReferences->getId(s0) == PX_SERIAL_OBJECT_ID_INVALID)
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: Object of type %s in externalReferences collection requires an id.",
+ s0.getConcreteTypeName());
+ }
+ else
+ continue;
+ }
+ else
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: Object of type %s references a missing serial object of type %s. "
+ "Please completed the collection or specify an externalReferences collection containing the object.",
+ s.getConcreteTypeName(), s0.getConcreteTypeName());
+ }
+ subordinateCollection->release();
+ requiresCollection->release();
+ return false;
+ }
+ }
+ cmRequiresCollection->mObjects.clear();
+ }
+ requiresCollection->release();
+
+ PxU32 numOrphans = subordinateCollection->getNbObjects();
+
+ for(PxU32 j = 0; j < numOrphans; ++j)
+ {
+ PxBase& subordinate = subordinateCollection->getObject(j);
+
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: An object of type %s is subordinate but not required "
+ "by other objects in the collection (orphan). Please remove the object from the collection or add its owner.",
+ subordinate.getConcreteTypeName());
+ }
+
+ subordinateCollection->release();
+
+ if(numOrphans>0)
+ return false;
+
+ if(externalReferences)
+ {
+ PxCollection* oppositeRequiresCollection = PxCreateCollection();
+ PX_ASSERT(oppositeRequiresCollection);
+
+ RequiresCallback requiresCallback(*oppositeRequiresCollection);
+
+ for (PxU32 i = 0; i < externalReferences->getNbObjects(); ++i)
+ {
+ PxBase& s = externalReferences->getObject(i);
+ const PxSerializer* serializer = sr.getSerializer(s.getConcreteType());
+ PX_ASSERT(serializer);
+ serializer->requires(s, requiresCallback);
+
+ Cm::Collection* cmCollection = static_cast<Cm::Collection*>(oppositeRequiresCollection);
+
+ for(PxU32 j = 0; j < cmCollection->getNbObjects(); ++j)
+ {
+ PxBase& s0 = cmCollection->getObject(j);
+
+ if(collection.contains(s0))
+ {
+ oppositeRequiresCollection->release();
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxSerialization::isSerializable: Object of type %s in externalReferences references an object "
+ "of type %s in collection (circular dependency).",
+ s.getConcreteTypeName(), s0.getConcreteTypeName());
+ return false;
+ }
+ }
+ cmCollection->mObjects.clear();
+ }
+ oppositeRequiresCollection->release();
+ }
+
+ return true;
+}
+
+void PxSerialization::complete(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* exceptFor, bool followJoints)
+{
+ PxCollection* curCollection = PxCreateCollection();
+ PX_ASSERT(curCollection);
+ curCollection->add(collection);
+
+ PxCollection* requiresCollection = PxCreateCollection();
+ PX_ASSERT(requiresCollection);
+
+ do
+ {
+ getRequiresCollection(*requiresCollection, *curCollection, collection, exceptFor, sr, followJoints);
+
+ collection.add(*requiresCollection);
+ PxCollection* swap = curCollection;
+ curCollection = requiresCollection;
+ requiresCollection = swap;
+ (static_cast<Cm::Collection*>(requiresCollection))->mObjects.clear();
+
+ }while(curCollection->getNbObjects() > 0);
+
+ requiresCollection->release();
+ curCollection->release();
+
+}
+
+void PxSerialization::createSerialObjectIds(PxCollection& collection, const PxSerialObjectId base)
+{
+ PxSerialObjectId localBase = base;
+ PxU32 nbObjects = collection.getNbObjects();
+
+ for (PxU32 i = 0; i < nbObjects; ++i)
+ {
+ while(collection.find(localBase))
+ {
+ localBase++;
+ }
+
+ PxBase& s = collection.getObject(i);
+ if(PX_SERIAL_OBJECT_ID_INVALID == collection.getId(s))
+ {
+ collection.addId(s, localBase);
+ localBase++;
+ }
+ }
+}
+
+namespace physx { namespace Sn
+{
+ static PxU32 addToStringTable(physx::shdfnd::Array<char>& stringTable, const char* str)
+ {
+ if(!str)
+ return 0xffffffff;
+
+ PxI32 length = PxI32(stringTable.size());
+ const char* table = stringTable.begin();
+ const char* start = table;
+ while(length)
+ {
+ if(strcmp(table, str)==0)
+ return PxU32(table - start);
+
+ const char* saved = table;
+ while(*table++);
+ length -= PxU32(table - saved);
+ PX_ASSERT(length>=0);
+ }
+
+ const PxU32 offset = stringTable.size();
+
+ while(*str)
+ stringTable.pushBack(*str++);
+ stringTable.pushBack(0);
+ return offset;
+ }
+} }
+
+void PxSerialization::dumpBinaryMetaData(PxOutputStream& outputStream, PxSerializationRegistry& sr)
+{
+ class MetaDataStream : public PxOutputStream
+ {
+ public:
+ bool addNewType(const char* typeName)
+ {
+ for(PxU32 i=0;i<types.size();i++)
+ {
+ if(strcmp(types[i], typeName)==0)
+ return false;
+ }
+ types.pushBack(typeName);
+ return true;
+ }
+ virtual PxU32 write(const void* src, PxU32 count)
+ {
+ PX_ASSERT(count==sizeof(PxMetaDataEntry));
+ const PxMetaDataEntry* entry = reinterpret_cast<const PxMetaDataEntry*>(src);
+ if(( entry->flags & PxMetaDataFlag::eTYPEDEF) || ((entry->flags & PxMetaDataFlag::eCLASS) && (!entry->name)) )
+ newType = addNewType(entry->type);
+ if(newType)
+ metaData.pushBack(*entry);
+ return count;
+ }
+ shdfnd::Array<PxMetaDataEntry> metaData;
+ shdfnd::Array<const char*> types;
+ bool newType;
+ }s;
+
+ SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr);
+ sn.getBinaryMetaData(s);
+
+ shdfnd::Array<char> stringTable;
+
+ PxU32 nb = s.metaData.size();
+ PxMetaDataEntry* entries = s.metaData.begin();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ entries[i].type = reinterpret_cast<const char*>(size_t(addToStringTable(stringTable, entries[i].type)));
+ entries[i].name = reinterpret_cast<const char*>(size_t(addToStringTable(stringTable, entries[i].name)));
+ }
+
+ PxU32 platformTag = getBinaryPlatformTag();
+
+#if PX_X64
+ const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::ePC);
+#endif
+#if PX_X86 || defined(__CYGWIN__)
+ const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::ePC);
+#endif
+#if PX_ARM_FAMILY
+ const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::eARM);
+#endif
+
+ const PxU32 header = PX_MAKE_FOURCC('M','E','T','A');
+ const PxU32 version = PX_PHYSICS_VERSION;
+ const PxU32 binaryVersion = PX_BINARY_SERIAL_VERSION;
+ const PxU32 ptrSize = sizeof(void*);
+ PxU32 buildNumber = 0;
+#if defined(PX_BUILD_NUMBER)
+ buildNumber = PX_BUILD_NUMBER;
+#endif
+ outputStream.write(&header, 4);
+ outputStream.write(&version, 4);
+ outputStream.write(&binaryVersion, 4);
+ outputStream.write(&buildNumber, 4);
+ outputStream.write(&ptrSize, 4);
+ outputStream.write(&platformTag, 4);
+ outputStream.write(&gaussMapLimit, 4);
+
+ outputStream.write(&nb, 4);
+ outputStream.write(entries, nb*sizeof(PxMetaDataEntry));
+
+ //concreteTypes to name
+ PxU32 num = sn.getNbSerializers();
+ outputStream.write(&num, 4);
+ for(PxU32 i=0; i<num; i++)
+ {
+ PxU16 type = sn.getSerializerType(i);
+ PxU32 nameOffset = addToStringTable(stringTable, sn.getSerializerName(i));
+ outputStream.write(&type, 2);
+ outputStream.write(&nameOffset, 4);
+ }
+
+ PxU32 length = stringTable.size();
+ const char* table = stringTable.begin();
+ outputStream.write(&length, 4);
+ outputStream.write(table, length);
+}
+
+PxBinaryConverter* PxSerialization::createBinaryConverter()
+{
+ return PX_NEW(ConvX)();
+}