aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary
diff options
context:
space:
mode:
Diffstat (limited to 'PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary')
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinaryDeserialization.cpp305
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp402
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.cpp156
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.h182
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.cpp63
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.h44
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Common.h43
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Convert.cpp1434
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Error.cpp92
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.cpp840
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.h186
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.cpp451
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.h112
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.cpp90
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.h45
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.cpp94
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.h303
17 files changed, 4842 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinaryDeserialization.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinaryDeserialization.cpp
new file mode 100644
index 00000000..981cfa2a
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinaryDeserialization.cpp
@@ -0,0 +1,305 @@
+// 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 "PsHash.h"
+#include "PsHashMap.h"
+#include "PsFoundation.h"
+#include "CmIO.h"
+#include "SnFile.h"
+#include "PsString.h"
+#include "extensions/PxSerialization.h"
+#include "PxPhysics.h"
+#include "PxPhysicsSerialization.h"
+#include "SnSerializationContext.h"
+#include "PxSerializer.h"
+#include "serialization/SnSerializationRegistry.h"
+#include "serialization/SnSerialUtils.h"
+#include "CmCollection.h"
+#include "SnConvX_Align.h"
+
+using namespace physx;
+using namespace Sn;
+
+namespace
+{
+ PX_INLINE PxU8* alignPtr(PxU8* ptr, PxU32 alignment = PX_SERIAL_ALIGN)
+ {
+ if(!alignment)
+ return ptr;
+
+ const PxU32 padding = getPadding(size_t(ptr), alignment);
+ PX_ASSERT(!getPadding(size_t(ptr + padding), alignment));
+ return ptr + padding;
+ }
+
+ PX_FORCE_INLINE PxU32 read32(PxU8*& address)
+ {
+ const PxU32 value = *reinterpret_cast<PxU32*>(address);
+ address += sizeof(PxU32);
+ return value;
+ }
+
+ bool readHeader(PxU8*& address, PxU32& version)
+ {
+ const PxU32 header = read32(address);
+ PX_UNUSED(header);
+
+ version = read32(address);
+
+ const PxU32 binaryVersion = read32(address);
+ PX_UNUSED(binaryVersion);
+ const PxU32 buildNumber = read32(address);
+ PX_UNUSED(buildNumber);
+ const PxU32 platformTag = read32(address);
+ PX_UNUSED(platformTag);
+ const PxU32 markedPadding = read32(address);
+ PX_UNUSED(markedPadding);
+
+#if PX_CHECKED
+ if (header != PX_MAKE_FOURCC('S','E','B','D'))
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "Buffer contains data with wrong header indicating invalid binary data.");
+ return false;
+ }
+
+ if (!checkCompatibility(version, binaryVersion))
+ {
+ char buffer[512];
+ getCompatibilityVersionsStr(buffer, 512);
+
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "Buffer contains data version (%x-%d) is incompatible with this PhysX sdk.\n These versions would be compatible: %s",
+ version, binaryVersion, buffer);
+ return false;
+ }
+
+ if (platformTag != getBinaryPlatformTag())
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "Buffer contains data with platform mismatch:\nExpected: %s \nActual: %s\n",
+ getBinaryPlatformName(getBinaryPlatformTag()),
+ getBinaryPlatformName(platformTag));
+ return false;
+ }
+#endif
+ return true;
+ }
+
+ bool checkImportReferences(const ImportReference* importReferences, PxU32 nbImportReferences, const Cm::Collection* externalRefs)
+ {
+ if (!externalRefs)
+ {
+ if (nbImportReferences > 0)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::createCollectionFromBinary: External references needed but no externalRefs collection specified.");
+ return false;
+ }
+ }
+ else
+ {
+ for (PxU32 i=0; i<nbImportReferences;i++)
+ {
+ PxSerialObjectId id = importReferences[i].id;
+ PxType type = importReferences[i].type;
+
+ PxBase* referencedObject = externalRefs->find(id);
+ if (!referencedObject)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::createCollectionFromBinary: External reference %" PX_PRIu64 " expected in externalRefs collection but not found.", id);
+ return false;
+ }
+ if (referencedObject->getConcreteType() != type)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerialization::createCollectionFromBinary: External reference %d type mismatch. Expected %d but found %d in externalRefs collection.", type, referencedObject->getConcreteType());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+}
+
+PxCollection* PxSerialization::createCollectionFromBinary(void* memBlock, PxSerializationRegistry& sr, const PxCollection* pxExternalRefs)
+{
+#if PX_CHECKED
+ if(size_t(memBlock) & (PX_SERIAL_FILE_ALIGN-1))
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "Buffer must be 128-bytes aligned.");
+ return NULL;
+ }
+#endif
+ PxU8* address = reinterpret_cast<PxU8*>(memBlock);
+ const Cm::Collection* externalRefs = static_cast<const Cm::Collection*>(pxExternalRefs);
+
+ PxU32 version;
+ if (!readHeader(address, version))
+ {
+ return NULL;
+ }
+
+ ManifestEntry* manifestTable;
+ PxU32 nbObjectsInCollection;
+ PxU32 objectDataEndOffset;
+
+ // read number of objects in collection
+ address = alignPtr(address);
+ nbObjectsInCollection = read32(address);
+
+ // read manifest (PxU32 offset, PxConcreteType type)
+ {
+ address = alignPtr(address);
+ PxU32 nbManifestEntries = read32(address);
+ PX_ASSERT(*reinterpret_cast<PxU32*>(address) == 0); //first offset is always 0
+ manifestTable = (nbManifestEntries > 0) ? reinterpret_cast<ManifestEntry*>(address) : NULL;
+ address += nbManifestEntries*sizeof(ManifestEntry);
+ objectDataEndOffset = read32(address);
+ }
+
+ ImportReference* importReferences;
+ PxU32 nbImportReferences;
+ // read import references
+ {
+ address = alignPtr(address);
+ nbImportReferences = read32(address);
+ importReferences = (nbImportReferences > 0) ? reinterpret_cast<ImportReference*>(address) : NULL;
+ address += nbImportReferences*sizeof(ImportReference);
+ }
+
+ if (!checkImportReferences(importReferences, nbImportReferences, externalRefs))
+ {
+ return NULL;
+ }
+
+ ExportReference* exportReferences;
+ PxU32 nbExportReferences;
+ // read export references
+ {
+ address = alignPtr(address);
+ nbExportReferences = read32(address);
+ exportReferences = (nbExportReferences > 0) ? reinterpret_cast<ExportReference*>(address) : NULL;
+ address += nbExportReferences*sizeof(ExportReference);
+ }
+
+ // read internal references arrays
+ PxU32 nbInternalPtrReferences = 0;
+ PxU32 nbInternalIdxReferences = 0;
+ InternalReferencePtr* internalPtrReferences = NULL;
+ InternalReferenceIdx* internalIdxReferences = NULL;
+ {
+ address = alignPtr(address);
+
+ nbInternalPtrReferences = read32(address);
+ internalPtrReferences = (nbInternalPtrReferences > 0) ? reinterpret_cast<InternalReferencePtr*>(address) : NULL;
+ address += nbInternalPtrReferences*sizeof(InternalReferencePtr);
+
+ nbInternalIdxReferences = read32(address);
+ internalIdxReferences = (nbInternalIdxReferences > 0) ? reinterpret_cast<InternalReferenceIdx*>(address) : NULL;
+ address += nbInternalIdxReferences*sizeof(InternalReferenceIdx);
+ }
+
+ // create internal references map
+ PxF32 loadFactor = 0.75f;
+ PxF32 _loadFactor = 1.0f / loadFactor;
+ PxU32 hashSize = PxU32((nbInternalPtrReferences + nbInternalIdxReferences + 1)*_loadFactor);
+ InternalRefMap internalReferencesMap(hashSize, loadFactor);
+ {
+ //create hash (we should load the hashes directly from memory)
+ for (PxU32 i=0;i<nbInternalPtrReferences;i++)
+ {
+ const InternalReferencePtr& ref = internalPtrReferences[i];
+ internalReferencesMap.insertUnique( InternalRefKey(ref.reference, ref.kind), SerialObjectIndex(ref.objIndex));
+ }
+ for (PxU32 i=0;i<nbInternalIdxReferences;i++)
+ {
+ const InternalReferenceIdx& ref = internalIdxReferences[i];
+ internalReferencesMap.insertUnique(InternalRefKey(ref.reference, ref.kind), SerialObjectIndex(ref.objIndex));
+ }
+ }
+
+ SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr);
+ Cm::Collection* collection = static_cast<Cm::Collection*>(PxCreateCollection());
+ PX_ASSERT(collection);
+ collection->mObjects.reserve(PxU32(nbObjectsInCollection*_loadFactor) + 1);
+ if(nbExportReferences > 0)
+ collection->mIds.reserve(PxU32(nbExportReferences*_loadFactor) + 1);
+
+ PxU8* addressObjectData = alignPtr(address);
+ PxU8* addressExtraData = alignPtr(addressObjectData + objectDataEndOffset);
+
+ DeserializationContext context(manifestTable, importReferences, addressObjectData, internalReferencesMap, externalRefs, addressExtraData, version);
+
+ // iterate over memory containing PxBase objects, create the instances, resolve the addresses, import the external data, add to collection.
+ {
+ PxU32 nbObjects = nbObjectsInCollection;
+
+ while(nbObjects--)
+ {
+ address = alignPtr(address);
+ context.alignExtraData();
+
+ // read PxBase header with type and get corresponding serializer.
+ PxBase* header = reinterpret_cast<PxBase*>(address);
+ const PxType classType = header->getConcreteType();
+ const PxSerializer* serializer = sn.getSerializer(classType);
+ PX_ASSERT(serializer);
+
+ PxBase* instance = serializer->createObject(address, context);
+ if (!instance)
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "Cannot create class instance for concrete type %d.", classType);
+ collection->release();
+ return NULL;
+ }
+
+ collection->internalAdd(instance);
+ }
+ }
+
+ PX_ASSERT(nbObjectsInCollection == collection->internalGetNbObjects());
+
+ // update new collection with export references
+ {
+ PX_ASSERT(addressObjectData != NULL);
+ for (PxU32 i=0;i<nbExportReferences;i++)
+ {
+ bool isExternal;
+ PxU32 manifestIndex = exportReferences[i].objIndex.getIndex(isExternal);
+ PX_ASSERT(!isExternal);
+ PxBase* obj = reinterpret_cast<PxBase*>(addressObjectData + manifestTable[manifestIndex].offset);
+ collection->mIds.insertUnique(exportReferences[i].id, obj);
+ collection->mObjects[obj] = exportReferences[i].id;
+ }
+ }
+
+ PxAddCollectionToPhysics(*collection);
+ return collection;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp
new file mode 100644
index 00000000..f9a8b1b9
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp
@@ -0,0 +1,402 @@
+// 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 "PsHash.h"
+#include "PsHashMap.h"
+#include "CmIO.h"
+#include "SnFile.h"
+#include "PsString.h"
+#include "PsIntrinsics.h"
+#include "extensions/PxSerialization.h"
+#include "SnSerializationContext.h"
+#include "PxSerializer.h"
+#include "serialization/SnSerialUtils.h"
+#include "serialization/SnSerializationRegistry.h"
+#include "SnConvX_Align.h"
+#include "PxDefaultStreams.h"
+#include "CmCollection.h"
+#include "PxPhysicsVersion.h"
+#include "PsUtilities.h"
+
+using namespace physx;
+using namespace Cm;
+using namespace Sn;
+
+//------------------------------------------------------------------------------------
+//// Binary Serialized PxCollection, format documentation
+//------------------------------------------------------------------------------------
+//
+//
+//------------------------------------------------------------------------------------
+//// overview:
+//// header information
+//// manifest table
+//// import references
+//// export references
+//// internal references
+//// object data
+//// extra data
+//------------------------------------------------------------------------------------
+//
+//
+//------------------------------------------------------------------------------------
+//// header information:
+//// header tag plus various version and platform information
+//------------------------------------------------------------------------------------
+// header SEBD
+// PX_PHYSICS_VERSION
+// PX_BINARY_SERIAL_VERSION
+// PX_BUILD_NUMBER (or 0 if not defined)
+// platform tag
+// markedPadding (on for PX_CHECKED)
+// nbObjectsInCollection
+//
+//
+//------------------------------------------------------------------------------------
+//// manifest table:
+//// one entry per collected object
+//// offsets relative to object data buffer
+//------------------------------------------------------------------------------------
+// alignment
+// PxU32 size
+// (PxU32 offset, PxType type)*size
+// PxU32 endOffset
+//
+//
+//------------------------------------------------------------------------------------
+//// import references:
+//// one entry per required reference to external collection
+//------------------------------------------------------------------------------------
+// alignment
+// PxU32 size
+// (PxSerialObjectId id, PxType type)*size
+//
+//
+//------------------------------------------------------------------------------------
+//// export references:
+//// one entry per object in the collection with id
+//// object indices point into the manifest table (objects in the same collection)
+//------------------------------------------------------------------------------------
+// alignment
+// PxU32 size
+// (PxSerialObjectId id, SerialObjectIndex objIndex)*size
+//
+//
+//------------------------------------------------------------------------------------
+//// internal references:
+//// one entry per reference, kind pair
+//// object indices point either into the manifest table or into the import references
+//// depending on whether the entry references the same collection or the external one
+//// one section for pointer type references and one for index type references.
+//------------------------------------------------------------------------------------
+// alignment
+// PxU32 sizePtrs;
+// (size_t reference, PxU32 kind, SerialObjectIndex objIndex)*sizePtrs
+// PxU32 sizeIdx;
+// (PxU32 reference, PxU32 kind, SerialObjectIndex objIndex)*sizePtrs
+//
+//
+//------------------------------------------------------------------------------------
+//// object data:
+//// serialized PxBase derived class instances
+//// each object size depends on specific class
+//// offsets are stored in manifest table
+//------------------------------------------------------------------------------------
+// alignment
+// (PxConcreteType type, -----)
+// alignment
+// (PxConcreteType type, --------)
+// alignment
+// (PxConcreteType type, --)
+// .
+// .
+//
+//
+// -----------------------------------------------------------------------------------
+//// extra data:
+//// extra data memory block
+//// serialized and deserialized by PxBase implementations
+////----------------------------------------------------------------------------------
+// extra data
+//
+//------------------------------------------------------------------------------------
+
+namespace
+{
+
+ class LegacySerialStream : public PxSerializationContext
+ {
+ public:
+ LegacySerialStream(OutputStreamWriter& writer,
+ const PxCollection& collection,
+ bool exportNames) : mWriter(writer), mCollection(collection), mExportNames(exportNames) {}
+ void writeData(const void* buffer, PxU32 size) { mWriter.write(buffer, size); }
+ PxU32 getTotalStoredSize() { return mWriter.getStoredSize(); }
+ void alignData(PxU32 alignment)
+ {
+ if(!alignment)
+ return;
+
+ PxI32 bytesToPad = PxI32(getPadding(getTotalStoredSize(), alignment));
+ static const PxI32 BUFSIZE = 64;
+ char buf[BUFSIZE];
+ PxMemSet(buf, 0, bytesToPad < BUFSIZE ? PxU32(bytesToPad) : PxU32(BUFSIZE));
+ while(bytesToPad > 0)
+ {
+ writeData(buf, bytesToPad < BUFSIZE ? PxU32(bytesToPad) : PxU32(BUFSIZE));
+ bytesToPad -= BUFSIZE;
+ }
+ PX_ASSERT(!getPadding(getTotalStoredSize(), alignment));
+ }
+
+ virtual void registerReference(PxBase&, PxU32, size_t)
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__,
+ "Cannot register references during exportData, exportExtraData.");
+ }
+
+ virtual const PxCollection& getCollection() const
+ {
+ return mCollection;
+ }
+ virtual void writeName(const char* name)
+ {
+ PxU32 len = name && mExportNames ? PxU32(strlen(name)) + 1 : 0;
+ writeData(&len, sizeof(len));
+ if(len) writeData(name, len);
+ }
+
+ private:
+ LegacySerialStream& operator=(const LegacySerialStream&);
+ OutputStreamWriter& mWriter;
+ const PxCollection& mCollection;
+ bool mExportNames;
+ };
+
+ void writeHeader(PxSerializationContext& stream, bool hasDeserializedAssets)
+ {
+ PX_UNUSED(hasDeserializedAssets);
+ struct Header
+ {
+ PxU32 header;
+ PxU32 version;
+ PxU32 binaryVersion;
+ PxU32 buildNumber;
+ PxU32 platformTag;
+ PxU32 markedPadding;
+ PxU32 materialOffset;
+ };
+
+ //serialized binary data.
+ const PxU32 header = PX_MAKE_FOURCC('S','E','B','D');
+ stream.writeData(&header, sizeof(PxU32));
+
+ PxU32 version = PX_PHYSICS_VERSION;
+ stream.writeData(&version, sizeof(PxU32));
+
+ PxU32 binaryVersion = PX_BINARY_SERIAL_VERSION;
+ stream.writeData(&binaryVersion, sizeof(PxU32));
+
+ PxU32 buildNumber = 0;
+#if defined(PX_BUILD_NUMBER)
+ buildNumber = PX_BUILD_NUMBER;
+#endif
+ stream.writeData(&buildNumber, sizeof(PxU32));
+
+ PxU32 platformTag = getBinaryPlatformTag();
+ stream.writeData(&platformTag, sizeof(PxU32));
+
+ PxU32 markedPadding = 0;
+#if PX_CHECKED
+ if(!hasDeserializedAssets)
+ markedPadding = 1;
+#endif
+ stream.writeData(&markedPadding, sizeof(PxU32));
+ }
+}
+
+bool PxSerialization::serializeCollectionToBinary(PxOutputStream& outputStream, PxCollection& pxCollection, PxSerializationRegistry& sr, const PxCollection* pxExternalRefs, bool exportNames)
+{
+ if(!PxSerialization::isSerializable(pxCollection, sr, pxExternalRefs))
+ return false;
+
+ Collection& collection = static_cast<Collection&>(pxCollection);
+ const Collection* externalRefs = static_cast<const Collection*>(pxExternalRefs);
+
+ //temporary memory stream which allows fixing up data up stream
+
+ SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr);
+
+ // sort collection by "order" value (this will be the order in which they get serialized)
+ sortCollection(collection, sn, false);
+
+ //initialized the context with the sorted collection.
+ SerializationContext context(collection, externalRefs);
+
+ // gather reference information
+ bool hasDeserializedAssets = false;
+ {
+ const PxU32 nb = collection.internalGetNbObjects();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ PxBase* s = collection.internalGetObject(i);
+ PX_ASSERT(s && s->getConcreteType());
+#if PX_CHECKED
+ //can't guarantee marked padding for deserialized instances
+ if(!(s->getBaseFlags() & PxBaseFlag::eOWNS_MEMORY))
+ hasDeserializedAssets = true;
+#endif
+ const PxSerializer* serializer = sn.getSerializer(s->getConcreteType());
+ PX_ASSERT(serializer);
+ serializer->registerReferences(*s, context);
+ }
+ }
+
+ // now start the actual serialization into the output stream
+ OutputStreamWriter writer(outputStream);
+ LegacySerialStream stream(writer, collection, exportNames);
+
+ writeHeader(stream, hasDeserializedAssets);
+
+ // write size of collection
+ stream.alignData(PX_SERIAL_ALIGN);
+ PxU32 nbObjectsInCollection = collection.internalGetNbObjects();
+ stream.writeData(&nbObjectsInCollection, sizeof(PxU32));
+
+ // write the manifest table (PxU32 offset, PxConcreteType type)
+ {
+ Ps::Array<ManifestEntry> manifestTable(collection.internalGetNbObjects());
+ PxU32 headerOffset = 0;
+ for(PxU32 i=0;i<collection.internalGetNbObjects();i++)
+ {
+ PxBase* s = collection.internalGetObject(i);
+ PX_ASSERT(s && s->getConcreteType());
+ PxType concreteType = s->getConcreteType();
+ const PxSerializer* serializer = sn.getSerializer(concreteType);
+ PX_ASSERT(serializer);
+ manifestTable[i] = ManifestEntry(headerOffset, concreteType);
+ PxU32 classSize = PxU32(serializer->getClassSize());
+ headerOffset += getPadding(classSize, PX_SERIAL_ALIGN) + classSize;
+ }
+ stream.alignData(PX_SERIAL_ALIGN);
+ const PxU32 nb = manifestTable.size();
+ stream.writeData(&nb, sizeof(PxU32));
+ stream.writeData(manifestTable.begin(), manifestTable.size()*sizeof(ManifestEntry));
+
+ //store offset for end of object buffer (PxU32 offset)
+ stream.writeData(&headerOffset, sizeof(PxU32));
+ }
+
+ // write import references
+ {
+ const Ps::Array<ImportReference>& importReferences = context.getImportReferences();
+ stream.alignData(PX_SERIAL_ALIGN);
+ const PxU32 nb = importReferences.size();
+ stream.writeData(&nb, sizeof(PxU32));
+ stream.writeData(importReferences.begin(), importReferences.size()*sizeof(ImportReference));
+ }
+
+ // write export references
+ {
+ PxU32 nbIds = collection.getNbIds();
+ Ps::Array<ExportReference> exportReferences(nbIds);
+ //we can't get quickly from id to object index in collection.
+ //if we only need this here, its not worth to build a hash
+ nbIds = 0;
+ for (PxU32 i=0;i<collection.getNbObjects();i++)
+ {
+ PxBase& obj = collection.getObject(i);
+ PxSerialObjectId id = collection.getId(obj);
+ if (id != PX_SERIAL_OBJECT_ID_INVALID)
+ {
+ SerialObjectIndex objIndex(i, false); //i corresponds to manifest entry
+ exportReferences[nbIds++] = ExportReference(id, objIndex);
+ }
+ }
+ stream.alignData(PX_SERIAL_ALIGN);
+ stream.writeData(&nbIds, sizeof(PxU32));
+ stream.writeData(exportReferences.begin(), exportReferences.size()*sizeof(ExportReference));
+ }
+
+ // write internal references
+ {
+ InternalRefMap& internalReferencesPtrMap = context.getInternalReferencesPtrMap();
+ Ps::Array<InternalReferencePtr> internalReferencesPtr(internalReferencesPtrMap.size());
+ PxU32 nbInternalPtrReferences = 0;
+ for(InternalRefMap::Iterator iter = internalReferencesPtrMap.getIterator(); !iter.done(); ++iter)
+ internalReferencesPtr[nbInternalPtrReferences++] = InternalReferencePtr(iter->first.first, iter->first.second, iter->second);
+
+ InternalRefMap& internalReferencesIdxMap = context.getInternalReferencesIdxMap();
+ Ps::Array<InternalReferenceIdx> internalReferencesIdx(internalReferencesIdxMap.size());
+ PxU32 nbInternalIdxReferences = 0;
+ for(InternalRefMap::Iterator iter = internalReferencesIdxMap.getIterator(); !iter.done(); ++iter)
+ internalReferencesIdx[nbInternalIdxReferences++] = InternalReferenceIdx(Ps::to32(iter->first.first), iter->first.second, iter->second);
+
+ stream.alignData(PX_SERIAL_ALIGN);
+
+ stream.writeData(&nbInternalPtrReferences, sizeof(PxU32));
+ stream.writeData(internalReferencesPtr.begin(), internalReferencesPtr.size()*sizeof(InternalReferencePtr));
+
+ stream.writeData(&nbInternalIdxReferences, sizeof(PxU32));
+ stream.writeData(internalReferencesIdx.begin(), internalReferencesIdx.size()*sizeof(InternalReferenceIdx));
+ }
+
+ // write object data
+ {
+ stream.alignData(PX_SERIAL_ALIGN);
+ const PxU32 nb = collection.internalGetNbObjects();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ PxBase* s = collection.internalGetObject(i);
+ PX_ASSERT(s && s->getConcreteType());
+ const PxSerializer* serializer = sn.getSerializer(s->getConcreteType());
+ PX_ASSERT(serializer);
+ stream.alignData(PX_SERIAL_ALIGN);
+ serializer->exportData(*s, stream);
+ }
+ }
+
+ // write extra data
+ {
+ const PxU32 nb = collection.internalGetNbObjects();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ PxBase* s = collection.internalGetObject(i);
+ PX_ASSERT(s && s->getConcreteType());
+
+ const PxSerializer* serializer = sn.getSerializer(s->getConcreteType());
+ PX_ASSERT(serializer);
+
+ stream.alignData(PX_SERIAL_ALIGN);
+ serializer->exportExtraData(*s, stream);
+ }
+ }
+
+ return true;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.cpp
new file mode 100644
index 00000000..ad486c2d
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.cpp
@@ -0,0 +1,156 @@
+// 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.
+
+/*
+- get rid of STL
+
+- NpArticulationLinkArray with more than 4 entries
+- big convexes Xbox => PC
+
+- put a cache in "convertClass" function
+- remove MD one at a time and check what happens in the converter. Make it robust/report errors
+- for xbox, compare against source xbox file if it exists
+- maybe put some info in the header to display "File generated by ConvX 1.xx" on screen (to debug)
+- report inconsistent naming convention in each class!!!!
+- try to automatically discover padding bytes? use "0xcd" pattern?
+* do last param of XXXX_ITEMS macro automatically
+- what if source files are 64bits? can we safely convert a 64bit ptr to 32bit?
+*/
+
+#include "foundation/PxErrorCallback.h"
+#include "foundation/PxAllocatorCallback.h"
+#include "foundation/PxIO.h"
+#include "SnConvX.h"
+#include "serialization/SnSerializationRegistry.h"
+#include <assert.h>
+#include "PsFoundation.h"
+
+using namespace physx;
+
+Sn::ConvX::ConvX() :
+ mMetaData_Src (NULL),
+ mMetaData_Dst (NULL),
+ mOutStream (NULL),
+ mMustFlip (false),
+ mOutputSize (0),
+ mSrcPtrSize (0),
+ mDstPtrSize (0),
+ mNullPtr (false),
+ mNoOutput (false),
+ mMarkedPadding (false),
+ mNbErrors (0),
+ mNbWarnings (0),
+ mReportMode (PxConverterReportMode::eNORMAL),
+ mPerformConversion (true)
+{
+ // memset(mZeros, 0, CONVX_ZERO_BUFFER_SIZE);
+ memset(mZeros, 0x42, CONVX_ZERO_BUFFER_SIZE);
+}
+
+Sn::ConvX::~ConvX()
+{
+ resetNbErrors();
+ resetConvexFlags();
+ releaseMetaData();
+ resetUnions();
+}
+
+void Sn::ConvX::release()
+{
+ delete this;
+}
+
+bool Sn::ConvX::setMetaData(PxInputStream& inputStream, MetaDataType type)
+{
+ resetNbErrors();
+ return (loadMetaData(inputStream, type) != NULL);
+}
+
+bool Sn::ConvX::setMetaData(PxInputStream& srcMetaData, PxInputStream& dstMetaData)
+{
+ releaseMetaData();
+ resetUnions();
+
+ if(!setMetaData(srcMetaData, META_DATA_SRC))
+ return false;
+ if(!setMetaData(dstMetaData, META_DATA_DST))
+ return false;
+
+ return true;
+}
+
+
+bool Sn::ConvX::convert(PxInputStream& srcStream, PxU32 srcSize, PxOutputStream& targetStream)
+{
+ if(!mMetaData_Src || !mMetaData_Dst)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__,
+ "PxBinaryConverter: metadata not defined. Call PxBinaryConverter::setMetaData first.\n");
+ return false;
+ }
+
+ resetConvexFlags();
+ resetNbErrors();
+
+ bool conversionStatus = false;
+ if(mPerformConversion)
+ {
+ if(srcSize == 0)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxBinaryConverter: source serialized data size is zero.\n");
+ return false;
+ }
+
+ void* memory = PX_ALLOC_TEMP(srcSize+ALIGN_FILE, "ConvX source file");
+ void* memoryA = reinterpret_cast<void*>((size_t(memory) + ALIGN_FILE)&~(ALIGN_FILE-1));
+
+ const PxU32 nbBytesRead = srcStream.read(memoryA, srcSize);
+ if(nbBytesRead != srcSize)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
+ "PxBinaryConverter: failure on reading source serialized data.\n");
+ PX_FREE(memory);
+ return false;
+ }
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\n\nConverting...\n\n");
+
+ {
+ if(!initOutput(targetStream))
+ {
+ PX_FREE(memory);
+ return false;
+ }
+ conversionStatus = convert(memoryA, int(srcSize));
+ closeOutput();
+ }
+
+ PX_FREE(memory);
+ }
+ return conversionStatus;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.h
new file mode 100644
index 00000000..9ce9d86f
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX.h
@@ -0,0 +1,182 @@
+// 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.
+
+#ifndef PX_CONVX_H
+#define PX_CONVX_H
+
+#include "foundation/PxErrors.h"
+#include "PxBinaryConverter.h"
+#include "PxTypeInfo.h"
+#include "CmPhysXCommon.h"
+#include "PsUserAllocated.h"
+#include "PsArray.h"
+#include "SnConvX_Common.h"
+#include "SnConvX_Union.h"
+#include "SnConvX_MetaData.h"
+#include "SnConvX_Align.h"
+
+#define CONVX_ZERO_BUFFER_SIZE 256
+
+namespace physx {
+
+class PxSerializationRegistry;
+
+namespace Sn {
+
+ struct HeightFieldData;
+ class PointerRemap
+ {
+ public:
+ PointerRemap();
+ ~PointerRemap();
+
+ bool checkRefIsNotUsed(PxU32 ref) const;
+ void setObjectRef(PxU64 object64, PxU32 ref);
+ bool getObjectRef(PxU64 object64, PxU32& ref) const;
+
+ struct InternalData
+ {
+ PxU64 object;
+ PxU32 id;
+ };
+
+ Ps::Array<InternalData> mData;
+ };
+
+ class ConvX : public physx::PxBinaryConverter, public shdfnd::UserAllocated
+ {
+ public:
+ ConvX();
+ virtual ~ConvX();
+
+ virtual void release();
+ virtual void setReportMode(PxConverterReportMode::Enum mode) { mReportMode = mode; }
+ PX_FORCE_INLINE bool silentMode() const { return mReportMode==PxConverterReportMode::eNONE; }
+ PX_FORCE_INLINE bool verboseMode() const { return mReportMode==PxConverterReportMode::eVERBOSE; }
+
+ virtual bool setMetaData(PxInputStream& srcMetaData, PxInputStream& dstMetaData);
+ virtual bool convert(PxInputStream& srcStream, PxU32 srcSize, PxOutputStream& targetStream);
+
+ private:
+ ConvX& operator=(const ConvX&);
+ bool setMetaData(PxInputStream& inputStream, MetaDataType type);
+
+ // Meta-data
+ void releaseMetaData();
+ const MetaData* loadMetaData(PxInputStream& inputStream, MetaDataType type);
+ const MetaData* getBinaryMetaData(MetaDataType type);
+ int getNbMetaClasses(MetaDataType type);
+ MetaClass* getMetaClass(unsigned int i, MetaDataType type) const;
+ MetaClass* getMetaClass(const char* name, MetaDataType type) const;
+ MetaClass* getMetaClass(PxConcreteType::Enum concreteType, MetaDataType type);
+ MetaData* mMetaData_Src;
+ MetaData* mMetaData_Dst;
+
+ // Convert
+
+ bool convert(const void* buffer, int fileSize);
+ void resetConvexFlags();
+ void _enumerateFields(const MetaClass* mc, ExtraDataEntry2* entries, int& nb, int baseOffset, MetaDataType type) const;
+ void _enumerateExtraData(const char* address, const MetaClass* mc, ExtraDataEntry* entries, int& nb, int offset, MetaDataType type) const;
+ PxU64 read64(const void*& buffer);
+ int read32(const void*& buffer);
+ short read16(const void*& buffer);
+ bool convertClass(const char* buffer, const MetaClass* mc, int offset);
+ const char* convertExtraData_Array(const char* Address, const char* lastAddress, const char* objectAddress, const ExtraDataEntry& ed);
+ const char* convertExtraData_Ptr(const char* Address, const char* lastAddress, const PxMetaDataEntry& entry, int count, int ptrSize_Src, int ptrSize_Dst);
+ int getConcreteType(const char* buffer);
+ bool convertCollection(const void* buffer, int fileSize, int nbObjects);
+ const void* convertManifestTable(const void* buffer, int& fileSize);
+ const void* convertImportReferences(const void* buffer, int& fileSize);
+ const void* convertExportReferences(const void* buffer, int& fileSize);
+ const void* convertInternalReferences(const void* buffer, int& fileSize);
+ const void* convertReferenceTables(const void* buffer, int& fileSize, int& nbObjectsInCollection);
+ bool checkPaddingBytes(const char* buffer, int byteCount);
+
+ // ---- big convex surgery ----
+ PsArray<bool> mConvexFlags;
+ // Align
+ const char* alignStream(const char* buffer, int alignment=ALIGN_DEFAULT);
+ void alignTarget(int alignment);
+
+ char mZeros[CONVX_ZERO_BUFFER_SIZE];
+ // Unions
+ bool registerUnion(const char* name);
+ bool registerUnionType(const char* unionName, const char* typeName, int typeValue);
+ const char* getTypeName(const char* unionName, int typeValue);
+ void resetUnions();
+ PsArray<Union> mUnions;
+ // Output
+ void setNullPtr(bool);
+ void setNoOutput(bool);
+ bool initOutput(PxOutputStream& targetStream);
+ void closeOutput();
+ int getCurrentOutputSize();
+ void output(short value);
+ void output(int value);
+ void output(PxU64 value);
+ void output(const char* buffer, int nbBytes);
+ void convert8 (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convertPad8 (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convert16 (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convert32 (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convert64 (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convertFloat(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ void convertPtr (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+ PxOutputStream* mOutStream;
+ bool mMustFlip;
+ int mOutputSize;
+ int mSrcPtrSize;
+ int mDstPtrSize;
+ bool mNullPtr;
+ bool mNoOutput;
+ bool mMarkedPadding;
+
+ // Errors
+ void resetNbErrors();
+ int getNbErrors() const;
+ void displayMessage(physx::PxErrorCode::Enum code, const char* format, ...);
+ int mNbErrors;
+ int mNbWarnings;
+
+ // Settings
+ PxConverterReportMode::Enum mReportMode;
+ bool mPerformConversion;
+
+ // Remap pointers
+ void exportIntAsPtr(int value);
+ void exportInt(int value);
+ void exportInt64(PxU64 value);
+ PointerRemap mRemap;
+ PointerRemap* mActiveRemap;
+ PxU32 mPointerRemapCounter;
+
+ friend class MetaData;
+ friend struct MetaClass;
+ };
+} }
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.cpp
new file mode 100644
index 00000000..5c576f5c
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.cpp
@@ -0,0 +1,63 @@
+// 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.
+
+#include "SnConvX.h"
+#include "SnConvX_Align.h"
+#include <assert.h>
+using namespace physx;
+
+void Sn::ConvX::alignTarget(int alignment)
+{
+ const int outputSize = getCurrentOutputSize();
+ const PxU32 outPadding = getPadding(size_t(outputSize), PxU32(alignment));
+ if(outPadding)
+ {
+ assert(outPadding<CONVX_ZERO_BUFFER_SIZE);
+ output(mZeros, int(outPadding));
+ }
+}
+
+const char* Sn::ConvX::alignStream(const char* buffer, int alignment)
+{
+ const PxU32 padding = getPadding(size_t(buffer), PxU32(alignment));
+ assert(!getPadding(size_t(buffer + padding), PxU32(alignment)));
+
+ const int outputSize = getCurrentOutputSize();
+ const PxU32 outPadding = getPadding(size_t(outputSize), PxU32(alignment));
+ if(outPadding==padding)
+ {
+ assert(outPadding<CONVX_ZERO_BUFFER_SIZE);
+ output(mZeros, int(outPadding));
+ }
+ else if(outPadding)
+ {
+ assert(outPadding<CONVX_ZERO_BUFFER_SIZE);
+ output(mZeros, int(outPadding));
+ }
+
+ return buffer + padding;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.h
new file mode 100644
index 00000000..b3ec81c2
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Align.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef PX_CONVX_ALIGN_H
+#define PX_CONVX_ALIGN_H
+
+namespace physx { namespace Sn {
+ #define ALIGN_DEFAULT 16
+ #define ALIGN_FILE 128
+
+ PX_INLINE PxU32 getPadding(size_t value, PxU32 alignment)
+ {
+ const PxU32 mask = alignment-1;
+ const PxU32 overhead = PxU32(value) & mask;
+ return (alignment - overhead) & mask;
+ }
+
+} }
+
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Common.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Common.h
new file mode 100644
index 00000000..677480e4
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Common.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef PX_CONVX_COMMON_H
+#define PX_CONVX_COMMON_H
+
+#if PX_VC
+#pragma warning(disable:4121) // alignment of a member was sensitive to packing
+#endif
+
+#include "common/PxPhysXCommonConfig.h"
+
+#define DELETESINGLE(x) if(x){ delete x; x = NULL; }
+#define DELETEARRAY(x) if(x){ delete []x; x = NULL; }
+
+#define inline_ PX_FORCE_INLINE
+#define PsArray physx::shdfnd::Array
+
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Convert.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Convert.cpp
new file mode 100644
index 00000000..a9fe0b9c
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Convert.cpp
@@ -0,0 +1,1434 @@
+// 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.
+
+#include "foundation/PxErrorCallback.h"
+#include "SnConvX.h"
+#include "serialization/SnSerialUtils.h"
+#include "PsAlloca.h"
+#include "CmUtils.h"
+#include "PxDefaultStreams.h"
+#include <assert.h>
+
+using namespace physx;
+using namespace physx::Sn;
+using namespace Cm;
+
+void Sn::ConvX::resetConvexFlags()
+{
+ mConvexFlags.clear();
+}
+
+void Sn::ConvX::_enumerateFields(const MetaClass* mc, ExtraDataEntry2* entries, int& nb, int baseOffset, MetaDataType type) const
+{
+ PxU32 nbFields = mc->mFields.size();
+ int offsetCheck = baseOffset;
+ for(PxU32 j=0;j<nbFields;j++)
+ {
+ const PxMetaDataEntry& entry = mc->mFields[j];
+ if(entry.mFlags & PxMetaDataFlag::eCLASS || entry.mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ continue;
+
+ assert(offsetCheck == baseOffset + entry.mOffset);
+
+ int currentOffset = baseOffset + entry.mOffset;
+
+ //for(int c=0;c<entry.mCount;c++)
+ {
+ if(entry.mFlags & PxMetaDataFlag::eUNION)
+ {
+ entries[nb].entry = entry;
+ entries[nb].offset = currentOffset;
+ entries[nb].cb = 0;
+ nb++;
+ }
+ else if(entry.mFlags & PxMetaDataFlag::ePTR) // This also takes care of the vtable pointer
+ {
+ entries[nb].entry = entry;
+ entries[nb].offset = currentOffset;
+ entries[nb].cb = &Sn::ConvX::convertPtr;
+ nb++;
+ }
+ else
+ {
+ MetaClass* fieldType = getMetaClass(entry.mType, type);
+ assert(fieldType);
+ if(fieldType->mCallback)
+ {
+ entries[nb].entry = entry;
+ entries[nb].offset = currentOffset;
+ entries[nb].cb = fieldType->mCallback;
+ nb++;
+ }
+ else
+ {
+ for(int c=0;c<entry.mCount;c++)
+ {
+ _enumerateFields(fieldType, entries, nb, currentOffset, type);
+ currentOffset += entry.mSize/entry.mCount;
+ }
+ }
+ }
+ }
+ offsetCheck += entry.mSize;
+ }
+}
+
+void Sn::ConvX::_enumerateExtraData(const char* address, const MetaClass* mc, ExtraDataEntry* entries,
+ int& nb, int offset, MetaDataType type) const
+{
+ PxU32 nbFields = mc->mFields.size();
+ for(PxU32 j=0;j<nbFields;j++)
+ {
+ const PxMetaDataEntry& entry = mc->mFields[j];
+ if(entry.mFlags & PxMetaDataFlag::eCLASS /*|| entry.mFlags & PxMetaDataFlag::ePTR*/ || entry.mFlags & PxMetaDataFlag::eTYPEDEF)
+ continue;
+
+ const char* entryType = entry.mType;
+
+ //
+ // Insanely Twisted Shadow GeometryUnion
+ //
+ // Special code is needed as long as there are no meta data tags to describe our unions properly. The way it is done here is
+ // not future-proof at all. There should be a tag to describe where the union type can be found and the number of bytes
+ // this type id needs. Then a mapping needs to get added from each union type id to the proper meta class name.
+ //
+ if (entry.mFlags & PxMetaDataFlag::eUNION)
+ {
+ if (!mc->mClassName || strcmp(mc->mClassName, "Gu::GeometryUnion")!=0)
+ continue;
+ else
+ {
+ // ### hardcoded bit here, will only work when union type is the first int of the struct
+ const int* tmp = reinterpret_cast<const int*>(address + offset);
+ const int unionType = *tmp;
+
+ ConvX* tmpConv = const_cast<ConvX*>(this); // ... don't ask
+ const char* typeName = tmpConv->getTypeName(entry.mType, unionType);
+ assert(typeName);
+
+ bool isTriMesh = (strcmp(typeName, "PxTriangleMeshGeometryLL") == 0);
+ bool isHeightField = (strcmp(typeName, "PxHeightFieldGeometryLL") == 0);
+ if (!isTriMesh && !isHeightField)
+ {
+ continue;
+ }
+ else
+ {
+ entryType = typeName;
+ }
+ }
+ }
+
+ // MetaClass* extraDataType = getMetaClass(entry.mType, type);
+ // if(!extraDataType)
+ // continue;
+
+ if(entry.mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ {
+ entries[nb].entry = entry;
+ entries[nb].offset = offset+entry.mOffset;
+ nb++;
+ }
+ else
+ {
+ if(entry.mFlags & PxMetaDataFlag::ePTR)
+ continue;
+
+ MetaClass* extraDataType = getMetaClass(entryType, type);
+ if(!extraDataType)
+ continue;
+
+ if(!extraDataType->mCallback)
+ _enumerateExtraData(address, extraDataType, entries, nb, offset+entry.mOffset, type);
+ }
+ }
+}
+
+PxU64 Sn::ConvX::read64(const void*& buffer)
+{
+ const PxU64* buf64 = reinterpret_cast<const PxU64*>(buffer);
+ buffer = reinterpret_cast<const void*>(size_t(buffer) + sizeof(PxU64));
+ PxU64 value = *buf64;
+ output(value);
+ return value;
+}
+
+int Sn::ConvX::read32(const void*& buffer)
+{
+ const int* buf32 = reinterpret_cast<const int*>(buffer);
+ buffer = reinterpret_cast<const void*>(size_t(buffer) + sizeof(int));
+ int value = *buf32;
+ output(value);
+ return value;
+}
+
+short Sn::ConvX::read16(const void*& buffer)
+{
+ const short* buf16 = reinterpret_cast<const short*>(buffer);
+ buffer = reinterpret_cast<const void*>(size_t(buffer) + sizeof(short));
+ short value = *buf16;
+ output(value);
+ return value;
+}
+
+#if PX_CHECKED
+extern const char* gVTable;
+static bool compareEntries(const ExtraDataEntry2& e0, const ExtraDataEntry2& e1)
+{
+ if(e0.entry.isVTablePtr() && e1.entry.isVTablePtr())
+ return true;
+
+ if((e0.entry.mFlags & PxMetaDataFlag::eUNION) && (e1.entry.mFlags & PxMetaDataFlag::eUNION))
+ {
+ if(e0.entry.mType && e1.entry.mType)
+ {
+ // We can't compare the ptrs since they index different string tables
+ if(strcmp(e0.entry.mType, e1.entry.mType)==0)
+ return true;
+ }
+ return false;
+ }
+
+ if(e0.entry.mName && e1.entry.mName)
+ {
+ // We can't compare the ptrs since they index different string tables
+ if(strcmp(e0.entry.mName, e1.entry.mName)==0)
+ return true;
+ }
+ return false;
+}
+#endif
+
+// TODO: optimize this
+bool Sn::ConvX::convertClass(const char* buffer, const MetaClass* mc, int offset)
+{
+ // ---- big convex surgery ----
+ bool convexSurgery = false;
+ bool foundNbVerts = false;
+ bool removeBigData = false;
+
+ // force reference
+ (void)foundNbVerts;
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "%s\n", mc->mClassName);
+ displayMessage(PxErrorCode::eDEBUG_INFO, "+++++++++++++++++++++++++++++++++++++++++++++\n");
+
+ if(strcmp(mc->mClassName, "ConvexMesh")==0)
+ {
+ convexSurgery = true;
+ }
+ // ---- big convex surgery ----
+
+ int nbSrcEntries = 0;
+ PX_ALLOCA(srcEntries, ExtraDataEntry2, 256); // ### painful ctors here
+ int nbDstEntries = 0;
+ PX_ALLOCA(dstEntries, ExtraDataEntry2, 256); // ### painful ctors here
+ // Find corresponding meta-class for target platform
+ const MetaClass* target_mc = getMetaClass(mc->mClassName, META_DATA_DST);
+ assert(target_mc);
+
+ if(mc->mCallback)
+ {
+ srcEntries[0].cb = mc->mCallback;
+ srcEntries[0].offset = offset;
+ srcEntries[0].entry.mType = mc->mClassName;
+ srcEntries[0].entry.mName = mc->mClassName;
+ srcEntries[0].entry.mOffset = offset;
+ srcEntries[0].entry.mSize = mc->mSize;
+ srcEntries[0].entry.mCount = 1;
+ srcEntries[0].entry.mFlags = 0;
+ nbSrcEntries = 1;
+
+ assert(target_mc->mCallback);
+ dstEntries[0].cb = target_mc->mCallback;
+ dstEntries[0].offset = offset;
+ dstEntries[0].entry.mType = target_mc->mClassName;
+ dstEntries[0].entry.mName = target_mc->mClassName;
+ dstEntries[0].entry.mOffset = offset;
+ dstEntries[0].entry.mSize = target_mc->mSize;
+ dstEntries[0].entry.mCount = 1;
+ dstEntries[0].entry.mFlags = 0;
+ nbDstEntries = 1;
+ }
+ else
+ {
+ nbSrcEntries = 0;
+ _enumerateFields(mc, srcEntries, nbSrcEntries, 0, META_DATA_SRC);
+ assert(nbSrcEntries<256);
+
+ nbDstEntries = 0;
+ _enumerateFields(target_mc, dstEntries, nbDstEntries, 0, META_DATA_DST);
+ assert(nbDstEntries<256);
+
+ // nb = mc->mNbEntries;
+ // assert(nb>=0);
+ // memcpy(entries, mc->mEntries, nb*sizeof(ExtraDataEntry2));
+ }
+
+ int srcOffsetCheck = 0;
+ int dstOffsetCheck = 0;
+ int j = 0;
+ // Track cases where the vtable pointer location is different for different platforms.
+ // The variables indicate whether a platform has a vtable pointer entry that has not been converted yet
+ // and they will remember the index of the corrssponding entry. This works because there can only
+ // be one open vtable pointer entry at a time.
+ int srcOpenVTablePtrEntry = -1;
+ int dstOpenVTablePtrEntry = -1;
+
+ //if the src and dst platform place the vtable pointers at different locations some fiddling with the iteration count can be necessary.
+ int addVTablePtrShiftIteration = 0;
+ const int maxNb = nbSrcEntries > nbDstEntries ? nbSrcEntries : nbDstEntries;
+ for(int i=0; i < (maxNb + addVTablePtrShiftIteration); i++)
+ {
+
+ if (i < nbSrcEntries)
+ {
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\t0x%p\t%x\t%d\t%d\t%s", buffer + srcOffsetCheck,
+ buffer[srcOffsetCheck], srcOffsetCheck, srcEntries[i].entry.mOffset, srcEntries[i].entry.mName);
+ for (int byteCount = 1; byteCount < srcEntries[i].entry.mSize; ++byteCount)
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\t0x%p\t%x\t%d\t%d\t.", buffer + srcOffsetCheck + byteCount,
+ buffer[srcOffsetCheck + byteCount], srcOffsetCheck + byteCount, srcEntries[i].entry.mOffset + byteCount);
+ }
+
+ bool handlePadding = true;
+ bool skipLoop = false;
+ while(handlePadding)
+ {
+ const int pad0 = i<nbSrcEntries ? srcEntries[i].entry.mFlags & PxMetaDataFlag::ePADDING : 0;
+ const int pad1 = j<nbDstEntries ? dstEntries[j].entry.mFlags & PxMetaDataFlag::ePADDING : 0;
+ if(pad0 || pad1)
+ {
+ if(pad0)
+ {
+#if PX_CHECKED
+ if (mMarkedPadding && (strcmp(srcEntries[i].entry.mType, "paddingByte")==0))
+ if(!checkPaddingBytes(buffer + srcOffsetCheck, srcEntries[i].entry.mSize))
+ {
+ if(i>0)
+ {
+ displayMessage(PxErrorCode::eDEBUG_WARNING,
+ "PxBinaryConverter warning: Bytes after %s::%s don't look like padding bytes. Likely mismatch between binary data and metadata.\n",
+ mc->mClassName, srcEntries[i-1].entry.mName );
+ }
+ else
+ displayMessage(PxErrorCode::eDEBUG_WARNING,
+ "PxBinaryConverter warning: Bytes after %s don't look like padding bytes. Likely mismatch between binary data and metadata.\n",
+ mc->mClassName);
+
+ }
+#endif
+ if(pad1)
+ {
+ // Both have padding
+ // ### check sizes, output bytes
+ if(srcEntries[i].entry.mSize==dstEntries[j].entry.mSize)
+ {
+ // I guess we can just go on with the normal code here
+ handlePadding = false;
+ }
+ else
+ {
+ // Output padding
+ assert(srcEntries[i].cb);
+ assert(srcEntries[i].offset == srcOffsetCheck);
+
+ const int padSize = dstEntries[j].entry.mSize;
+ char* paddingBytes = reinterpret_cast<char*>(PX_ALLOC(sizeof(char)*padSize, "paddingByte"));
+ memset(paddingBytes, 0, size_t(padSize));
+ assert(dstEntries[j].cb);
+ (this->*dstEntries[j].cb)(paddingBytes, dstEntries[j].entry, dstEntries[j].entry);
+ assert(dstOffsetCheck==dstEntries[j].offset);
+ dstOffsetCheck += padSize;
+ PX_FREE(paddingBytes);
+
+ // srcEntries[i].cb(buffer+srcOffsetCheck, srcEntries[i].entry, dstEntries[j].entry);
+ // assert(dstOffsetCheck==dstEntries[j].offset);
+ // dstOffsetCheck += dstEntries[j].entry.mSize;
+ srcOffsetCheck += srcEntries[i].entry.mSize;
+
+ // Skip dest padding field
+ j++;
+
+ // continue; // ### BUG, doesn't go back to the "for"
+ skipLoop = true;
+ handlePadding = false;
+ }
+ }
+ else
+ {
+ // Src has padding, dst has not => skip conversion
+ // Don't increase j
+ skipLoop = true;
+ handlePadding = false;
+ srcOffsetCheck += srcEntries[i].entry.mSize;
+ }
+ }
+ else
+ {
+ if(pad1)
+ {
+ // Dst has padding, src has not
+
+ // Output padding
+ const int padSize = dstEntries[j].entry.mSize;
+ char* paddingBytes = reinterpret_cast<char*>(PX_ALLOC(sizeof(char)*padSize, "paddingByte"));
+ memset(paddingBytes, 0, size_t(padSize));
+ assert(dstEntries[j].cb);
+ (this->*dstEntries[j].cb)(paddingBytes, dstEntries[j].entry, dstEntries[j].entry);
+ assert(dstOffsetCheck==dstEntries[j].offset);
+ dstOffsetCheck += padSize;
+ PX_FREE(paddingBytes);
+
+ // Skip dest padding field, keep same src field
+ j++;
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+ }
+ else handlePadding = false;
+ }
+
+ if(skipLoop)
+ continue;
+
+ int modSrcOffsetCheck = srcOffsetCheck;
+ const ExtraDataEntry2* srcEntryPtr = &srcEntries[i];
+ const ExtraDataEntry2* dstEntryPtr = &dstEntries[j];
+
+ bool isSrcVTablePtr = (i < nbSrcEntries) ? srcEntryPtr->entry.isVTablePtr() : false;
+ if (isSrcVTablePtr && (dstOpenVTablePtrEntry != -1))
+ {
+ // vtable ptr position mismatch:
+ // this check is necessary to align src and dst index again when the
+ // dst vtable pointer has been written already and the src vtable ptr
+ // element is reached.
+ //
+ // i
+ // src: | a | b | vt-ptr | c | ...
+ // dst: | vt-ptr | a | b | c | ...
+ // j
+ //
+ // it needs special treatment because the following case fails otherwise
+ // i
+ // src: | a | b | vt-ptr | c | vt-ptr | ...
+ // dst: | vt-ptr | a | b | vt-ptr | c | ...
+ // j
+
+ //
+ // This entry has been written already -> advance to next src entry
+ //
+ srcOffsetCheck += srcEntryPtr->entry.mSize;
+ i++;
+ isSrcVTablePtr = (i < nbSrcEntries) ? srcEntryPtr->entry.isVTablePtr() : false;
+ PX_ASSERT(dstOpenVTablePtrEntry < nbDstEntries);
+ PX_ASSERT(dstEntries[dstOpenVTablePtrEntry].entry.isVTablePtr());
+ dstOpenVTablePtrEntry = -1;
+ PX_ASSERT(addVTablePtrShiftIteration == 0);
+ }
+ bool isDstVTablePtr = (j < nbDstEntries) ? dstEntryPtr->entry.isVTablePtr() : false;
+ if (isDstVTablePtr && (srcOpenVTablePtrEntry != -1))
+ {
+ // i
+ // src: | vt-ptr | a | b | c | ...
+ // dst: | a | b | vt-ptr | c | ...
+ // j
+
+ i--; // next iteration the current element should get processed
+ isSrcVTablePtr = true;
+ PX_ASSERT(srcOpenVTablePtrEntry < nbSrcEntries);
+ srcEntryPtr = &srcEntries[srcOpenVTablePtrEntry];
+ PX_ASSERT(srcEntryPtr->entry.isVTablePtr());
+ modSrcOffsetCheck = srcEntryPtr->offset;
+ srcOffsetCheck -= srcEntryPtr->entry.mSize; // to make sure total change is 0 after this iteration
+ srcOpenVTablePtrEntry = -1;
+ PX_ASSERT(addVTablePtrShiftIteration == 1);
+ addVTablePtrShiftIteration = 0;
+ }
+
+ if(i==nbSrcEntries && j==nbDstEntries)
+ {
+ PX_ASSERT((srcOpenVTablePtrEntry == -1) && (dstOpenVTablePtrEntry == -1));
+ break;
+ }
+
+ if (isSrcVTablePtr || isDstVTablePtr)
+ {
+ if (!isSrcVTablePtr)
+ {
+ // i
+ // src: | a | b | vt-ptr | c | ...
+ // dst: | vt-ptr | a | b | c | ...
+ // j
+
+ PX_ASSERT(dstOpenVTablePtrEntry == -1); // the other case should be detected and treated earlier
+ PX_ASSERT(srcOpenVTablePtrEntry == -1);
+ PX_ASSERT(addVTablePtrShiftIteration == 0);
+
+ int k;
+ for(k=i+1; k < nbSrcEntries; k++)
+ {
+ if (srcEntries[k].entry.isVTablePtr())
+ break;
+ }
+ PX_ASSERT(k < nbSrcEntries);
+
+ srcEntryPtr = &srcEntries[k];
+ modSrcOffsetCheck = srcEntryPtr->offset;
+ srcOffsetCheck -= srcEntryPtr->entry.mSize; // to make sure total change is 0 after this iteration
+
+ dstOpenVTablePtrEntry = j;
+ i--; // to make sure the original entry gets processed in the next iteration
+ }
+ else if (!isDstVTablePtr)
+ {
+ // i ---> i
+ // src: | vt-ptr | a | b | c | ...
+ // dst: | a | b | vt-ptr | c | ...
+ // j
+
+ PX_ASSERT(srcOpenVTablePtrEntry == -1); // the other case should be detected and treated earlier
+ PX_ASSERT(dstOpenVTablePtrEntry == -1);
+ PX_ASSERT(addVTablePtrShiftIteration == 0);
+
+ srcOffsetCheck += srcEntryPtr->entry.mSize;
+ modSrcOffsetCheck = srcOffsetCheck;
+ srcOpenVTablePtrEntry = i;
+ i++;
+ srcEntryPtr = &srcEntries[i];
+
+ addVTablePtrShiftIteration = 1; // additional iteration might be needed to process vtable pointer at the end of a class
+
+ PX_ASSERT((i < nbSrcEntries) && ((srcEntryPtr->entry.mFlags & PxMetaDataFlag::ePADDING) == 0));
+ // if the second check fails, this whole section might have to be done before the padding bytes get processed. Not sure
+ // what other consequences that might have though.
+ }
+ }
+#if PX_CHECKED
+ else
+ {
+ if(!compareEntries(*srcEntryPtr, *dstEntryPtr))
+ {
+ displayMessage(PxErrorCode::eINVALID_PARAMETER, "\rConvX::convertClass: %s, src meta data and dst meta data don't match!", mc->mClassName);
+ return false;
+ }
+ }
+#endif
+
+ const ExtraDataEntry2& srcEntry = *srcEntryPtr;
+ const ExtraDataEntry2& dstEntry = *dstEntryPtr;
+
+ if(srcEntry.entry.mFlags & PxMetaDataFlag::eUNION)
+ {
+ // ### hardcoded bit here, will only work when union type is the first int of the struct
+ const int* tmp = reinterpret_cast<const int*>(buffer + modSrcOffsetCheck);
+ const int unionType = *tmp;
+
+ const char* typeName = getTypeName(srcEntry.entry.mType, unionType);
+ assert(typeName);
+
+ MetaClass* unionMC = getMetaClass(typeName, META_DATA_SRC);
+ assert(unionMC);
+
+ convertClass(buffer + modSrcOffsetCheck, unionMC, 0); // ### recurse
+
+ dstOffsetCheck += dstEntry.entry.mSize;
+
+ MetaClass* targetUnionMC = getMetaClass(typeName, META_DATA_DST);
+ assert(targetUnionMC);
+
+ const int delta = dstEntry.entry.mSize - targetUnionMC->mSize;
+ char* deltaBytes = reinterpret_cast<char*>(PX_ALLOC(sizeof(char)*delta, "deltaBytes"));
+ memset(deltaBytes, 0, size_t(delta));
+ output(deltaBytes, delta); // Skip unused bytes at the end of the union
+ PX_FREE(deltaBytes);
+ srcOffsetCheck += srcEntry.entry.mSize; // do not use modSrcOffsetCheck here!
+ }
+ else
+ {
+ assert(srcEntry.cb);
+ assert(srcEntry.offset == modSrcOffsetCheck);
+
+ // ---- big convex surgery ----
+ if(convexSurgery)
+ {
+ if(strcmp(srcEntry.entry.mName, "mNbHullVertices")==0)
+ {
+ assert(srcEntry.entry.mSize==1);
+ const int nbVerts = int(*(buffer+modSrcOffsetCheck));
+ assert(!foundNbVerts);
+ foundNbVerts = true;
+
+ const int gaussMapLimit = getBinaryMetaData(META_DATA_DST)->getGaussMapLimit();
+ if(nbVerts > gaussMapLimit)
+ {
+ // We need a gauss map and we have one => keep it
+ }
+ else
+ {
+ // We don't need a gauss map and we have one => remove it
+ removeBigData = true;
+ }
+ }
+ else
+ {
+ if(removeBigData)
+ {
+ const bool isBigConvexData = strcmp(srcEntry.entry.mType, "BigConvexData")==0 ||
+ strcmp(srcEntry.entry.mType, "BigConvexRawData")==0;
+ if(isBigConvexData)
+ {
+ assert(foundNbVerts);
+ setNullPtr(true);
+ }
+ }
+ }
+ }
+ // ---- big convex surgery ----
+
+ (this->*srcEntry.cb)(buffer+modSrcOffsetCheck, srcEntry.entry, dstEntry.entry);
+ assert(dstOffsetCheck==dstEntry.offset);
+ dstOffsetCheck += dstEntry.entry.mSize;
+ srcOffsetCheck += srcEntry.entry.mSize; // do not use modSrcOffsetCheck here!
+
+ // ---- big convex surgery ----
+ if(convexSurgery && removeBigData)
+ setNullPtr(false);
+ // ---- big convex surgery ----
+ }
+
+ j++;
+ }
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "---------------------------------------------\n");
+
+ while(j<nbDstEntries)
+ {
+ assert(dstEntries[j].entry.mFlags & PxMetaDataFlag::ePADDING);
+ if(dstEntries[j].entry.mFlags & PxMetaDataFlag::ePADDING)
+ {
+ dstOffsetCheck += dstEntries[j].entry.mSize;
+ }
+ j++;
+ }
+
+ assert(j==nbDstEntries);
+ assert(dstOffsetCheck==target_mc->mSize);
+ assert(srcOffsetCheck==mc->mSize);
+
+ // ---- big convex surgery ----
+ if(convexSurgery)
+ mConvexFlags.pushBack(removeBigData);
+ // ---- big convex surgery ----
+
+ return true;
+}
+
+// Handles data defined with PX_DEF_BIN_METADATA_EXTRA_ARRAY
+const char* Sn::ConvX::convertExtraData_Array(const char* Address, const char* lastAddress, const char* objectAddress,
+ const ExtraDataEntry& ed)
+{
+ (void)lastAddress;
+ MetaClass* mc = getMetaClass(ed.entry.mType, META_DATA_SRC);
+ assert(mc);
+
+ // PT: safe to cast to int here since we're reading a count.
+ const int count = int(peek(ed.entry.mSize, objectAddress + ed.offset, ed.entry.mFlags));
+
+ // if(ed.entry.mCount) // Reused as align value
+ if(ed.entry.mAlignment)
+ {
+ Address = alignStream(Address, ed.entry.mAlignment);
+ // Address = alignStream(Address, ed.entry.mCount);
+ assert(Address<=lastAddress);
+ }
+
+ for(int c=0;c<count;c++)
+ {
+ convertClass(Address, mc, 0);
+ Address += mc->mSize;
+ assert(Address<=lastAddress);
+ }
+ return Address;
+}
+
+const char* Sn::ConvX::convertExtraData_Ptr(const char* Address, const char* lastAddress, const PxMetaDataEntry& entry, int count,
+ int ptrSize_Src, int ptrSize_Dst)
+{
+ (void)lastAddress;
+
+ PxMetaDataEntry tmpSrc = entry;
+ tmpSrc.mCount = count;
+ tmpSrc.mSize = count * ptrSize_Src;
+
+ PxMetaDataEntry tmpDst = entry;
+ tmpDst.mCount = count;
+ tmpDst.mSize = count * ptrSize_Dst;
+
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "extra data ptrs\n");
+ displayMessage(PxErrorCode::eDEBUG_INFO, "+++++++++++++++++++++++++++++++++++++++++++++\n");
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\t0x%p\t%x\t\t\t%s", Address, Address[0], entry.mName);
+ for (int byteCount = 1; byteCount < ptrSize_Src*count; ++byteCount)
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\t0x%p\t%x\t\t\t.", Address + byteCount, Address[byteCount]);
+
+ convertPtr(Address, tmpSrc, tmpDst);
+ Address += count * ptrSize_Src;
+ assert(Address<=lastAddress);
+ return Address;
+}
+
+static bool decodeControl(PxU64 control, const ExtraDataEntry& ed, PxU64 controlMask = 0)
+{
+ if(ed.entry.mFlags & PxMetaDataFlag::eCONTROL_FLIP)
+ {
+ if(controlMask)
+ {
+ return (control & controlMask) ? false : true;
+ }
+ else
+ {
+ return control==0;
+ }
+ }
+ else
+ {
+ if(controlMask)
+ {
+ return (control & controlMask) ? true : false;
+ }
+ else
+ {
+ return control!=0;
+ }
+ }
+
+}
+
+// ### currently hardcoded, should change
+int Sn::ConvX::getConcreteType(const char* buffer)
+{
+ MetaClass* mc = getMetaClass("PxBase", META_DATA_SRC);
+ assert(mc);
+ PxMetaDataEntry entry;
+ if(mc->getFieldByType("PxType", entry))
+ {
+ // PT: safe to cast to int here since we're reading our own PxType
+ return int(peek(entry.mSize, buffer + entry.mOffset));
+ }
+ assert(0);
+ return 0xffffffff;
+}
+
+struct Item : public shdfnd::UserAllocated
+{
+ MetaClass* mc;
+ const char* address;
+};
+
+bool Sn::ConvX::convertCollection(const void* buffer, int fileSize, int nbObjects)
+{
+ const char* lastAddress = reinterpret_cast<const char*>(buffer) + fileSize;
+ const char* Address = alignStream(reinterpret_cast<const char*>(buffer));
+
+ const int ptrSize_Src = mSrcPtrSize;
+ const int ptrSize_Dst = mDstPtrSize;
+ Item* objects = PX_NEW(Item)[PxU32(nbObjects)];
+
+ for(PxU32 i=0;i<PxU32(nbObjects);i++)
+ {
+ const float percents = float(i)/float(nbObjects);
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "Object conversion: %d%%", int(percents*100.0f));
+
+ Address = alignStream(Address);
+ assert(Address<=lastAddress);
+
+ PxConcreteType::Enum classType = PxConcreteType::Enum(getConcreteType(Address));
+ MetaClass* metaClass = getMetaClass(classType, META_DATA_SRC);
+ if(!metaClass)
+ {
+ PX_DELETE_ARRAY(objects);
+ return false;
+ }
+
+ objects[i].mc = metaClass;
+ objects[i].address = Address;
+
+ if(!convertClass(Address, metaClass, 0))
+ {
+ PX_DELETE_ARRAY(objects);
+ return false;
+ }
+
+ Address += metaClass->mSize;
+ assert(Address<=lastAddress);
+ }
+
+ // Fields / extra data
+ if(1)
+ {
+ // ---- big convex surgery ----
+ unsigned int nbConvexes = 0;
+ // ---- big convex surgery ----
+ //const char* StartAddress2 = Address;
+ //int startDstSize2 = getCurrentOutputSize();
+ for(int i=0;i<nbObjects;i++)
+ {
+ //const char* StartAddress = Address;
+ //int startDstSize = getCurrentOutputSize();
+
+ const float percents = float(i)/float(nbObjects);
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, "Extra data conversion: %d%%", int(percents*100.0f));
+
+ MetaClass* mc0 = objects[i].mc;
+ const char* objectAddress = objects[i].address;
+
+ // printf("%d: %s\n", i, mc->mClassName);
+ // if(strcmp(mc->mClassName, "TriangleMesh")==0)
+ // if(strcmp(mc->mClassName, "NpRigidDynamic")==0)
+ if(strcmp(mc0->mClassName, "HybridModel")==0)
+ {
+ int stop=1;
+ (void)(stop);
+ }
+
+ // ### we actually need to collect all extra data for this class, including data from embedded members.
+
+ PX_ALLOCA(entries, ExtraDataEntry, 256);
+ int nbEntries = 0;
+ _enumerateExtraData(objectAddress, mc0, entries, nbEntries, 0, META_DATA_SRC);
+ assert(nbEntries<256);
+
+ Address = alignStream(Address);
+ assert(Address<=lastAddress);
+
+ for(int j=0;j<nbEntries;j++)
+ {
+ const ExtraDataEntry& ed = entries[j];
+ assert(ed.entry.mFlags & PxMetaDataFlag::eEXTRA_DATA);
+
+ if(ed.entry.mFlags & PxMetaDataFlag::eEXTRA_ITEM)
+ {
+ // ---- big convex surgery ----
+ if(1)
+ {
+ const bool isBigConvexData = strcmp(ed.entry.mType, "BigConvexData")==0;
+ if(isBigConvexData)
+ {
+ assert(nbConvexes<mConvexFlags.size());
+ if(mConvexFlags[nbConvexes++])
+ setNoOutput(true);
+ }
+ }
+ // ---- big convex surgery ----
+
+ MetaClass* extraDataType = getMetaClass(ed.entry.mType, META_DATA_SRC);
+ assert(extraDataType);
+
+ //sschirm: we used to have ed.entry.mOffset here, but that made cloth deserialization fail.
+ const char* controlAddress = objectAddress + ed.offset;
+ const PxU64 controlValue = peek(ed.entry.mOffsetSize, controlAddress);
+
+ if(controlValue)
+ {
+ if(ed.entry.mAlignment)
+ {
+ Address = alignStream(Address, ed.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+
+ const char* classAddress = Address;
+ convertClass(Address, extraDataType, 0);
+ Address += extraDataType->mSize;
+ assert(Address<=lastAddress);
+
+ // Enumerate extra data for this optional class, and convert it too.
+ // This assumes the extra data for the optional class is always appended to the class itself,
+ // which is something we'll need to enforce in the SDK. So far this is only to handle optional
+ // inline arrays.
+
+ // ### this should probably be recursive eventually
+ PX_ALLOCA(entries2, ExtraDataEntry, 256);
+ int nbEntries2 = 0;
+ _enumerateExtraData(objectAddress, extraDataType, entries2, nbEntries2, 0, META_DATA_SRC);
+ assert(nbEntries2<256);
+ for(int k=0;k<nbEntries2;k++)
+ {
+ const ExtraDataEntry& ed2 = entries2[k];
+ assert(ed2.entry.mFlags & PxMetaDataFlag::eEXTRA_DATA);
+ if(ed2.entry.mFlags & PxMetaDataFlag::eEXTRA_ITEMS)
+ {
+ const int controlOffset = ed2.entry.mOffset;
+ const int controlSize = ed2.entry.mSize;
+ const int countOffset = ed2.entry.mCount;
+ const int countSize = ed2.entry.mOffsetSize;
+
+ const PxU64 controlValue2 = peek(controlSize, classAddress + controlOffset);
+
+ PxU64 controlMask = 0;
+ if(ed2.entry.mFlags & PxMetaDataFlag::eCONTROL_MASK)
+ {
+ controlMask = PxU64(ed2.entry.mFlags & (PxMetaDataFlag::eCONTROL_MASK_RANGE << 16));
+ controlMask = controlMask >> 16;
+ }
+
+ if(decodeControl(controlValue2, ed2, controlMask))
+ {
+ // PT: safe to cast to int here since we're reading a count
+ int count = int(peek(countSize, classAddress + countOffset, ed2.entry.mFlags));
+
+ if(ed2.entry.mAlignment)
+ {
+ assert(0); // Never tested
+ Address = alignStream(Address, ed2.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+
+ if(ed2.entry.mFlags & PxMetaDataFlag::ePTR)
+ {
+ assert(0); // Never tested
+ }
+ else
+ {
+ MetaClass* mc = getMetaClass(ed2.entry.mType, META_DATA_SRC);
+ assert(mc);
+
+ while(count--)
+ {
+ convertClass(Address, mc, 0);
+ Address += mc->mSize;
+ assert(Address<=lastAddress);
+ }
+ }
+
+ }
+ }
+ else
+ {
+ if( (ed2.entry.mFlags & PxMetaDataFlag::eALIGNMENT) && ed2.entry.mAlignment)
+ {
+ Address = alignStream(Address, ed2.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+ else
+ {
+ // We assume it's an normal array, e.g. the ones from "big convexes"
+ assert(!(ed2.entry.mFlags & PxMetaDataFlag::eEXTRA_ITEM));
+
+ Address = convertExtraData_Array(Address, lastAddress, classAddress, ed2);
+ }
+ }
+ }
+
+ }
+ else
+ {
+ int stop = 0;
+ (void)(stop);
+ }
+
+ // ---- big convex surgery ----
+ setNoOutput(false);
+ // ---- big convex surgery ----
+ }
+ else if(ed.entry.mFlags & PxMetaDataFlag::eEXTRA_ITEMS)
+ {
+ // PX_DEF_BIN_METADATA_EXTRA_ITEMS
+ int reloc = ed.offset - ed.entry.mOffset; // ### because the enum code only fixed the "controlOffset"!
+ const int controlOffset = ed.entry.mOffset;
+ const int controlSize = ed.entry.mSize;
+ const int countOffset = ed.entry.mCount;
+ const int countSize = ed.entry.mOffsetSize;
+
+ // const int controlValue2 = peek(controlSize, objectAddress + controlOffset);
+ const PxU64 controlValue2 = peek(controlSize, objectAddress + controlOffset + reloc);
+
+ PxU64 controlMask = 0;
+ if(ed.entry.mFlags & PxMetaDataFlag::eCONTROL_MASK)
+ {
+ controlMask = PxU64(ed.entry.mFlags & (PxMetaDataFlag::eCONTROL_MASK_RANGE << 16));
+ controlMask = controlMask >> 16;
+ }
+
+ if(decodeControl(controlValue2, ed, controlMask))
+ {
+ // PT: safe to cast to int here since we're reading a count
+ // int count = peek(countSize, objectAddress + countOffset); // ###
+ int count = int(peek(countSize, objectAddress + countOffset + reloc, ed.entry.mFlags)); // ###
+
+ if(ed.entry.mAlignment)
+ {
+ Address = alignStream(Address, ed.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+
+ if(ed.entry.mFlags & PxMetaDataFlag::ePTR)
+ {
+ Address = convertExtraData_Ptr(Address, lastAddress, ed.entry, count, ptrSize_Src, ptrSize_Dst);
+ }
+ else
+ {
+ MetaClass* mc = getMetaClass(ed.entry.mType, META_DATA_SRC);
+ assert(mc);
+
+ while(count--)
+ {
+ convertClass(Address, mc, 0);
+ Address += mc->mSize;
+ assert(Address<=lastAddress);
+ }
+ }
+ }
+
+ }
+ else if(ed.entry.mFlags & PxMetaDataFlag::eALIGNMENT)
+ {
+ if(ed.entry.mAlignment)
+ {
+ displayMessage(PxErrorCode::eDEBUG_INFO, " align to %d bytes\n", ed.entry.mAlignment);
+ displayMessage(PxErrorCode::eDEBUG_INFO, "---------------------------------------------\n");
+
+ Address = alignStream(Address, ed.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+ }
+ else if(ed.entry.mFlags & PxMetaDataFlag::eEXTRA_NAME)
+ {
+ if(ed.entry.mAlignment)
+ {
+ Address = alignStream(Address, ed.entry.mAlignment);
+ assert(Address<=lastAddress);
+ }
+
+ //get string count
+ MetaClass* mc = getMetaClass("PxU32", META_DATA_SRC);
+ assert(mc);
+ //safe to cast to int here since we're reading a count.
+ const int count = int(peek(mc->mSize, Address, 0));
+
+ displayMessage(PxErrorCode::eDEBUG_INFO, " convert %d bytes string\n", count);
+
+ convertClass(Address, mc, 0);
+ Address += mc->mSize;
+
+ mc = getMetaClass(ed.entry.mType, META_DATA_SRC);
+ assert(mc);
+
+ for(int c=0;c<count;c++)
+ {
+ convertClass(Address, mc, 0);
+ Address += mc->mSize;
+ assert(Address<=lastAddress);
+ }
+ }
+ else
+ {
+ Address = convertExtraData_Array(Address, lastAddress, objectAddress, ed);
+ }
+ }
+ }
+ PX_DELETE_ARRAY(objects);
+ assert(nbConvexes==mConvexFlags.size());
+ }
+
+ assert(Address==lastAddress);
+
+ return true;
+}
+
+bool Sn::ConvX::convert(const void* buffer, int fileSize)
+{
+ // Test initial alignment
+ if(size_t(buffer) & (ALIGN_DEFAULT-1))
+ {
+ assert(0);
+ return false;
+ }
+
+ const int header = read32(buffer); fileSize -= 4; (void)header;
+
+ if (header != PX_MAKE_FOURCC('S','E','B','D'))
+ {
+ displayMessage(physx::PxErrorCode::eINVALID_PARAMETER,
+ "PxBinaryConverter: Buffer contains data with bad header indicating invalid serialized data.");
+ return false;
+ }
+
+ const int version = read32(buffer); fileSize -= 4; (void)version;
+
+ const int binaryVersion = read32(buffer); fileSize -= 4;
+
+ if (!checkCompatibility(PxU32(version), PxU32(binaryVersion)))
+ {
+ char buf[512];
+ getCompatibilityVersionsStr(buf, 512);
+
+ displayMessage(physx::PxErrorCode::eINVALID_PARAMETER,
+ "PxBinaryConverter: Buffer contains data version (%x-%d) is incompatible with this PhysX sdk.\n These versions would be compatible: %s",
+ version, binaryVersion, buf);
+ return false;
+ }
+ const int buildNumber = read32(buffer); fileSize -= 4; (void)buildNumber;
+
+ //read src platform tag and write dst platform tag according dst meta data
+ const int srcPlatformTag = *reinterpret_cast<const int*>(buffer);
+ buffer = reinterpret_cast<const void*>(size_t(buffer) + 4);
+ fileSize -= 4;
+ const int dstPlatformTag = mMetaData_Dst->getPlatformTag();
+ output(dstPlatformTag);
+
+ if (srcPlatformTag != mMetaData_Src->getPlatformTag())
+ {
+ displayMessage(physx::PxErrorCode::eINVALID_PARAMETER,
+ "PxBinaryConverter: Mismatch of platform tags of binary data and metadata:\n Binary Data: %s\n MetaData: %s\n",
+ getBinaryPlatformName(PxU32(srcPlatformTag)),
+ getBinaryPlatformName(PxU32(mMetaData_Src->getPlatformTag())));
+ return false;
+ }
+
+ //read whether input data has marked padding, and set it for the output data (since 0xcd is written into pads on conversion)
+ const int srcMarkedPadding = *reinterpret_cast<const int*>(buffer);
+ buffer = reinterpret_cast<const void*>(size_t(buffer) + 4);
+ fileSize -= 4;
+ mMarkedPadding = srcMarkedPadding != 0;
+ const int dstMarkedPadding = 1;
+ output(dstMarkedPadding);
+
+ int nbObjectsInCollection;
+
+ buffer = convertReferenceTables(buffer, fileSize, nbObjectsInCollection);
+ if(!buffer)
+ return false;
+
+ bool ret = convertCollection(buffer, fileSize, nbObjectsInCollection);
+ mMarkedPadding = false;
+ return ret;
+}
+
+// PT: code below added to support 64bit-to-32bit conversions
+void Sn::ConvX::exportIntAsPtr(int value)
+{
+ const int ptrSize_Src = mSrcPtrSize;
+ const int ptrSize_Dst = mDstPtrSize;
+
+ PxMetaDataEntry entry;
+
+ const char* address = NULL;
+ const PxU32 value32 = PxU32(value);
+ const PxU64 value64 = PxU64(value)&0xffffffff;
+
+ if(ptrSize_Src==4)
+ {
+ address = reinterpret_cast<const char*>(&value32);
+ }
+ else if(ptrSize_Src==8)
+ {
+ address = reinterpret_cast<const char*>(&value64);
+ }
+ else assert(0);
+
+ convertExtraData_Ptr(address, address + ptrSize_Src, entry, 1, ptrSize_Src, ptrSize_Dst);
+}
+
+void Sn::ConvX::exportInt(int value)
+{
+ output(value);
+}
+
+void Sn::ConvX::exportInt64(PxU64 value)
+{
+ output(value);
+}
+
+PointerRemap::PointerRemap()
+{
+}
+
+PointerRemap::~PointerRemap()
+{
+}
+
+bool PointerRemap::checkRefIsNotUsed(PxU32 ref) const
+{
+ const PxU32 size = mData.size();
+ for(PxU32 i=0;i<size;i++)
+ {
+ if(mData[i].id==ref)
+ return false;
+ }
+ return true;
+}
+
+void PointerRemap::setObjectRef(PxU64 object64, PxU32 ref)
+{
+ const PxU32 size = mData.size();
+ for(PxU32 i=0;i<size;i++)
+ {
+ if(mData[i].object==object64)
+ {
+ mData[i].id = ref;
+ return;
+ }
+ }
+ InternalData data;
+ data.object = object64;
+ data.id = ref;
+ mData.pushBack(data);
+}
+
+bool PointerRemap::getObjectRef(PxU64 object64, PxU32& ref) const
+{
+ const PxU32 size = mData.size();
+ for(PxU32 i=0;i<size;i++)
+ {
+ if(mData[i].object==object64)
+ {
+ ref = mData[i].id;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+Converting the PxBase object offsets in the manifest table is fairly complicated now.
+It would be good to have an easy callback mechanism for custom things like this.
+*/
+const void* Sn::ConvX::convertManifestTable(const void* buffer, int& fileSize)
+{
+ PxU32 padding = getPadding(size_t(buffer), ALIGN_DEFAULT);
+ buffer = alignStream(reinterpret_cast<const char*>(buffer));
+ fileSize -= padding;
+ int nb = read32(buffer);
+ fileSize -= 4;
+
+ MetaClass* mc_src = getMetaClass("Sn::ManifestEntry", META_DATA_SRC);
+ assert(mc_src);
+
+ MetaClass* mc_dst = getMetaClass("Sn::ManifestEntry", META_DATA_DST);
+ assert(mc_dst);
+
+ bool mdOk;
+ PxMetaDataEntry srcTypeField;
+ mdOk = mc_src->getFieldByName("type", srcTypeField);
+ PX_UNUSED(mdOk);
+ PX_ASSERT(mdOk);
+
+ PxMetaDataEntry dstOffsetField;
+ mdOk = mc_dst->getFieldByName("offset", dstOffsetField);
+ PX_ASSERT(mdOk);
+
+ const char* address = reinterpret_cast<const char*>(buffer);
+ PxU32 headerOffset = 0;
+ for(int i=0;i<nb;i++)
+ {
+ PxConcreteType::Enum classType = PxConcreteType::Enum(peek(srcTypeField.mSize, address + srcTypeField.mOffset));
+
+ //convert ManifestEntry but output to tmpStream
+ PxDefaultMemoryOutputStream tmpStream;
+ {
+ //backup output state
+ PxOutputStream* outStream = mOutStream;
+ PxU32 outputSize = PxU32(mOutputSize);
+
+ mOutStream = &tmpStream;
+ mOutputSize = 0;
+
+ convertClass(address, mc_src, 0);
+ PX_ASSERT(tmpStream.getSize() == PxU32(mc_dst->mSize));
+
+ //restore output state
+ mOutStream = outStream;
+ mOutputSize = int(outputSize);
+ }
+
+ //output patched offset
+ PX_ASSERT(dstOffsetField.mOffset == 0); //assuming offset is the first data
+ output(int(headerOffset));
+
+ //output rest of ManifestEntry
+ PxU32 restSize = PxU32(mc_dst->mSize - dstOffsetField.mSize);
+ mOutStream->write(tmpStream.getData() + dstOffsetField.mSize, restSize);
+ mOutputSize += restSize;
+
+ //increment source stream
+ address += mc_src->mSize;
+ fileSize -= mc_src->mSize;
+ assert(fileSize>=0);
+
+ //update headerOffset using the type and dst meta data of the type
+ MetaClass* mc_classType_dst = getMetaClass(classType, META_DATA_DST);
+ if(!mc_classType_dst)
+ return NULL;
+ headerOffset += getPadding(size_t(mc_classType_dst->mSize), PX_SERIAL_ALIGN) + mc_classType_dst->mSize;
+ }
+
+ output(int(headerOffset)); //endoffset
+ buffer = address + 4;
+ fileSize -= 4;
+ return buffer;
+}
+
+const void* Sn::ConvX::convertImportReferences(const void* buffer, int& fileSize)
+{
+ PxU32 padding = getPadding(size_t(buffer), ALIGN_DEFAULT);
+ buffer = alignStream(reinterpret_cast<const char*>(buffer));
+ fileSize -= padding;
+ int nb = read32(buffer);
+ fileSize -= 4;
+
+ if(!nb)
+ return buffer;
+
+ MetaClass* mc = getMetaClass("Sn::ImportReference", META_DATA_SRC);
+ assert(mc);
+
+ const char* address = reinterpret_cast<const char*>(buffer);
+ for(int i=0;i<nb;i++)
+ {
+ convertClass(address, mc, 0);
+ address += mc->mSize;
+ fileSize -= mc->mSize;
+ assert(fileSize>=0);
+ }
+ return address;
+}
+
+const void* Sn::ConvX::convertExportReferences(const void* buffer, int& fileSize)
+{
+ PxU32 padding = getPadding(size_t(buffer), ALIGN_DEFAULT);
+ buffer = alignStream(reinterpret_cast<const char*>(buffer));
+ fileSize -= padding;
+ int nb = read32(buffer);
+ fileSize -= 4;
+
+ if(!nb)
+ return buffer;
+
+ MetaClass* mc = getMetaClass("Sn::ExportReference", META_DATA_SRC);
+ assert(mc);
+
+ const char* address = reinterpret_cast<const char*>(buffer);
+ for(int i=0;i<nb;i++)
+ {
+ convertClass(address, mc, 0);
+ address += mc->mSize;
+ fileSize -= mc->mSize;
+ assert(fileSize>=0);
+ }
+ return address;
+}
+
+const void* Sn::ConvX::convertInternalReferences(const void* buffer, int& fileSize)
+{
+ PxU32 padding = getPadding(size_t(buffer), ALIGN_DEFAULT);
+ buffer = alignStream(reinterpret_cast<const char*>(buffer));
+ fileSize -= padding;
+
+ //pointer references
+ int nbPtrReferences = read32(buffer);
+ fileSize -= 4;
+ if(nbPtrReferences)
+ {
+ const char* address = reinterpret_cast<const char*>(buffer);
+ MetaClass* mc = getMetaClass("Sn::InternalReferencePtr", META_DATA_SRC);
+ assert(mc);
+ for(int i=0;i<nbPtrReferences;i++)
+ {
+ convertClass(address, mc, 0);
+ address += mc->mSize;
+ fileSize -= mc->mSize;
+ assert(fileSize>=0);
+ }
+ buffer = address;
+ }
+
+ //index references
+ int nbIdxReferences = read32(buffer);
+ fileSize -= 4;
+ if (nbIdxReferences)
+ {
+ const char* address = reinterpret_cast<const char*>(buffer);
+ MetaClass* mc = getMetaClass("Sn::InternalReferenceIdx", META_DATA_SRC);
+ assert(mc);
+ for(int i=0;i<nbIdxReferences;i++)
+ {
+ convertClass(address, mc, 0);
+ address += mc->mSize;
+ fileSize -= mc->mSize;
+ assert(fileSize>=0);
+ }
+ buffer = address;
+ }
+ return buffer;
+}
+
+
+const void* Sn::ConvX::convertReferenceTables(const void* buffer, int& fileSize, int& nbObjectsInCollection)
+{
+ // PT: the map should not be used while creating it, so use one indirection
+ mActiveRemap = NULL;
+ mRemap.mData.clear();
+ mPointerRemapCounter = 0;
+
+ PxU32 padding = getPadding(size_t(buffer), ALIGN_DEFAULT);
+ buffer = alignStream(reinterpret_cast<const char*>(buffer));
+ fileSize -= padding;
+
+ nbObjectsInCollection = read32(buffer);
+ if (nbObjectsInCollection == 0)
+ displayMessage(PxErrorCode::eDEBUG_INFO, "\n\nConverting empty collection!\n\n");
+ fileSize -= 4;
+
+ buffer = convertManifestTable(buffer, fileSize);
+
+ if(!buffer)
+ return NULL;
+
+ buffer = convertImportReferences(buffer, fileSize);
+ buffer = convertExportReferences(buffer, fileSize);
+ buffer = convertInternalReferences(buffer, fileSize);
+
+ // PT: the map can now be used
+ mActiveRemap = &mRemap;
+
+ return buffer;
+}
+
+bool Sn::ConvX::checkPaddingBytes(const char* buffer, int byteCount)
+{
+ const unsigned char* src = reinterpret_cast<const unsigned char*>(buffer);
+
+ int i = 0;
+ while ((i < byteCount) && (src[i] == 0xcd))
+ i++;
+ return (i == byteCount);
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Error.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Error.cpp
new file mode 100644
index 00000000..9debc679
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Error.cpp
@@ -0,0 +1,92 @@
+// 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.
+
+#include "foundation/PxErrorCallback.h"
+#include "SnConvX.h"
+#include <stdarg.h>
+#include "PsString.h"
+#include "PsFoundation.h"
+
+#define MAX_DISPLAYED_ISSUES 10
+
+using namespace physx;
+
+void Sn::ConvX::resetNbErrors()
+{
+ mNbErrors = 0;
+ mNbWarnings = 0;
+}
+
+int Sn::ConvX::getNbErrors() const
+{
+ return mNbErrors;
+}
+
+void Sn::ConvX::displayMessage(PxErrorCode::Enum code, const char* format, ...)
+{
+ if(silentMode())
+ return;
+
+ int sum = mNbWarnings + mNbErrors;
+ if(sum >= MAX_DISPLAYED_ISSUES)
+ return;
+
+ bool display = false;
+
+ if(code==PxErrorCode::eINTERNAL_ERROR || code==PxErrorCode::eINVALID_OPERATION || code==PxErrorCode::eINVALID_PARAMETER)
+ {
+ mNbErrors++;
+ display = true;
+ }
+ else if(code == PxErrorCode::eDEBUG_WARNING)
+ {
+ mNbWarnings++;
+ display = true;
+ }
+
+ if(display || ((sum == 0) && verboseMode()) )
+ {
+ va_list va;
+ va_start(va, format);
+ Ps::getFoundation().errorImpl(code, __FILE__, __LINE__, format, va);
+ va_end(va);
+ }
+
+ if(display)
+ {
+ if( sum == 0)
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_INFO, __FILE__, __LINE__, "Hit warnings or errors: skipping further verbose output.\n");
+ }
+ else if(sum == MAX_DISPLAYED_ISSUES-1)
+ {
+ Ps::getFoundation().error(PxErrorCode::eDEBUG_INFO, __FILE__, __LINE__, "Exceeding 10 warnings or errors: skipping further output.\n");
+ }
+ }
+
+ return;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.cpp
new file mode 100644
index 00000000..4d2eda22
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.cpp
@@ -0,0 +1,840 @@
+// 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.
+
+#include "foundation/PxIO.h"
+#include "SnConvX.h"
+#include "common/PxSerialFramework.h"
+#include "serialization/SnSerialUtils.h"
+#include <assert.h>
+
+using namespace physx;
+using namespace physx::Sn;
+
+//#define REMOVE_EXPLICIT_PADDING
+
+static const char gVTablePtr[] = "v-table ptr";
+static const char gAutoPadding[] = "auto-generated padding";
+static const char gByte[] = "paddingByte";
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool PxMetaDataEntry::isVTablePtr() const
+{
+ return mType==gVTablePtr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool MetaClass::getFieldByType(const char* type, PxMetaDataEntry& entry) const
+{
+ assert(type);
+ PxU32 nbFields = mFields.size();
+ for(PxU32 i=0;i<nbFields;i++)
+ {
+ if(strcmp(mFields[i].mType, type)==0)
+ {
+ entry = mFields[i];
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MetaClass::getFieldByName(const char* name, PxMetaDataEntry& entry) const
+{
+ assert(name);
+ PxU32 nbFields = mFields.size();
+ for(PxU32 i=0;i<nbFields;i++)
+ {
+ if(strcmp(mFields[i].mName, name)==0)
+ {
+ entry = mFields[i];
+ return true;
+ }
+ }
+ return false;
+}
+
+void MetaClass::checkAndCompleteClass(const MetaData& owner, int& startOffset, int& nbBytes)
+{
+ if(startOffset!=-1)
+ {
+ owner.mConvX.displayMessage(PxErrorCode::eDEBUG_INFO,
+ "\n Adding %d padding bytes at offset %d in class %s.\n", nbBytes, startOffset, mClassName);
+
+ // Leap of faith: add padding bytes there
+ PxMetaDataEntry padding;
+ padding.mType = gByte;
+ padding.mName = gAutoPadding;
+ padding.mOffset = startOffset;
+ padding.mSize = nbBytes;
+ padding.mCount = nbBytes;
+ padding.mFlags = PxMetaDataFlag::ePADDING;
+ mFields.pushBack(padding);
+
+ startOffset = -1;
+ }
+}
+
+bool MetaClass::check(const MetaData& owner)
+{
+ owner.mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, "Checking class: %s\n", mClassName);
+
+ if(mCallback)
+ return true; // Skip atomic types
+ if(mMaster)
+ return true; // Skip typedefs
+
+ bool* map = reinterpret_cast<bool*>(PX_ALLOC(sizeof(bool)*mSize, "bool"));
+ memset(map, 0, size_t(mSize));
+
+ const PxU32 nbFields = mFields.size();
+ for(PxU32 i=0;i<nbFields;i++)
+ {
+ const PxMetaDataEntry& field = mFields[i];
+ if(field.mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ continue;
+// if((field.mFlags & PxMetaDataFlag::eUNION) && !field.mSize)
+// continue; // Union type
+ assert(field.mSize);
+ const int byteStart = field.mOffset;
+ const int byteEnd = field.mOffset + field.mSize;
+ assert(byteStart>=0 && byteStart<mSize);
+ assert(byteEnd>=0 && byteEnd<=mSize);
+
+ int startOffset = -1;
+ int nbBytes = 0;
+ for(int j=byteStart;j<byteEnd;j++)
+ {
+ if(map[j])
+ {
+ if(startOffset==-1)
+ {
+ startOffset = int(i);
+ nbBytes = 0;
+ }
+ nbBytes++;
+// displayErrorMessage(" %s: found overlapping bytes!\n", mClassName);
+ }
+ else
+ {
+ if(startOffset!=-1)
+ {
+ owner.mConvX.displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: %s: %d overlapping bytes at offset %d!\n", mClassName, nbBytes, startOffset);
+ startOffset = -1;
+ PX_ALWAYS_ASSERT_MESSAGE("Overlapping bytes!");
+ }
+ }
+ map[j] = true;
+ }
+ if(startOffset!=-1)
+ {
+ owner.mConvX.displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: %s: %d overlapping bytes at offset %d!\n", mClassName, nbBytes, startOffset);
+ startOffset = -1;
+ PX_ALWAYS_ASSERT_MESSAGE("Overlapping bytes!");
+ }
+ }
+
+ {
+ int startOffset = -1;
+ int nbBytes = 0;
+ for(int i=0;i<mSize;i++)
+ {
+ if(!map[i])
+ {
+ if(startOffset==-1)
+ {
+ startOffset = i;
+ nbBytes = 0;
+ }
+ nbBytes++;
+ }
+ else
+ {
+ checkAndCompleteClass(owner, startOffset, nbBytes);
+ }
+ }
+ checkAndCompleteClass(owner, startOffset, nbBytes);
+ }
+ PX_FREE(map);
+
+
+ //
+ for(PxU32 i=0;i<nbFields;i++)
+ {
+ const PxMetaDataEntry& current = mFields[i];
+ if(current.mFlags & PxMetaDataFlag::ePTR)
+ continue;
+
+ MetaClass* fieldMetaClass = owner.mConvX.getMetaClass(current.mType, owner.getType());
+ if(!fieldMetaClass)
+ {
+ owner.mConvX.displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: Missing meta-data for: %s\n", current.mType);
+ return false;
+ }
+ else
+ {
+ if(current.mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ {
+ owner.mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, "Extra data: %s\n", current.mType);
+ }
+ else
+ {
+ assert(fieldMetaClass->mSize*current.mCount==current.mSize);
+ }
+ }
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+MetaData::MetaData(ConvX& convx) :
+ mConvX (convx),
+ mType (META_DATA_NONE),
+ mNbEntries (0),
+ mEntries (NULL),
+ mStringTable (NULL),
+ mVersion (0),
+ mBuildNumber (0),
+ mSizeOfPtr (0),
+ mPlatformTag (0),
+ mGaussMapLimit (0),
+ mFlip (false)
+{
+}
+
+MetaData::~MetaData()
+{
+ PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 i=0;i<nbMetaClasses;i++)
+ {
+ MetaClass* current = mMetaClasses[i];
+ PX_DELETE(current);
+ }
+
+ PX_FREE(mStringTable);
+ PX_DELETE_ARRAY(mEntries);
+}
+
+MetaClass* MetaData::getMetaClass(const char* name) const
+{
+ PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 i=0;i<nbMetaClasses;i++)
+ {
+ MetaClass* current = mMetaClasses[i];
+ if(strcmp(current->mClassName, name)==0)
+ {
+ while(current->mMaster)
+ current = current->mMaster;
+ return current;
+ }
+ }
+ return NULL;
+}
+
+MetaClass* MetaData::getMetaClass(PxConcreteType::Enum concreteType) const
+{
+ for(PxU32 i=0; i< mConcreteTypeTable.size(); i++)
+ {
+ if(mConcreteTypeTable[i].first == concreteType)
+ {
+ const char* className = offsetToText(reinterpret_cast<const char*>(size_t(mConcreteTypeTable[i].second)));
+ return getMetaClass(className);
+ }
+ }
+ return NULL;
+}
+
+MetaClass* MetaData::addNewClass(const char* name, int size, MetaClass* master, ConvertCallback callback)
+{
+ // PT: if you reach this assert, you used PX_DEF_BIN_METADATA_TYPEDEF twice on the same type
+ assert(!getMetaClass(name));
+ MetaClass* mc = PX_NEW(MetaClass);
+ mc->mCallback = callback;
+ mc->mMaster = master;
+ mc->mClassName = name;
+ mc->mSize = size;
+ mc->mDepth = 0;
+ mc->mProcessed = false;
+// mc->mNbEntries = -1;
+
+ mMetaClasses.pushBack(mc);
+
+ return mc;
+}
+
+bool MetaData::load(PxInputStream& inputStream, MetaDataType type)
+{
+ assert(type!=META_DATA_NONE);
+
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, "Loading %s meta-data...\n", type==META_DATA_SRC ? "source" : "target");
+
+ mType = type;
+
+ mFlip = false;
+ {
+ int header;
+ inputStream.read(&header, 4);
+ if(header==PX_MAKE_FOURCC('M','E','T','A'))
+ {
+ mFlip = false;
+ }
+ else if(header==PX_MAKE_FOURCC('A','T','E','M'))
+ {
+ mFlip = true;
+ }
+ else
+ {
+ mConvX.displayMessage(PxErrorCode::eINVALID_PARAMETER, "PxBinaryConverter: invalid meta-data file!\n");
+ return false;
+ }
+
+ if (type == META_DATA_SRC && mFlip)
+ {
+ mConvX.displayMessage(PxErrorCode::eINVALID_PARAMETER,
+ "PxBinaryConverter: source meta data needs to match endianness with current system!");
+ return false;
+ }
+
+ inputStream.read(&mVersion, 4);
+ inputStream.read(&mBinaryVersion, 4);
+ if(mFlip)
+ {
+ flip(mVersion);
+ flip(mBinaryVersion);
+ }
+
+ if (!checkCompatibility(PxU32(mVersion), PxU32(mBinaryVersion)))
+ {
+ char buffer[512];
+ getCompatibilityVersionsStr(buffer, 512);
+
+ mConvX.displayMessage(PxErrorCode::eINVALID_PARAMETER,
+ "PxBinaryConverter: data version (%x-%d) is incompatible with this PhysX sdk.\n These versions would be compatible: %s",
+ mVersion, mBinaryVersion, buffer);
+
+ return false;
+ }
+ inputStream.read(&mBuildNumber, 4);
+ if(mFlip)
+ flip(mBuildNumber);
+
+
+ inputStream.read(&mSizeOfPtr, 4);
+ if(mFlip)
+ flip(mSizeOfPtr);
+
+ inputStream.read(&mPlatformTag, 4);
+ if(mFlip)
+ flip(mPlatformTag);
+
+ if (!Sn::isBinaryPlatformTagValid(PxU32(mPlatformTag)))
+ {
+ mConvX.displayMessage(PxErrorCode::eINVALID_PARAMETER, "PxBinaryConverter: Unknown meta data platform tag");
+ return false;
+ }
+
+ inputStream.read(&mGaussMapLimit, 4);
+ if(mFlip)
+ flip(mGaussMapLimit);
+
+ inputStream.read(&mNbEntries, 4);
+ if(mFlip)
+ flip(mNbEntries);
+
+ mEntries = PX_NEW(PxMetaDataEntry)[PxU32(mNbEntries)];
+ if(mSizeOfPtr==8)
+ {
+ for(int i=0;i<mNbEntries;i++)
+ {
+ MetaDataEntry64 tmp;
+ inputStream.read(&tmp, sizeof(MetaDataEntry64));
+ if (mFlip) // important to flip them first, else the cast below might destroy information
+ {
+ flip(tmp.mType);
+ flip(tmp.mName);
+ }
+ // We can safely cast to 32bits here since we transformed the pointers to offsets in the string table on export
+ mEntries[i].mType = reinterpret_cast<const char*>(size_t(tmp.mType));
+ mEntries[i].mName = reinterpret_cast<const char*>(size_t(tmp.mName));
+ mEntries[i].mOffset = tmp.mOffset;
+ mEntries[i].mSize = tmp.mSize;
+ mEntries[i].mCount = tmp.mCount;
+ mEntries[i].mOffsetSize = tmp.mOffsetSize;
+ mEntries[i].mFlags = tmp.mFlags;
+ mEntries[i].mAlignment = tmp.mAlignment;
+ }
+ }
+ else
+ {
+ assert(mSizeOfPtr==4);
+// inputStream.read(mEntries, mNbEntries*sizeof(PxMetaDataEntry));
+ for(int i=0;i<mNbEntries;i++)
+ {
+ MetaDataEntry32 tmp;
+ inputStream.read(&tmp, sizeof(MetaDataEntry32));
+ if (mFlip)
+ {
+ flip(tmp.mType);
+ flip(tmp.mName);
+ }
+ mEntries[i].mType = reinterpret_cast<const char*>(size_t(tmp.mType));
+ mEntries[i].mName = reinterpret_cast<const char*>(size_t(tmp.mName));
+ mEntries[i].mOffset = tmp.mOffset;
+ mEntries[i].mSize = tmp.mSize;
+ mEntries[i].mCount = tmp.mCount;
+ mEntries[i].mOffsetSize = tmp.mOffsetSize;
+ mEntries[i].mFlags = tmp.mFlags;
+ mEntries[i].mAlignment = tmp.mAlignment;
+ }
+ }
+
+ if(mFlip)
+ {
+ for(int i=0;i<mNbEntries;i++)
+ {
+ // mEntries[i].mType and mEntries[i].mName have been flipped already because they need special treatment
+ // on 64bit to 32bit platform conversions
+ flip(mEntries[i].mOffset);
+ flip(mEntries[i].mSize);
+ flip(mEntries[i].mCount);
+ flip(mEntries[i].mOffsetSize);
+ flip(mEntries[i].mFlags);
+ flip(mEntries[i].mAlignment);
+ }
+ }
+
+ int nbConcreteType;
+ inputStream.read(&nbConcreteType, 4);
+ if(mFlip)
+ flip(nbConcreteType);
+
+ for(int i=0; i<nbConcreteType; i++)
+ {
+ PxU16 concreteType;
+ PxU32 nameOffset;
+ inputStream.read(&concreteType, 2);
+ inputStream.read(&nameOffset, 4);
+ if(mFlip)
+ {
+ flip(concreteType);
+ flip(nameOffset);
+ }
+
+ mConcreteTypeTable.pushBack( Ps::Pair<PxConcreteType::Enum, PxU32>(PxConcreteType::Enum(concreteType), nameOffset) );
+ }
+
+ int tableSize;
+ inputStream.read(&tableSize, 4);
+ if(mFlip)
+ flip(tableSize);
+
+ mStringTable = reinterpret_cast<char*>(PX_ALLOC(sizeof(char)*tableSize, "MetaData StringTable"));
+ inputStream.read(mStringTable, PxU32(tableSize));
+ }
+
+ // Register atomic types
+ {
+ addNewClass("bool", 1, NULL, &ConvX::convert8);
+ addNewClass("char", 1, NULL, &ConvX::convert8);
+ addNewClass("short", 2, NULL, &ConvX::convert16);
+ addNewClass("int", 4, NULL, &ConvX::convert32);
+ addNewClass("PxU64", 8, NULL, &ConvX::convert64);
+ addNewClass("float", 4, NULL, &ConvX::convertFloat);
+
+ addNewClass("paddingByte", 1, NULL, &ConvX::convertPad8);
+ }
+
+ {
+ MetaClass* currentClass = NULL;
+ for(int i=0;i<mNbEntries;i++)
+ {
+ mEntries[i].mType = offsetToText(mEntries[i].mType);
+ mEntries[i].mName = offsetToText(mEntries[i].mName);
+
+ if(mEntries[i].mFlags & PxMetaDataFlag::eTYPEDEF)
+ {
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, "Found typedef: %s => %s\n", mEntries[i].mName, mEntries[i].mType);
+ MetaClass* mc = getMetaClass(mEntries[i].mName);
+ if(mc)
+ addNewClass(mEntries[i].mType, mc->mSize, mc, mc->mCallback);
+ else
+ mConvX.displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: Invalid typedef - Missing metadata for: %s, please check the source metadata.\n"
+ , mEntries[i].mName);
+ }
+ else if(mEntries[i].mFlags & PxMetaDataFlag::eCLASS)
+ {
+ if(!mEntries[i].mName)
+ {
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, "Found class: %s\n", mEntries[i].mType);
+ currentClass = addNewClass(mEntries[i].mType, mEntries[i].mSize);
+
+ if(mEntries[i].mFlags & PxMetaDataFlag::eVIRTUAL)
+ {
+ PxMetaDataEntry vtable;
+ vtable.mType = gVTablePtr;
+ vtable.mName = gVTablePtr;
+ vtable.mOffset = 0;
+ vtable.mSize = mSizeOfPtr;
+ vtable.mCount = 1;
+ vtable.mFlags = PxMetaDataFlag::ePTR;
+ currentClass->mFields.pushBack(vtable);
+ }
+ }
+ else
+ {
+ assert(currentClass);
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO, " - inherits from: %s\n", mEntries[i].mName);
+ currentClass->mBaseClasses.pushBack(mEntries[i]);
+ }
+ }
+ else
+ {
+ const int isUnion = mEntries[i].mFlags & PxMetaDataFlag::eUNION;
+
+ if(isUnion && !mEntries[i].mSize)
+ {
+ mConvX.registerUnionType(mEntries[i].mType, mEntries[i].mName, mEntries[i].mOffset);
+ }
+ else
+ {
+ if(isUnion)
+ {
+ mConvX.registerUnion(mEntries[i].mType);
+ }
+
+ const int isPadding = mEntries[i].mFlags & PxMetaDataFlag::ePADDING;
+
+ assert(currentClass);
+#ifdef REMOVE_EXPLICIT_PADDING
+ if(!isPadding)
+#endif
+ currentClass->mFields.pushBack(mEntries[i]);
+
+ if(isPadding)
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO,
+ " - contains padding: %s - %s\n", mEntries[i].mType, mEntries[i].mName);
+ else if(mEntries[i].mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO,
+ " - contains extra data: %s%s\n", mEntries[i].mType, mEntries[i].mFlags & PxMetaDataFlag::ePTR ? "*" : "");
+ else
+ mConvX.displayMessage(PxErrorCode::eDEBUG_INFO,
+ " - contains field: %s%s\n", mEntries[i].mType, mEntries[i].mFlags & PxMetaDataFlag::ePTR ? "*" : "");
+
+ }
+ }
+ }
+ }
+
+ // Sort classes by depth
+ struct Local
+ {
+ static bool _computeDepth(const MetaData& md, MetaClass* current, int currentDepth, int& maxDepth)
+ {
+ if(currentDepth>maxDepth)
+ maxDepth = currentDepth;
+
+ PxU32 nbBases = current->mBaseClasses.size();
+ for(PxU32 i=0;i<nbBases;i++)
+ {
+ const PxMetaDataEntry& baseClassEntry = current->mBaseClasses[i];
+ MetaClass* baseClass = md.getMetaClass(baseClassEntry.mName);
+ if(!baseClass)
+ {
+ md.mConvX.displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: Can't find class %s metadata, please check the source metadata.\n", baseClassEntry.mName);
+ return false;
+ }
+ if (!_computeDepth(md, baseClass, currentDepth+1, maxDepth))
+ return false;
+ }
+ return true;
+ }
+
+ static int compareClasses(const void* c0, const void* c1)
+ {
+ MetaClass** mc0 = reinterpret_cast<MetaClass**>(const_cast<void*>(c0));
+ MetaClass** mc1 = reinterpret_cast<MetaClass**>(const_cast<void*>(c1));
+// return (*mc0)->mSize - (*mc1)->mSize;
+ return (*mc0)->mDepth - (*mc1)->mDepth;
+ }
+
+ static int compareEntries(const void* c0, const void* c1)
+ {
+ PxMetaDataEntry* mc0 = reinterpret_cast<PxMetaDataEntry*>(const_cast<void*>(c0));
+ PxMetaDataEntry* mc1 = reinterpret_cast<PxMetaDataEntry*>(const_cast<void*>(c1));
+ //mOffset is used to access control information for extra data, and not for offsets of the data itself.
+ assert(!(mc0->mFlags & PxMetaDataFlag::eEXTRA_DATA));
+ assert(!(mc1->mFlags & PxMetaDataFlag::eEXTRA_DATA));
+ return mc0->mOffset - mc1->mOffset;
+ }
+ };
+ {
+ // Compute depths
+ const PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 i=0;i<nbMetaClasses;i++)
+ {
+ MetaClass* current = mMetaClasses[i];
+ int maxDepth = 0;
+ if(!Local::_computeDepth(*this, current, 0, maxDepth))
+ return false;
+ current->mDepth = maxDepth;
+ }
+
+ // Sort by depth
+ MetaClass** metaClasses = &mMetaClasses[0];
+ qsort(metaClasses, size_t(nbMetaClasses), sizeof(MetaClass*), Local::compareClasses);
+ }
+
+ // Replicate fields from base classes
+ {
+ PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 k=0;k<nbMetaClasses;k++)
+ {
+ MetaClass* current = mMetaClasses[k];
+ PxU32 nbBases = current->mBaseClasses.size();
+
+ // merge entries of base classes and current class in the right order
+ // this is needed for extra data ordering, which is not covered by the mOffset sort
+ // in the next stage below
+ PsArray<PxMetaDataEntry> mergedEntries;
+
+ for(PxU32 i=0;i<nbBases;i++)
+ {
+ const PxMetaDataEntry& baseClassEntry = current->mBaseClasses[i];
+ MetaClass* baseClass = getMetaClass(baseClassEntry.mName);
+ assert(baseClass);
+ assert(baseClass->mBaseClasses.size()==0 || baseClass->mProcessed);
+
+ PxU32 nbBaseFields = baseClass->mFields.size();
+ for(PxU32 j=0;j<nbBaseFields;j++)
+ {
+ PxMetaDataEntry f = baseClass->mFields[j];
+ // Don't merge primary v-tables to avoid redundant v-table entries.
+ // It means the base v-table won't be inherited & needs to be explicitly defined in the metadata. Seems reasonable.
+ // Could be done better though.
+
+ if(f.mType==gVTablePtr && !f.mOffset && !baseClassEntry.mOffset)
+ continue;
+
+ f.mOffset += baseClassEntry.mOffset;
+ mergedEntries.pushBack(f);
+ }
+ current->mProcessed = true;
+ }
+
+ //append current fields to base class fields
+ for (PxU32 i = 0; i < current->mFields.size(); i++)
+ {
+ mergedEntries.pushBack(current->mFields[i]);
+ }
+ current->mFields.clear();
+ current->mFields.assign(mergedEntries.begin(), mergedEntries.end());
+ }
+ }
+
+ // Check classes
+ {
+ PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 i=0;i<nbMetaClasses;i++)
+ {
+ MetaClass* current = mMetaClasses[i];
+ if(!current->check(*this))
+ return false;
+ }
+ }
+
+ // Sort meta-data by offset
+ {
+ PxU32 nbMetaClasses = mMetaClasses.size();
+ for(PxU32 i=0;i<nbMetaClasses;i++)
+ {
+ MetaClass* current = mMetaClasses[i];
+ PxU32 nbFields = current->mFields.size();
+ if(nbFields<2)
+ continue;
+ PxMetaDataEntry* entries = &current->mFields[0];
+
+ PxMetaDataEntry* newEntries = PX_NEW(PxMetaDataEntry)[nbFields];
+ PxU32 nb = 0;
+ for(PxU32 j=0;j<nbFields;j++)
+ if(!(entries[j].mFlags & PxMetaDataFlag::eEXTRA_DATA))
+ newEntries[nb++] = entries[j];
+ PxU32 nbToSort = nb;
+ for(PxU32 j=0;j<nbFields;j++)
+ if(entries[j].mFlags & PxMetaDataFlag::eEXTRA_DATA)
+ newEntries[nb++] = entries[j];
+ assert(nb==nbFields);
+ memcpy(entries, newEntries, nb*sizeof(PxMetaDataEntry));
+ PX_DELETE_ARRAY(newEntries);
+ qsort(entries, size_t(nbToSort), sizeof(PxMetaDataEntry), Local::compareEntries);
+ }
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ConvX::releaseMetaData()
+{
+ DELETESINGLE(mMetaData_Dst);
+ DELETESINGLE(mMetaData_Src);
+}
+
+const MetaData* ConvX::loadMetaData(PxInputStream& inputStream, MetaDataType type)
+{
+ if (type != META_DATA_SRC && type != META_DATA_DST)
+ {
+ displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: Wrong meta data type, please check the source metadata.\n");
+ return NULL;
+ }
+
+ PX_ASSERT(type == META_DATA_SRC || type == META_DATA_DST);
+
+ MetaData*& metaDataPtr = (type == META_DATA_SRC) ? mMetaData_Src : mMetaData_Dst;
+ metaDataPtr = PX_NEW(MetaData)(*this);
+ if(!(metaDataPtr)->load(inputStream, type))
+ DELETESINGLE(metaDataPtr);
+ return metaDataPtr;
+}
+
+const MetaData* ConvX::getBinaryMetaData(MetaDataType type)
+{
+ if(type==META_DATA_SRC)
+ return mMetaData_Src;
+ if(type==META_DATA_DST)
+ return mMetaData_Dst;
+ PX_ASSERT(0);
+ return NULL;
+}
+
+int ConvX::getNbMetaClasses(MetaDataType type)
+{
+ if(type==META_DATA_SRC)
+ return mMetaData_Src->getNbMetaClasses();
+ if(type==META_DATA_DST)
+ return mMetaData_Dst->getNbMetaClasses();
+ PX_ASSERT(0);
+ return 0;
+}
+
+MetaClass* ConvX::getMetaClass(unsigned int i, MetaDataType type) const
+{
+ if(type==META_DATA_SRC)
+ return mMetaData_Src->getMetaClass(i);
+ if(type==META_DATA_DST)
+ return mMetaData_Dst->getMetaClass(i);
+ PX_ASSERT(0);
+ return NULL;
+}
+
+MetaClass* ConvX::getMetaClass(const char* name, MetaDataType type) const
+{
+ if(type==META_DATA_SRC)
+ return mMetaData_Src->getMetaClass(name);
+ if(type==META_DATA_DST)
+ return mMetaData_Dst->getMetaClass(name);
+ PX_ASSERT(0);
+ return NULL;
+}
+
+MetaClass* ConvX::getMetaClass(PxConcreteType::Enum concreteType, MetaDataType type)
+{
+ MetaClass* metaClass = NULL;
+ if(type==META_DATA_SRC)
+ metaClass = mMetaData_Src->getMetaClass(concreteType);
+ if(type==META_DATA_DST)
+ metaClass = mMetaData_Dst->getMetaClass(concreteType);
+
+ if(!metaClass)
+ {
+ displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: Missing concreteType %d metadata! serialized a class without dumping metadata. Please check the metadata.",
+ concreteType);
+ return NULL;
+ }
+
+ return metaClass;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Peek & poke, yes sir.
+PxU64 physx::Sn::peek(int size, const char* buffer, int flags)
+{
+ const int maskMSB = flags & PxMetaDataFlag::eCOUNT_MASK_MSB;
+ const int skipIfOne = flags & PxMetaDataFlag::eCOUNT_SKIP_IF_ONE;
+ switch(size)
+ {
+ case 1:
+ {
+ unsigned char value = *(reinterpret_cast<const unsigned char*>(buffer));
+ if(maskMSB)
+ value &= 0x7f;
+ if(skipIfOne && value==1)
+ return 0;
+ return PxU64(value);
+ }
+ case 2:
+ {
+ unsigned short value = *(reinterpret_cast<const unsigned short*>(buffer));
+ if(maskMSB)
+ value &= 0x7fff;
+ if(skipIfOne && value==1)
+ return 0;
+ return PxU64(value);
+ }
+ case 4:
+ {
+ unsigned int value = *(reinterpret_cast<const unsigned int*>(buffer));
+ if(maskMSB)
+ value &= 0x7fffffff;
+ if(skipIfOne && value==1)
+ return 0;
+ return PxU64(value);
+ }
+ case 8:
+ {
+ PxU64 value = *(reinterpret_cast<const PxU64*>(buffer));
+ if(maskMSB)
+ value &= (PxU64(-1))>>1;
+ if(skipIfOne && value==1)
+ return 0;
+ return value;
+ }
+ };
+ PX_ASSERT(0);
+ return PxU64(-1);
+}
+
+
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.h
new file mode 100644
index 00000000..29597b62
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_MetaData.h
@@ -0,0 +1,186 @@
+// 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.
+
+#ifndef PX_CONVX_METADATA_H
+#define PX_CONVX_METADATA_H
+
+#include "SnConvX_Output.h"
+#include "PxMetaDataFlags.h"
+
+namespace physx { namespace Sn {
+
+#if PX_VC
+#pragma warning (push)
+#pragma warning (disable : 4371) //layout of class may have changed from a previous version of the compiler due to better packing of member
+#endif
+
+
+ // PT: beware, must match corresponding structure in PxMetaData.h
+ struct PxMetaDataEntry : public shdfnd::UserAllocated
+ {
+ PxMetaDataEntry()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+ bool isVTablePtr() const;
+
+ const char* mType; //!< Field type (bool, byte, quaternion, etc)
+ const char* mName; //!< Field name (appears exactly as in the source file)
+ int mOffset; //!< Offset from the start of the class (ie from "this", field is located at "this"+Offset)
+ int mSize; //!< sizeof(Type)
+ int mCount; //!< Number of items of type Type (0 for dynamic sizes)
+ int mOffsetSize; //!< Offset of dynamic size param, for dynamic arrays
+ int mFlags; //!< Field parameters
+ int mAlignment; //!< Explicit alignment added for DE1340
+ };
+
+ struct MetaDataEntry32
+ {
+ PxI32 mType; //!< Field type (bool, byte, quaternion, etc)
+ PxI32 mName; //!< Field name (appears exactly as in the source file)
+ int mOffset; //!< Offset from the start of the class (ie from "this", field is located at "this"+Offset)
+ int mSize; //!< sizeof(Type)
+ int mCount; //!< Number of items of type Type (0 for dynamic sizes)
+ int mOffsetSize; //!< Offset of dynamic size param, for dynamic arrays
+ int mFlags; //!< Field parameters
+ int mAlignment; //!< Explicit alignment added for DE1340
+ };
+
+ struct MetaDataEntry64
+ {
+ PxI64 mType; //!< Field type (bool, byte, quaternion, etc)
+ PxI64 mName; //!< Field name (appears exactly as in the source file)
+ int mOffset; //!< Offset from the start of the class (ie from "this", field is located at "this"+Offset)
+ int mSize; //!< sizeof(Type)
+ int mCount; //!< Number of items of type Type (0 for dynamic sizes)
+ int mOffsetSize; //!< Offset of dynamic size param, for dynamic arrays
+ int mFlags; //!< Field parameters
+ int mAlignment; //!< Explicit alignment added for DE1340
+ };
+
+ struct ExtraDataEntry
+ {
+ PxMetaDataEntry entry;
+ int offset;
+ };
+
+ struct ExtraDataEntry2 : ExtraDataEntry
+ {
+ ConvertCallback cb;
+ };
+
+ class MetaData;
+
+ struct MetaClass : public shdfnd::UserAllocated
+ {
+ bool getFieldByType(const char* type, PxMetaDataEntry& entry) const;
+ bool getFieldByName(const char* name, PxMetaDataEntry& entry) const;
+ bool check(const MetaData& owner);
+
+ ConvertCallback mCallback;
+ MetaClass* mMaster;
+ const char* mClassName;
+ int mSize;
+ int mDepth;
+ PsArray<PxMetaDataEntry> mBaseClasses;
+ PsArray<PxMetaDataEntry> mFields;
+ bool mProcessed;
+
+// int mNbEntries;
+// ExtraDataEntry2 mEntries[256];
+
+ private:
+ void checkAndCompleteClass(const MetaData& owner, int& startOffset, int& nbBytes);
+ };
+
+ enum MetaDataType
+ {
+ META_DATA_NONE,
+ META_DATA_SRC,
+ META_DATA_DST
+ };
+
+ class ConvX;
+ class MetaData : public shdfnd::UserAllocated
+ {
+ public:
+ MetaData(Sn::ConvX&);
+ ~MetaData();
+
+ bool load(PxInputStream& inputStream, MetaDataType type);
+
+ inline_ MetaDataType getType() const { return mType; }
+ inline_ int getVersion() const { return mVersion; }
+ inline_ int getBuildNumber() const { return mBuildNumber; }
+ inline_ int getPtrSize() const { return mSizeOfPtr; }
+ inline_ int getPlatformTag() const { return mPlatformTag; }
+ inline_ int getGaussMapLimit() const { return mGaussMapLimit; }
+ inline_ int getNbMetaClasses() const { return int(mMetaClasses.size()); }
+ inline_ MetaClass* getMetaClass(unsigned int i) const { return mMetaClasses[i]; }
+ inline_ bool getFlip() const { return mFlip; }
+
+ MetaClass* getMetaClass(const char* name) const;
+ MetaClass* getMetaClass(PxConcreteType::Enum concreteType) const;
+ MetaClass* addNewClass(const char* name, int size, MetaClass* master=NULL, ConvertCallback callback=NULL);
+ private:
+ MetaData& operator=(const MetaData&);
+ Sn::ConvX& mConvX;
+ MetaDataType mType;
+ int mNbEntries;
+ PxMetaDataEntry* mEntries;
+ char* mStringTable;
+ PsArray<MetaClass*> mMetaClasses;
+ int mVersion;
+ int mBinaryVersion;
+ int mBuildNumber;
+ int mSizeOfPtr;
+ int mPlatformTag;
+ int mGaussMapLimit;
+ bool mFlip;
+
+ PsArray< Ps::Pair<PxConcreteType::Enum, PxU32> > mConcreteTypeTable;
+
+ inline_ const char* offsetToText(const char* text) const
+ {
+ const size_t offset = size_t(text);
+ const PxU32 offset32 = PxU32(offset);
+// if(offset==-1)
+ if(offset32==0xffffffff)
+ return NULL;
+ return mStringTable + offset32;
+ }
+ friend struct MetaClass;
+ };
+
+ PxU64 peek(int size, const char* buffer, int flags=0);
+
+#if PX_VC
+#pragma warning (pop)
+#endif
+} }
+
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.cpp
new file mode 100644
index 00000000..9eaa601c
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.cpp
@@ -0,0 +1,451 @@
+// 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.
+
+#include "foundation/PxIO.h"
+#include "foundation/PxErrorCallback.h"
+#include "SnConvX.h"
+
+#if PX_VC
+#pragma warning(disable:4389) // signed/unsigned mismatch
+#endif
+
+using namespace physx;
+
+void Sn::ConvX::setNullPtr(bool flag)
+{
+ mNullPtr = flag;
+}
+
+void Sn::ConvX::setNoOutput(bool flag)
+{
+ mNoOutput = flag;
+}
+
+bool Sn::ConvX::initOutput(PxOutputStream& targetStream)
+{
+ mOutStream = &targetStream;
+
+ mOutputSize = 0;
+ mNullPtr = false;
+ mNoOutput = false;
+
+ const MetaData* srcMetaData = getBinaryMetaData(META_DATA_SRC);
+ PX_ASSERT(srcMetaData);
+ const MetaData* dstMetaData = getBinaryMetaData(META_DATA_DST);
+ PX_ASSERT(dstMetaData);
+
+ mSrcPtrSize = srcMetaData->getPtrSize();
+ mDstPtrSize = dstMetaData->getPtrSize();
+
+ PX_ASSERT(!srcMetaData->getFlip());
+ mMustFlip = dstMetaData->getFlip();
+ return true;
+}
+
+void Sn::ConvX::closeOutput()
+{
+ mOutStream = NULL;
+}
+
+int Sn::ConvX::getCurrentOutputSize()
+{
+ return mOutputSize;
+}
+
+void Sn::ConvX::output(short value)
+{
+ if(mNoOutput)
+ return;
+
+ if(mMustFlip)
+ flip(value);
+
+ PX_ASSERT(mOutStream);
+ const size_t size = mOutStream->write(&value, 2);
+ PX_ASSERT(size==2);
+ mOutputSize += int(size);
+}
+
+void Sn::ConvX::output(int value)
+{
+ if(mNoOutput)
+ return;
+
+ if(mMustFlip)
+ flip(value);
+
+ PX_ASSERT(mOutStream);
+ const size_t size = mOutStream->write(&value, 4);
+ PX_ASSERT(size==4);
+ mOutputSize += int(size);
+}
+
+//ntohll is a macro on apple yosemite
+static PxU64 ntohll_internal(const PxU64 value)
+{
+ union
+ {
+ PxU64 ull;
+ PxU8 c[8];
+ } x;
+
+ x.ull = value;
+
+ PxU8 c = 0;
+ c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
+ c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
+ c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
+ c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
+
+ return x.ull;
+}
+
+void Sn::ConvX::output(PxU64 value)
+{
+ if(mNoOutput)
+ return;
+
+ if(mMustFlip)
+// flip(value);
+ value = ntohll_internal(value);
+
+ PX_ASSERT(mOutStream);
+ const size_t size = mOutStream->write(&value, 8);
+ PX_ASSERT(size==8);
+ mOutputSize += int(size);
+}
+
+void Sn::ConvX::output(const char* buffer, int nbBytes)
+{
+ if(mNoOutput)
+ return;
+
+ if(!nbBytes)
+ return;
+
+ PX_ASSERT(mOutStream);
+ const PxU32 size = mOutStream->write(buffer, PxU32(nbBytes));
+ PX_ASSERT(size== PxU32(nbBytes));
+ mOutputSize += int(size);
+}
+
+void Sn::ConvX::convert8(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==1*entry.mCount);
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ const PxU32 size = mOutStream->write(src, PxU32(entry.mSize));
+ PX_ASSERT(size== PxU32(entry.mSize));
+ mOutputSize += int(size);
+}
+
+// This is called to convert auto-generated "padding bytes" (or so we think).
+// We use a special converter to check the input bytes and issue warnings when it doesn't look like padding
+void Sn::ConvX::convertPad8(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ (void)src;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize);
+ PX_ASSERT(entry.mSize==1*entry.mCount);
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ // PT: we don't output the source data on purpose, to catch missing meta-data
+ // sschirm: changed that to 0xcd, so we can mark the output as "having marked pads"
+ const unsigned char b = 0xcd;
+ for(int i=0;i<entry.mSize;i++)
+ {
+ const size_t size = mOutStream->write(&b, 1);
+ (void)size;
+ }
+ mOutputSize += entry.mSize;
+}
+
+void Sn::ConvX::convert16(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==int(sizeof(short)*entry.mCount));
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ const short* data = reinterpret_cast<const short*>(src);
+ for(int i=0;i<entry.mCount;i++)
+ {
+ short value = *data++;
+ if(mMustFlip)
+ flip(value);
+
+ const size_t size = mOutStream->write(&value, sizeof(short));
+ PX_ASSERT(size==sizeof(short));
+ mOutputSize += int(size);
+ }
+}
+
+void Sn::ConvX::convert32(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==int(sizeof(int)*entry.mCount));
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ const int* data = reinterpret_cast<const int*>(src);
+ for(int i=0;i<entry.mCount;i++)
+ {
+ int value = *data++;
+ if(mMustFlip)
+ flip(value);
+
+ const size_t size = mOutStream->write(&value, sizeof(int));
+ PX_ASSERT(size==sizeof(int));
+ mOutputSize += int(size);
+ }
+}
+
+void Sn::ConvX::convert64(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==int(sizeof(PxU64)*entry.mCount));
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ const PxU64* data = reinterpret_cast<const PxU64*>(src);
+ for(int i=0;i<entry.mCount;i++)
+ {
+ PxU64 value = *data++;
+ if(mMustFlip)
+ value = ntohll_internal(value);
+
+ const size_t size = mOutStream->write(&value, sizeof(PxU64));
+ PX_ASSERT(size==sizeof(PxU64));
+ mOutputSize += int(size);
+ }
+}
+
+void Sn::ConvX::convertFloat(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==int(sizeof(float)*entry.mCount));
+ PX_ASSERT(mOutStream);
+ PX_ASSERT(entry.mSize==dstEntry.mSize);
+
+ const float* data = reinterpret_cast<const float*>(src);
+ for(int i=0;i<entry.mCount;i++)
+ {
+ float value = *data++;
+ if(mMustFlip)
+ flip(value);
+
+ const size_t size = mOutStream->write(&value, sizeof(float));
+ PX_ASSERT(size==sizeof(float));
+ mOutputSize += int(size);
+ }
+}
+
+void Sn::ConvX::convertPtr(const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry)
+{
+ (void)dstEntry;
+ if(mNoOutput)
+ return;
+
+ PX_ASSERT(entry.mSize==mSrcPtrSize*entry.mCount);
+ PX_ASSERT(mOutStream);
+
+ char buffer[16];
+ for(int i=0;i<entry.mCount;i++)
+ {
+ PxU64 testValue=0;
+ // Src pointer can be 4 or 8 bytes so we can't use "void*" here
+ if(mSrcPtrSize==4)
+ {
+ PX_ASSERT(sizeof(PxU32)==4);
+ const PxU32* data = reinterpret_cast<const PxU32*>(src);
+ PxU32 value = *data++;
+ src = reinterpret_cast<const char*>(data);
+
+ if(mActiveRemap)
+ {
+ PxU32 ref;
+ if(mActiveRemap->getObjectRef(value, ref))
+ {
+ value = ref;
+ }
+ else if(value)
+ {
+ // value = 0;
+ //We use the pointer of mName for its length
+ // PT: on serialization mName is transformed to an index by the name manager, so we should not modify its value.
+ if(!entry.mName || strcmp(entry.mName, "mName"))
+ value=0x12345678;
+ }
+ }
+ else
+ {
+ //we should only get here during convertReferenceTables to build up the pointer map
+ PxU32 ref;
+ if (mRemap.getObjectRef(value, ref))
+ {
+ value = ref;
+ }
+ else if(value)
+ {
+ const PxU32 remappedRef = 0x80000000 | (mPointerRemapCounter++ +1);
+ mRemap.setObjectRef(value, remappedRef);
+ value = remappedRef;
+ }
+ }
+
+ if(mMustFlip)
+ flip(value);
+
+ if(mNullPtr)
+ value = 0;
+
+ *reinterpret_cast<PxU32*>(buffer) = value;
+ }
+ else
+ {
+ PX_ASSERT(mSrcPtrSize==8);
+ PX_ASSERT(sizeof(PxU64)==8);
+ const PxU64* data = reinterpret_cast<const PxU64*>(src);
+ PxU64 value = *data++;
+ src = reinterpret_cast<const char*>(data);
+
+ if(mActiveRemap)
+ {
+ PxU32 ref;
+ if(mActiveRemap->getObjectRef(value, ref))
+ {
+ value = ref;
+ }
+ else if(value)
+ {
+ // value = 0;
+ //We use the pointer of mName for its length
+ // PT: on serialization mName is transformed to an index by the name manager, so we should not modify its value.
+ if(!entry.mName || strcmp(entry.mName, "mName"))
+ value=0x12345678;
+ }
+ }
+ else
+ {
+ //we should only get here during convertReferenceTables to build up the pointer map
+ PxU32 ref;
+ if (mRemap.getObjectRef(value, ref))
+ {
+ value = ref;
+ }
+ else if(value)
+ {
+ const PxU32 remappedRef = 0x80000000 | (mPointerRemapCounter++ +1);
+ mRemap.setObjectRef(value, remappedRef);
+ value = remappedRef;
+ }
+ }
+
+// PX_ASSERT(!mMustFlip);
+// if(mMustFlip)
+// flip(value);
+
+ if(mNullPtr)
+ value = 0;
+
+ testValue = value;
+
+ *reinterpret_cast<PxU64*>(buffer) = value;
+ }
+
+ if(mSrcPtrSize==mDstPtrSize)
+ {
+ const size_t size = mOutStream->write(buffer, PxU32(mSrcPtrSize));
+ PX_ASSERT(size==PxU32(mSrcPtrSize));
+ mOutputSize += int(size);
+ }
+ else
+ {
+ if(mDstPtrSize>mSrcPtrSize)
+ {
+ // 32bit to 64bit
+ PX_ASSERT(mDstPtrSize==8);
+ PX_ASSERT(mSrcPtrSize==4);
+
+ // We need to output the lower 32bits first for PC. Might be different on a 64bit console....
+
+ // Output src ptr for the lower 32bits
+ const size_t size = mOutStream->write(buffer, PxU32(mSrcPtrSize));
+ PX_ASSERT(size==PxU32(mSrcPtrSize));
+ mOutputSize += int(size);
+
+ // Output zeros for the higher 32bits
+ const int zero = 0;
+ const size_t size0 = mOutStream->write(&zero, 4);
+ PX_ASSERT(size0==4);
+ mOutputSize += int(size0);
+ }
+ else
+ {
+ // 64bit to 32bit
+ PX_ASSERT(mSrcPtrSize==8);
+ PX_ASSERT(mDstPtrSize==4);
+
+ // Not sure how we can safely convert 64bit ptrs to 32bit... just drop the high 32 bits?!?
+
+ PxU32 ptr32 = *reinterpret_cast<PxU32*>(buffer);
+ (void)ptr32;
+ PxU32 ptr32b = PxU32(testValue);
+ (void)ptr32b;
+
+ if(mMustFlip)
+ flip(ptr32b);
+
+ // Output src ptr for the lower 32bits
+ const size_t size = mOutStream->write(&ptr32b, 4);
+ PX_ASSERT(size==4);
+ mOutputSize += int(size);
+ }
+ }
+ }
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.h
new file mode 100644
index 00000000..6eaf7b99
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Output.h
@@ -0,0 +1,112 @@
+// 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.
+
+#ifndef PX_CONVX_OUTPUT_H
+#define PX_CONVX_OUTPUT_H
+
+#include "foundation/PxSimpleTypes.h"
+
+namespace physx { namespace Sn {
+
+ struct PxMetaDataEntry;
+ class ConvX;
+
+ typedef void (Sn::ConvX::*ConvertCallback) (const char* src, const PxMetaDataEntry& entry, const PxMetaDataEntry& dstEntry);
+
+ inline_ void flip(PxI16& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+ PxI8 temp = b[0];
+ b[0] = b[1];
+ b[1] = temp;
+ }
+
+ inline_ void flip(PxU16& v)
+ {
+ flip(reinterpret_cast<PxI16&>(v));
+ }
+
+ inline_ void flip32(PxI8* b)
+ {
+ PxI8 temp = b[0];
+ b[0] = b[3];
+ b[3] = temp;
+ temp = b[1];
+ b[1] = b[2];
+ b[2] = temp;
+ }
+
+ inline_ void flip(PxI32& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+ flip32(b);
+ }
+
+ inline_ void flip(PxU32& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+ flip32(b);
+ }
+
+ inline_ void flip(PxI64& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+
+ PxI8 temp = b[0];
+ b[0] = b[7];
+ b[7] = temp;
+ temp = b[1];
+ b[1] = b[6];
+ b[6] = temp;
+ temp = b[2];
+ b[2] = b[5];
+ b[5] = temp;
+ temp = b[3];
+ b[3] = b[4];
+ b[4] = temp;
+ }
+
+ inline_ void flip(PxF32& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+ flip32(b);
+ }
+
+ inline_ void flip(void*& v)
+ {
+ PxI8* b = reinterpret_cast<PxI8*>(&v);
+ flip32(b);
+ }
+
+ inline_ void flip(const PxI8*& v)
+ {
+ PxI8* b = const_cast<PxI8*>(v);
+ flip32(b);
+ }
+} }
+
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.cpp
new file mode 100644
index 00000000..ddff8df1
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.cpp
@@ -0,0 +1,90 @@
+// 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.
+
+#include "SnConvX.h"
+#include <assert.h>
+
+using namespace physx;
+
+void Sn::ConvX::resetUnions()
+{
+ mUnions.clear();
+}
+
+bool Sn::ConvX::registerUnion(const char* name)
+{
+ displayMessage(PxErrorCode::eDEBUG_INFO, "Registering union: %s\n", name);
+
+ Sn::Union u;
+ u.mName = name;
+
+ mUnions.pushBack(u);
+ return true;
+}
+
+bool Sn::ConvX::registerUnionType(const char* unionName, const char* typeName, int typeValue)
+{
+ const PxU32 nb = mUnions.size();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ if(strcmp(mUnions[i].mName, unionName)==0)
+ {
+ UnionType t;
+ t.mTypeName = typeName;
+ t.mTypeValue = typeValue;
+ mUnions[i].mTypes.pushBack(t);
+ displayMessage(PxErrorCode::eDEBUG_INFO, "Registering union type: %s | %s | %d\n", unionName, typeName, typeValue);
+ return true;
+ }
+ }
+
+ displayMessage(PxErrorCode::eINTERNAL_ERROR, "PxBinaryConverter: union not found: %s, please check the source metadata.\n", unionName);
+ return false;
+}
+
+const char* Sn::ConvX::getTypeName(const char* unionName, int typeValue)
+{
+ const PxU32 nb = mUnions.size();
+ for(PxU32 i=0;i<nb;i++)
+ {
+ if(strcmp(mUnions[i].mName, unionName)==0)
+ {
+ const PxU32 nbTypes = mUnions[i].mTypes.size();
+ for(PxU32 j=0;j<nbTypes;j++)
+ {
+ const UnionType& t = mUnions[i].mTypes[j];
+ if(t.mTypeValue==typeValue)
+ return t.mTypeName;
+ }
+ break;
+ }
+ }
+ displayMessage(PxErrorCode::eINTERNAL_ERROR,
+ "PxBinaryConverter: union type not found: %s, type %d, please check the source metadata.\n", unionName, typeValue);
+ assert(0);
+ return NULL;
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.h
new file mode 100644
index 00000000..6c94a12c
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnConvX_Union.h
@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef PX_UNION_H
+#define PX_UNION_H
+
+namespace physx { namespace Sn {
+ struct UnionType
+ {
+ const char* mTypeName;
+ int mTypeValue;
+ };
+
+ struct Union
+ {
+ const char* mName;
+ PsArray<UnionType> mTypes;
+ };
+} }
+
+#endif
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.cpp
new file mode 100644
index 00000000..ef46d552
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.cpp
@@ -0,0 +1,94 @@
+// 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 "PxBase.h"
+#include "SnSerializationContext.h"
+#include "PsFoundation.h"
+
+using namespace physx;
+using namespace Sn;
+
+PxBase* DeserializationContext::resolveReference(PxU32 kind, size_t reference) const
+{
+ const InternalRefMap::Entry* entry0 = mInternalReferencesMap.find(InternalRefKey(reference, kind));
+ PX_ASSERT(entry0);
+ SerialObjectIndex objIndex = entry0->second;
+ bool isExternal;
+ PxU32 index = objIndex.getIndex(isExternal);
+ PxBase* base = NULL;
+ if (isExternal)
+ {
+ const ImportReference& entry = mImportReferences[index];
+ base = mExternalRefs->find(entry.id);
+ }
+ else
+ {
+ const ManifestEntry& entry = mManifestTable[index];
+ base = reinterpret_cast<PxBase*>(mObjectDataAddress + entry.offset);
+ }
+ PX_ASSERT(base);
+ return base;
+}
+
+void SerializationContext::registerReference(PxBase& serializable, PxU32 kind, size_t reference)
+{
+#if PX_CHECKED
+ if ((kind & PX_SERIAL_REF_KIND_PTR_TYPE_BIT) == 0 && reference > 0xffffffff)
+ {
+ Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxSerializationContext::registerReference: only 32 bit indices supported.");
+ return;
+ }
+#endif
+
+ bool isExternal = mExternalRefs && mExternalRefs->contains(serializable);
+ PxU32 index;
+ if (isExternal)
+ {
+ PxSerialObjectId id = mExternalRefs->getId(serializable);
+ PX_ASSERT(id != PX_SERIAL_OBJECT_ID_INVALID);
+ if (const Ps::HashMap<PxSerialObjectId, PxU32>::Entry* entry = mImportReferencesMap.find(id))
+ {
+ index = entry->second;
+ }
+ else
+ {
+ index = mImportReferences.size();
+ mImportReferencesMap.insert(id, index);
+ mImportReferences.pushBack(ImportReference(id, serializable.getConcreteType()));
+ }
+ }
+ else
+ {
+ PX_ASSERT(mCollection.contains(serializable));
+ index = mObjToCollectionIndexMap[&serializable];
+ }
+
+ InternalRefMap& targetMap = (kind & PX_SERIAL_REF_KIND_PTR_TYPE_BIT) ? mInternalReferencesPtrMap : mInternalReferencesIdxMap;
+ targetMap[InternalRefKey(reference, kind)] = SerialObjectIndex(index, isExternal);
+}
diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.h
new file mode 100644
index 00000000..6bfa05e1
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnSerializationContext.h
@@ -0,0 +1,303 @@
+// 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.
+
+
+#ifndef PX_PHYSICS_SN_SERIALIZATION_CONTEXT
+#define PX_PHYSICS_SN_SERIALIZATION_CONTEXT
+
+#include "foundation/PxAssert.h"
+#include "foundation/PxMemory.h"
+#include "CmPhysXCommon.h"
+#include "PsHash.h"
+#include "PsUserAllocated.h"
+#include "PxSerialFramework.h"
+#include "CmCollection.h"
+#include "CmUtils.h"
+#include "PxDefaultStreams.h"
+#include "PsFoundation.h"
+#include "SnConvX_Align.h"
+
+namespace physx
+{
+ namespace Sn
+ {
+
+ struct ManifestEntry
+ {
+ //= ATTENTION! =====================================================================================
+ // Changing the data layout of this class breaks the binary serialization format. See comments for
+ // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+ // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+ // accordingly.
+ //==================================================================================================
+
+ PX_FORCE_INLINE ManifestEntry(PxU32 _offset, PxType _type)
+ {
+ Cm::markSerializedMem(this, sizeof(ManifestEntry));
+ offset = _offset;
+ type = _type;
+ }
+ PX_FORCE_INLINE ManifestEntry() { Cm::markSerializedMem(this, sizeof(ManifestEntry)); }
+ PX_FORCE_INLINE void operator =(const ManifestEntry& m)
+ {
+ PxMemCopy(this, &m, sizeof(ManifestEntry));
+ }
+
+ PxU32 offset;
+ PxType type;
+ };
+
+ struct ImportReference
+ {
+ //= ATTENTION! =====================================================================================
+ // Changing the data layout of this class breaks the binary serialization format. See comments for
+ // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+ // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+ // accordingly.
+ //==================================================================================================
+
+ PX_FORCE_INLINE ImportReference(PxSerialObjectId _id, PxType _type)
+ {
+ Cm::markSerializedMem(this, sizeof(ImportReference));
+ id = _id;
+ type = _type;
+ }
+ PX_FORCE_INLINE ImportReference() { Cm::markSerializedMem(this, sizeof(ImportReference)); }
+ PX_FORCE_INLINE void operator =(const ImportReference& m)
+ {
+ PxMemCopy(this, &m, sizeof(ImportReference));
+ }
+ PxSerialObjectId id;
+ PxType type;
+ };
+
+#define SERIAL_OBJECT_INDEX_TYPE_BIT (1u<<31)
+ struct SerialObjectIndex
+ {
+ //= ATTENTION! =====================================================================================
+ // Changing the data layout of this class breaks the binary serialization format. See comments for
+ // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+ // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+ // accordingly.
+ //==================================================================================================
+
+ PX_FORCE_INLINE SerialObjectIndex(PxU32 index, bool external) { setIndex(index, external); }
+ PX_FORCE_INLINE SerialObjectIndex(const SerialObjectIndex& objIndex) : mObjIndex(objIndex.mObjIndex) {}
+ PX_FORCE_INLINE SerialObjectIndex() : mObjIndex(PX_INVALID_U32) {}
+
+ PX_FORCE_INLINE void setIndex(PxU32 index, bool external)
+ {
+ PX_ASSERT((index & SERIAL_OBJECT_INDEX_TYPE_BIT) == 0);
+ mObjIndex = index | (external ? SERIAL_OBJECT_INDEX_TYPE_BIT : 0);
+ }
+
+ PX_FORCE_INLINE PxU32 getIndex(bool& isExternal)
+ {
+ PX_ASSERT(mObjIndex != PX_INVALID_U32);
+ isExternal = (mObjIndex & SERIAL_OBJECT_INDEX_TYPE_BIT) > 0;
+ return mObjIndex & ~SERIAL_OBJECT_INDEX_TYPE_BIT;
+ }
+
+ private:
+ PxU32 mObjIndex;
+ };
+
+ struct ExportReference
+ {
+ //= ATTENTION! =====================================================================================
+ // Changing the data layout of this class breaks the binary serialization format. See comments for
+ // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+ // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+ // accordingly.
+ //==================================================================================================
+
+ PX_FORCE_INLINE ExportReference(PxSerialObjectId _id, SerialObjectIndex _objIndex)
+ {
+ Cm::markSerializedMem(this, sizeof(ExportReference));
+ id = _id;
+ objIndex = _objIndex;
+ }
+ PX_FORCE_INLINE ExportReference() { Cm::markSerializedMem(this, sizeof(ExportReference)); }
+ PX_FORCE_INLINE void operator =(const ExportReference& m)
+ {
+ PxMemCopy(this, &m, sizeof(ExportReference));
+ }
+ PxSerialObjectId id;
+ SerialObjectIndex objIndex;
+ };
+
+ template<class ReferenceType>
+ struct InternalReference
+ {
+ //= ATTENTION! =====================================================================================
+ // Changing the data layout of this class breaks the binary serialization format. See comments for
+ // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+ // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+ // accordingly.
+ //==================================================================================================
+
+ PX_FORCE_INLINE InternalReference(ReferenceType _reference, PxU32 _kind, SerialObjectIndex _objIndex)
+ {
+ Cm::markSerializedMem(this, sizeof(InternalReference));
+ reference = _reference;
+ kind = _kind;
+ objIndex = _objIndex;
+ }
+ PX_FORCE_INLINE InternalReference() { Cm::markSerializedMem(this, sizeof(InternalReference)); }
+ PX_FORCE_INLINE void operator =(const InternalReference& m)
+ {
+ PxMemCopy(this, &m, sizeof(InternalReference));
+ }
+ ReferenceType reference;
+ PxU32 kind;
+ SerialObjectIndex objIndex;
+ };
+
+ typedef InternalReference<size_t> InternalReferencePtr;
+ typedef InternalReference<PxU32> InternalReferenceIdx;
+
+ typedef shdfnd::Pair<size_t, PxU32> InternalRefKey;
+ typedef Cm::CollectionHashMap<InternalRefKey, SerialObjectIndex> InternalRefMap;
+
+ class DeserializationContext : public PxDeserializationContext, public Ps::UserAllocated
+ {
+ PX_NOCOPY(DeserializationContext)
+
+ public:
+ DeserializationContext(const ManifestEntry* manifestTable,
+ const ImportReference* importReferences,
+ PxU8* objectDataAddress,
+ const InternalRefMap& internalReferencesMap,
+ const Cm::Collection* externalRefs,
+ PxU8* extraData,
+ PxU32 physxVersion)
+ : mManifestTable(manifestTable)
+ , mImportReferences(importReferences)
+ , mObjectDataAddress(objectDataAddress)
+ , mInternalReferencesMap(internalReferencesMap)
+ , mExternalRefs(externalRefs)
+ , mPhysXVersion(physxVersion)
+ {
+ mExtraDataAddress = extraData;
+ }
+
+ virtual PxBase* resolveReference(PxU32 kind, size_t reference) const;
+
+ PxU32 getPhysXVersion() const { return mPhysXVersion; }
+ private:
+ //various pointers to deserialized data
+ const ManifestEntry* mManifestTable;
+ const ImportReference* mImportReferences;
+ PxU8* mObjectDataAddress;
+
+ //internal references map for resolving references.
+ const InternalRefMap& mInternalReferencesMap;
+
+ //external collection for resolving import references.
+ const Cm::Collection* mExternalRefs;
+ const PxU32 mPhysXVersion;
+ };
+
+ class SerializationContext : public PxSerializationContext, public Ps::UserAllocated
+ {
+ PX_NOCOPY(SerializationContext)
+ public:
+ SerializationContext(const Cm::Collection& collection, const Cm::Collection* externalRefs)
+ : mCollection(collection)
+ , mExternalRefs(externalRefs)
+ {
+ // fill object to collection index map (same ordering as manifest)
+ for (PxU32 i=0;i<mCollection.internalGetNbObjects();i++)
+ {
+ mObjToCollectionIndexMap[mCollection.internalGetObject(i)] = i;
+ }
+ }
+
+ virtual void writeData(const void* buffer, PxU32 size) { mMemStream.write(buffer, size); }
+ virtual PxU32 getTotalStoredSize() { return mMemStream.getSize(); }
+ virtual void alignData(PxU32 alignment = PX_SERIAL_ALIGN)
+ {
+ if(!alignment)
+ return;
+
+ PxI32 bytesToPad = PxI32(getPadding(mMemStream.getSize(), alignment));
+ static const PxI32 BUFSIZE = 64;
+ char buf[BUFSIZE];
+ PxMemSet(buf, 0, bytesToPad < BUFSIZE ? PxU32(bytesToPad) : PxU32(BUFSIZE));
+ while(bytesToPad > 0)
+ {
+ mMemStream.write(buf, bytesToPad < BUFSIZE ? PxU32(bytesToPad) : PxU32(BUFSIZE));
+ bytesToPad -= BUFSIZE;
+ }
+ PX_ASSERT(!getPadding(getTotalStoredSize(), alignment));
+ }
+
+ virtual void writeName(const char*)
+ {
+ Ps::getFoundation().error(physx::PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__,
+ "Cannot export names during exportData.");
+ }
+
+ const PxCollection& getCollection() const { return mCollection; }
+
+ virtual void registerReference(PxBase& serializable, PxU32 kind, size_t reference);
+
+ const Ps::Array<ImportReference>& getImportReferences() { return mImportReferences; }
+ InternalRefMap& getInternalReferencesPtrMap() { return mInternalReferencesPtrMap; }
+ InternalRefMap& getInternalReferencesIdxMap() { return mInternalReferencesIdxMap; }
+
+ PxU32 getSize() const { return mMemStream.getSize(); }
+ PxU8* getData() const { return mMemStream.getData(); }
+
+
+
+ private:
+ //import reference map for unique registration of import references and corresponding buffer.
+ Ps::HashMap<PxSerialObjectId, PxU32> mImportReferencesMap;
+ Ps::Array<ImportReference> mImportReferences;
+
+ //maps for unique registration of internal references
+ InternalRefMap mInternalReferencesPtrMap;
+ InternalRefMap mInternalReferencesIdxMap;
+
+ //map for quick lookup of manifest index.
+ Ps::HashMap<const PxBase*, PxU32> mObjToCollectionIndexMap;
+
+ //collection and externalRefs collection for assigning references.
+ const Cm::Collection& mCollection;
+ const Cm::Collection* mExternalRefs;
+
+ PxDefaultMemoryOutputStream mMemStream;
+
+ };
+
+ } // namespace Sn
+}
+
+#endif