aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp')
-rw-r--r--PhysX_3.4/Source/PhysXExtensions/src/serialization/Binary/SnBinarySerialization.cpp402
1 files changed, 402 insertions, 0 deletions
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;
+}