diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXExtensions/src/serialization | |
| download | physx-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')
48 files changed, 13760 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 = ¤t->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 diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/File/SnFile.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/File/SnFile.h new file mode 100644 index 00000000..0c5a817e --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/File/SnFile.h @@ -0,0 +1,85 @@ +// 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 SN_FILE_H +#define SN_FILE_H + +// fopen_s - returns 0 on success, non-zero on failure + +#if PX_MICROSOFT_FAMILY + +#include <stdio.h> + +namespace physx +{ +namespace sn +{ +PX_INLINE PxI32 fopen_s(FILE** file, const char* name, const char* mode) +{ + static const PxU32 MAX_LEN = 300; + char buf[MAX_LEN+1]; + + PxU32 i; + for(i = 0; i<MAX_LEN && name[i]; i++) + buf[i] = name[i] == '/' ? '\\' : name[i]; + buf[i] = 0; + + return i == MAX_LEN ? -1 : ::fopen_s(file, buf, mode); +}; + +} // namespace sn +} // namespace physx + +#elif PX_UNIX_FAMILY || PX_PS4 + +#include <stdio.h> + +namespace physx +{ +namespace sn +{ +PX_INLINE PxI32 fopen_s(FILE** file, const char* name, const char* mode) +{ + FILE* fp = ::fopen(name, mode); + if(fp) + { + *file = fp; + return PxI32(0); + } + return -1; +} +} // namespace sn +} // namespace physx +#else +#error "Platform not supported!" +#endif + +#endif //SN_FILE_H + diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.cpp new file mode 100644 index 00000000..1a147058 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.cpp @@ -0,0 +1,151 @@ +// 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 "SnSerialUtils.h" +#include "PsString.h" +#include "PxSerialization.h" +#include "PxPhysicsVersion.h" +#include "PsBasicTemplates.h" + +using namespace physx; + +namespace +{ + +#define SN_NUM_BINARY_PLATFORMS 11 +const PxU32 sBinaryPlatformTags[SN_NUM_BINARY_PLATFORMS] = +{ + PX_MAKE_FOURCC('W','_','3','2'), + PX_MAKE_FOURCC('W','_','6','4'), + PX_MAKE_FOURCC('L','_','3','2'), + PX_MAKE_FOURCC('L','_','6','4'), + PX_MAKE_FOURCC('M','_','3','2'), + PX_MAKE_FOURCC('M','_','6','4'), + PX_MAKE_FOURCC('M','O','C','A'), + PX_MAKE_FOURCC('A','N','D','R'), + PX_MAKE_FOURCC('A','I','O','S'), + PX_MAKE_FOURCC('A','A','6','4'), + PX_MAKE_FOURCC('X','O','N','E') +}; + +const char* sBinaryPlatformNames[SN_NUM_BINARY_PLATFORMS] = +{ + "win32", + "win64", + "linux32", + "linux64", + "macOSX32", + "macOSX64", + "ps4", + "android", + "ios", + "ios64", + "xboxone" +}; + +#define SN_NUM_BINARY_COMPATIBLE_VERSIONS 1 + +// +// Important: if you adjust the following structure, please adjust the comment for PX_BINARY_SERIAL_VERSION as well +// +const Ps::Pair<PxU32, PxU32> sBinaryCompatibleVersions[SN_NUM_BINARY_COMPATIBLE_VERSIONS] = +{ + Ps::Pair<PxU32, PxU32>(PX_PHYSICS_VERSION, PX_BINARY_SERIAL_VERSION) +}; + +} + +namespace physx { namespace Sn { + +PxU32 getBinaryPlatformTag() +{ +#if PX_WINDOWS && PX_X86 + return sBinaryPlatformTags[0]; +#elif PX_WINDOWS && PX_X64 + return sBinaryPlatformTags[1]; +#elif PX_LINUX && (PX_X86 || PX_ARM) + return sBinaryPlatformTags[2]; +#elif PX_LINUX && (PX_X64 || PX_A64) + return sBinaryPlatformTags[3]; +#elif PX_OSX && PX_X86 + return sBinaryPlatformTags[4]; +#elif PX_OSX && PX_X64 + return sBinaryPlatformTags[5]; +#elif PX_PS4 + return sBinaryPlatformTags[6]; +#elif PX_ANDROID + return sBinaryPlatformTags[7]; +#elif PX_IOS && PX_ARM + return sBinaryPlatformTags[8]; +#elif PX_IOS && PX_A64 + return sBinaryPlatformTags[9]; +#elif PX_XBOXONE + return sBinaryPlatformTags[10]; +#else + #error Unknown binary platform +#endif +} + +bool isBinaryPlatformTagValid(physx::PxU32 platformTag) +{ + PxU32 platformIndex = 0; + while (platformIndex < SN_NUM_BINARY_PLATFORMS && platformTag != sBinaryPlatformTags[platformIndex]) platformIndex++; + return platformIndex < SN_NUM_BINARY_PLATFORMS; +} + +const char* getBinaryPlatformName(physx::PxU32 platformTag) +{ + PxU32 platformIndex = 0; + while (platformIndex < SN_NUM_BINARY_PLATFORMS && platformTag != sBinaryPlatformTags[platformIndex]) platformIndex++; + return (platformIndex == SN_NUM_BINARY_PLATFORMS) ? "unknown" : sBinaryPlatformNames[platformIndex]; +} + +bool checkCompatibility(const PxU32 version, const PxU32 binaryVersion) +{ + for(PxU32 i =0; i<SN_NUM_BINARY_COMPATIBLE_VERSIONS; i++) + { + if(version == sBinaryCompatibleVersions[i].first && binaryVersion == sBinaryCompatibleVersions[i].second) + return true; + } + return false; +} + +void getCompatibilityVersionsStr(char* buffer, PxU32 lenght) +{ + size_t len = 0; + for(PxU32 i =0; i<SN_NUM_BINARY_COMPATIBLE_VERSIONS; i++) + { + physx::shdfnd::snprintf(buffer + len, lenght - len, "%x-%d\n", sBinaryCompatibleVersions[i].first, sBinaryCompatibleVersions[i].second); + len = strlen(buffer); + } +} + +} // Sn +} // physx + diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.h new file mode 100644 index 00000000..31aa3944 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialUtils.h @@ -0,0 +1,50 @@ +// 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_SERIAL_UTILS +#define PX_PHYSICS_SN_SERIAL_UTILS + +#include "CmPhysXCommon.h" + +namespace physx +{ + +namespace Sn +{ + PxU32 getBinaryPlatformTag(); + bool isBinaryPlatformTagValid(PxU32 platformTag); + const char* getBinaryPlatformName(PxU32 platformTag); + bool checkCompatibility(const PxU32 version, const PxU32 binaryVersion); + void getCompatibilityVersionsStr(char* buffer, PxU32 lenght); +} + +} + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp new file mode 100644 index 00000000..15edeb46 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerialization.cpp @@ -0,0 +1,433 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PxPhysicsAPI.h" +#include "PxConstraintExt.h" +#include "PxPhysicsVersion.h" +#include "PsFoundation.h" +#include "PxMetaData.h" +#include "SnConvX.h" +#include "SnSerializationRegistry.h" +#include "SnSerialUtils.h" +#include "ExtSerialization.h" +#include "PxSerializer.h" +#include "CmCollection.h" + +using namespace physx; +using namespace Sn; + +namespace +{ + struct RequiresCallback : public PxProcessPxBaseCallback + { + RequiresCallback(physx::PxCollection& c) : collection(c) {} + void process(PxBase& base) + { + if(!collection.contains(base)) + collection.add(base); + } + + PxCollection& collection; + PX_NOCOPY(RequiresCallback) + }; + + struct CompleteCallback : public PxProcessPxBaseCallback + { + CompleteCallback(physx::PxCollection& r, physx::PxCollection& c, const physx::PxCollection* e) : + requires(r), complete(c), external(e) {} + void process(PxBase& base) + { + if(complete.contains(base) || (external && external->contains(base))) + return; + if(!requires.contains(base)) + requires.add(base); + } + + PxCollection& requires; + PxCollection& complete; + const PxCollection* external; + PX_NOCOPY(CompleteCallback) + }; + + void getRequiresCollection(PxCollection& requires, PxCollection& collection, PxCollection& complete, const PxCollection* external, PxSerializationRegistry& sr, bool followJoints) + { + CompleteCallback callback(requires, complete, external); + for (PxU32 i = 0; i < collection.getNbObjects(); ++i) + { + PxBase& s = collection.getObject(i); + const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); + PX_ASSERT(serializer); + serializer->requires(s, callback); + + if(followJoints) + { + PxRigidActor* actor = s.is<PxRigidActor>(); + if(actor) + { + Ps::Array<PxConstraint*> objects(actor->getNbConstraints()); + actor->getConstraints(objects.begin(), objects.size()); + + for(PxU32 j=0;j<objects.size();j++) + { + PxU32 typeId; + PxJoint* joint = reinterpret_cast<PxJoint*>(objects[j]->getExternalReference(typeId)); + if(typeId == PxConstraintExtIDs::eJOINT) + { + const PxSerializer* sj = sr.getSerializer(joint->getConcreteType()); + PX_ASSERT(sj); + sj->requires(*joint, callback); + if(!requires.contains(*joint)) + requires.add(*joint); + } + } + } + } + } + } +} + +bool PxSerialization::isSerializable(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalReferences) +{ + PxCollection* subordinateCollection = PxCreateCollection(); + PX_ASSERT(subordinateCollection); + + for(PxU32 i = 0; i < collection.getNbObjects(); ++i) + { + PxBase& s = collection.getObject(i); + const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); + PX_ASSERT(serializer); + if(serializer->isSubordinate()) + subordinateCollection->add(s); + + if(externalReferences) + { + PxSerialObjectId id = collection.getId(s); + if(id != PX_SERIAL_OBJECT_ID_INVALID) + { + PxBase* object = externalReferences->find(id); + if(object && (object != &s)) + { + subordinateCollection->release(); + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: Reference id %" PX_PRIu64 " used both in current collection and in externalReferences. " + "Please use unique identifiers.", id); + return false; + } + } + } + } + + PxCollection* requiresCollection = PxCreateCollection(); + PX_ASSERT(requiresCollection); + + RequiresCallback requiresCallback0(*requiresCollection); + + for (PxU32 i = 0; i < collection.getNbObjects(); ++i) + { + PxBase& s = collection.getObject(i); + const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); + PX_ASSERT(serializer); + serializer->requires(s, requiresCallback0); + + Cm::Collection* cmRequiresCollection = static_cast<Cm::Collection*>(requiresCollection); + + for(PxU32 j = 0; j < cmRequiresCollection->getNbObjects(); ++j) + { + PxBase& s0 = cmRequiresCollection->getObject(j); + + if(subordinateCollection->contains(s0)) + { + subordinateCollection->remove(s0); + continue; + } + + bool requiredIsInCollection = collection.contains(s0); + if(!requiredIsInCollection) + { + if(externalReferences) + { + if(!externalReferences->contains(s0)) + { + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: Object of type %s references a missing object of type %s. " + "The missing object needs to be added to either the current collection or the externalReferences collection.", + s.getConcreteTypeName(), s0.getConcreteTypeName()); + } + else if(externalReferences->getId(s0) == PX_SERIAL_OBJECT_ID_INVALID) + { + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: Object of type %s in externalReferences collection requires an id.", + s0.getConcreteTypeName()); + } + else + continue; + } + else + { + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: Object of type %s references a missing serial object of type %s. " + "Please completed the collection or specify an externalReferences collection containing the object.", + s.getConcreteTypeName(), s0.getConcreteTypeName()); + } + subordinateCollection->release(); + requiresCollection->release(); + return false; + } + } + cmRequiresCollection->mObjects.clear(); + } + requiresCollection->release(); + + PxU32 numOrphans = subordinateCollection->getNbObjects(); + + for(PxU32 j = 0; j < numOrphans; ++j) + { + PxBase& subordinate = subordinateCollection->getObject(j); + + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: An object of type %s is subordinate but not required " + "by other objects in the collection (orphan). Please remove the object from the collection or add its owner.", + subordinate.getConcreteTypeName()); + } + + subordinateCollection->release(); + + if(numOrphans>0) + return false; + + if(externalReferences) + { + PxCollection* oppositeRequiresCollection = PxCreateCollection(); + PX_ASSERT(oppositeRequiresCollection); + + RequiresCallback requiresCallback(*oppositeRequiresCollection); + + for (PxU32 i = 0; i < externalReferences->getNbObjects(); ++i) + { + PxBase& s = externalReferences->getObject(i); + const PxSerializer* serializer = sr.getSerializer(s.getConcreteType()); + PX_ASSERT(serializer); + serializer->requires(s, requiresCallback); + + Cm::Collection* cmCollection = static_cast<Cm::Collection*>(oppositeRequiresCollection); + + for(PxU32 j = 0; j < cmCollection->getNbObjects(); ++j) + { + PxBase& s0 = cmCollection->getObject(j); + + if(collection.contains(s0)) + { + oppositeRequiresCollection->release(); + Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::isSerializable: Object of type %s in externalReferences references an object " + "of type %s in collection (circular dependency).", + s.getConcreteTypeName(), s0.getConcreteTypeName()); + return false; + } + } + cmCollection->mObjects.clear(); + } + oppositeRequiresCollection->release(); + } + + return true; +} + +void PxSerialization::complete(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* exceptFor, bool followJoints) +{ + PxCollection* curCollection = PxCreateCollection(); + PX_ASSERT(curCollection); + curCollection->add(collection); + + PxCollection* requiresCollection = PxCreateCollection(); + PX_ASSERT(requiresCollection); + + do + { + getRequiresCollection(*requiresCollection, *curCollection, collection, exceptFor, sr, followJoints); + + collection.add(*requiresCollection); + PxCollection* swap = curCollection; + curCollection = requiresCollection; + requiresCollection = swap; + (static_cast<Cm::Collection*>(requiresCollection))->mObjects.clear(); + + }while(curCollection->getNbObjects() > 0); + + requiresCollection->release(); + curCollection->release(); + +} + +void PxSerialization::createSerialObjectIds(PxCollection& collection, const PxSerialObjectId base) +{ + PxSerialObjectId localBase = base; + PxU32 nbObjects = collection.getNbObjects(); + + for (PxU32 i = 0; i < nbObjects; ++i) + { + while(collection.find(localBase)) + { + localBase++; + } + + PxBase& s = collection.getObject(i); + if(PX_SERIAL_OBJECT_ID_INVALID == collection.getId(s)) + { + collection.addId(s, localBase); + localBase++; + } + } +} + +namespace physx { namespace Sn +{ + static PxU32 addToStringTable(physx::shdfnd::Array<char>& stringTable, const char* str) + { + if(!str) + return 0xffffffff; + + PxI32 length = PxI32(stringTable.size()); + const char* table = stringTable.begin(); + const char* start = table; + while(length) + { + if(strcmp(table, str)==0) + return PxU32(table - start); + + const char* saved = table; + while(*table++); + length -= PxU32(table - saved); + PX_ASSERT(length>=0); + } + + const PxU32 offset = stringTable.size(); + + while(*str) + stringTable.pushBack(*str++); + stringTable.pushBack(0); + return offset; + } +} } + +void PxSerialization::dumpBinaryMetaData(PxOutputStream& outputStream, PxSerializationRegistry& sr) +{ + class MetaDataStream : public PxOutputStream + { + public: + bool addNewType(const char* typeName) + { + for(PxU32 i=0;i<types.size();i++) + { + if(strcmp(types[i], typeName)==0) + return false; + } + types.pushBack(typeName); + return true; + } + virtual PxU32 write(const void* src, PxU32 count) + { + PX_ASSERT(count==sizeof(PxMetaDataEntry)); + const PxMetaDataEntry* entry = reinterpret_cast<const PxMetaDataEntry*>(src); + if(( entry->flags & PxMetaDataFlag::eTYPEDEF) || ((entry->flags & PxMetaDataFlag::eCLASS) && (!entry->name)) ) + newType = addNewType(entry->type); + if(newType) + metaData.pushBack(*entry); + return count; + } + shdfnd::Array<PxMetaDataEntry> metaData; + shdfnd::Array<const char*> types; + bool newType; + }s; + + SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr); + sn.getBinaryMetaData(s); + + shdfnd::Array<char> stringTable; + + PxU32 nb = s.metaData.size(); + PxMetaDataEntry* entries = s.metaData.begin(); + for(PxU32 i=0;i<nb;i++) + { + entries[i].type = reinterpret_cast<const char*>(size_t(addToStringTable(stringTable, entries[i].type))); + entries[i].name = reinterpret_cast<const char*>(size_t(addToStringTable(stringTable, entries[i].name))); + } + + PxU32 platformTag = getBinaryPlatformTag(); + +#if PX_X64 + const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::ePC); +#endif +#if PX_X86 || defined(__CYGWIN__) + const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::ePC); +#endif +#if PX_ARM_FAMILY + const PxU32 gaussMapLimit = PxGetGaussMapVertexLimitForPlatform(PxPlatform::eARM); +#endif + + const PxU32 header = PX_MAKE_FOURCC('M','E','T','A'); + const PxU32 version = PX_PHYSICS_VERSION; + const PxU32 binaryVersion = PX_BINARY_SERIAL_VERSION; + const PxU32 ptrSize = sizeof(void*); + PxU32 buildNumber = 0; +#if defined(PX_BUILD_NUMBER) + buildNumber = PX_BUILD_NUMBER; +#endif + outputStream.write(&header, 4); + outputStream.write(&version, 4); + outputStream.write(&binaryVersion, 4); + outputStream.write(&buildNumber, 4); + outputStream.write(&ptrSize, 4); + outputStream.write(&platformTag, 4); + outputStream.write(&gaussMapLimit, 4); + + outputStream.write(&nb, 4); + outputStream.write(entries, nb*sizeof(PxMetaDataEntry)); + + //concreteTypes to name + PxU32 num = sn.getNbSerializers(); + outputStream.write(&num, 4); + for(PxU32 i=0; i<num; i++) + { + PxU16 type = sn.getSerializerType(i); + PxU32 nameOffset = addToStringTable(stringTable, sn.getSerializerName(i)); + outputStream.write(&type, 2); + outputStream.write(&nameOffset, 4); + } + + PxU32 length = stringTable.size(); + const char* table = stringTable.begin(); + outputStream.write(&length, 4); + outputStream.write(table, length); +} + +PxBinaryConverter* PxSerialization::createBinaryConverter() +{ + return PX_NEW(ConvX)(); +} diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.cpp new file mode 100644 index 00000000..091f7e08 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.cpp @@ -0,0 +1,287 @@ +// 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 "SnSerializationRegistry.h" +#include "PxPhysics.h" +#include "PxPhysicsSerialization.h" +#include "ExtSerialization.h" +#include "PxSerializer.h" +#include "CmCollection.h" +#include "PxArticulationLink.h" +#include "PsFoundation.h" +#include "PsString.h" + +using namespace physx; + +namespace +{ + class CollectionSorter : public PxProcessPxBaseCallback + { + typedef Ps::Pair<PxBase*, PxSerialObjectId> Object; + + class Element + { + public: + Object object; + Ps::Array<PxU32> children; + bool isFinished; + + Element(PxBase* obj = NULL) : object(obj, PX_SERIAL_OBJECT_ID_INVALID), isFinished(false) {} + }; + + public: + CollectionSorter(Cm::Collection& collection, Sn::SerializationRegistry& sr, bool isRepx) : mCollection(collection), mSr(sr), mIsRepx(isRepx) {} + virtual ~CollectionSorter(){} + + void process(PxBase& base) + { + addChild(&base); + //ArticulationLink is not a repx serializer, so should require Articulation here + if( mIsRepx && PxConcreteType::eARTICULATION_LINK == base.getConcreteType() ) + { + PxArticulationLink* link = static_cast<PxArticulationLink*>(&base); + PxBase* a = reinterpret_cast<PxBase*>(&link->getArticulation()); + if(mCurElement->object.first != a ) //don't require itself + addChild(a); + } + } + + void sort() + { + Element element; + PxU32 i; + + PxU32 nbObject = mCollection.internalGetNbObjects(); + const Cm::Collection::ObjectToIdMap::Entry* objectdatas = mCollection.internalGetObjects(); + for( i = 0; i < nbObject; ++i ) + { + element.object.first = objectdatas[i].first; + element.object.second = objectdatas[i].second; + mObjToIdMap.insert(objectdatas[i].first, mElements.size()); + mElements.pushBack(element); + } + + for( i = 0; i < nbObject; ++i ) + { + mCurElement = &mElements[i]; + const PxSerializer* serializer = mSr.getSerializer(mCurElement->object.first->getConcreteType()); + PX_ASSERT(serializer); + serializer->requires(*mCurElement->object.first, *this); + } + + for( i = 0; i < nbObject; ++i ) + { + if( mElements[i].isFinished ) + continue; + + AddElement(mElements[i]); + } + + mCollection.mObjects.clear(); + for(Ps::Array<Object>::Iterator o = mSorted.begin(); o != mSorted.end(); ++o ) + { + mCollection.internalAdd(o->first, o->second); + } + } + + void AddElement(Element& e) + { + if( !e.isFinished ) + { + for( Ps::Array<PxU32>::Iterator child = e.children.begin(); child != e.children.end(); ++child ) + { + AddElement(mElements[*child]); + } + mSorted.pushBack(e.object); + e.isFinished = true; + } + } + + private: + PX_INLINE void addChild(PxBase* base) + { + PX_ASSERT(mCurElement); + const Ps::HashMap<PxBase*, PxU32>::Entry* entry = mObjToIdMap.find(base); + if(entry) + mCurElement->children.pushBack(entry->second); + } + + CollectionSorter& operator=(const CollectionSorter&); + Ps::HashMap<PxBase*, PxU32> mObjToIdMap; + Ps::Array<Element> mElements; + Cm::Collection& mCollection; + Sn::SerializationRegistry& mSr; + Ps::Array<Object> mSorted; + Element* mCurElement; + bool mIsRepx; + }; +} + +namespace physx { namespace Sn { + +SerializationRegistry::SerializationRegistry(PxPhysics& physics) + : mPhysics(physics) +{ + PxRegisterPhysicsSerializers(*this); + Ext::RegisterExtensionsSerializers(*this); + + registerBinaryMetaDataCallback(PxGetPhysicsBinaryMetaData); + registerBinaryMetaDataCallback(Ext::GetExtensionsBinaryMetaData); +} + +SerializationRegistry::~SerializationRegistry() +{ + PxUnregisterPhysicsSerializers(*this); + Ext::UnregisterExtensionsSerializers(*this); + + if(mSerializers.size() > 0) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::release(): some registered PxSerializer instances were not unregistered"); + } + + if(mRepXSerializers.size() > 0) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::release(): some registered PxRepXSerializer instances were not unregistered"); + } +} + +void SerializationRegistry::registerSerializer(PxType type, PxSerializer& serializer) +{ + if(mSerializers.find(type)) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::registerSerializer: Type %d has already been registered", type); + } + + mSerializers.insert(type, &serializer); +} + +PxSerializer* SerializationRegistry::unregisterSerializer(PxType type) +{ + const SerializerMap::Entry* e = mSerializers.find(type); + PxSerializer* s = e ? e->second : NULL; + + if(!mSerializers.erase(type)) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::unregisterSerializer: failed to find PxSerializer instance for type %d", type); + } + return s; +} + +const PxSerializer* SerializationRegistry::getSerializer(PxType type) const +{ + const SerializerMap::Entry* e = mSerializers.find(type); +#if PX_CHECKED + if (!e) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::getSerializer: failed to find PxSerializer instance for type %d", type); + } +#endif + return e ? e->second : NULL; +} + +PxType SerializationRegistry::getSerializerType(PxU32 index) const +{ + PX_ASSERT(index < mSerializers.size()); + return mSerializers.getEntries()[index].first; +} + +const char* SerializationRegistry::getSerializerName(PxU32 index) const +{ + PX_ASSERT(index < mSerializers.size()); + return mSerializers.getEntries()[index].second->getConcreteTypeName(); +} + +void SerializationRegistry::registerBinaryMetaDataCallback(PxBinaryMetaDataCallback callback) +{ + mMetaDataCallbacks.pushBack(callback); +} + +void SerializationRegistry::getBinaryMetaData(PxOutputStream& stream) const +{ + for(PxU32 i = 0; i < mMetaDataCallbacks.size(); i++) + { + mMetaDataCallbacks[i](stream); + } +} + +void SerializationRegistry::registerRepXSerializer(PxType type, PxRepXSerializer& serializer) +{ + if(mRepXSerializers.find(type)) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::registerRepXSerializer: Type %d has already been registered", type); + } + + mRepXSerializers.insert(type, &serializer); +} + +PxRepXSerializer* SerializationRegistry::getRepXSerializer(const char* typeName) const +{ + SerializationRegistry* sr = const_cast<SerializationRegistry*>(this); + for( RepXSerializerMap::Iterator iter = sr->mRepXSerializers.getIterator(); !iter.done(); ++iter) + { + if ( physx::shdfnd::stricmp( iter->second->getTypeName(), typeName ) == 0 ) + return iter->second; + } + return NULL; +} + +PxRepXSerializer* SerializationRegistry::unregisterRepXSerializer(PxType type) +{ + const RepXSerializerMap::Entry* e = mRepXSerializers.find(type); + PxRepXSerializer* s = e ? e->second : NULL; + + if(!mRepXSerializers.erase(type)) + { + shdfnd::getFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "PxSerializationRegistry::unregisterRepXSerializer: failed to find PxRepXSerializer instance for type %d", type); + } + return s; +} + +void sortCollection(Cm::Collection& collection, SerializationRegistry& sr, bool isRepx) +{ + CollectionSorter sorter(collection, sr, isRepx); + sorter.sort(); +} + +} // Sn + +PxSerializationRegistry* PxSerialization::createSerializationRegistry(PxPhysics& physics) +{ + return PX_NEW(Sn::SerializationRegistry)(physics); +} + +} // physx + diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.h new file mode 100644 index 00000000..6aa21c24 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/SnSerializationRegistry.h @@ -0,0 +1,91 @@ +// 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_REGISTRY +#define PX_PHYSICS_SN_SERIALIZATION_REGISTRY + +#include "PxSerialization.h" +#include "PxRepXSerializer.h" +#include "CmPhysXCommon.h" +#include "PsUserAllocated.h" +#include "PsArray.h" +#include "PsHashMap.h" + +namespace physx +{ + +namespace Cm { class Collection; } + +namespace Sn { + + class SerializationRegistry : public PxSerializationRegistry, public Ps::UserAllocated + { + public: + SerializationRegistry(PxPhysics& physics); + virtual ~SerializationRegistry(); + + virtual void release(){ PX_DELETE(this); } + + PxPhysics& getPhysics() const { return mPhysics; } + + //binary + void registerSerializer(PxType type, PxSerializer& serializer); + PxSerializer* unregisterSerializer(PxType type); + void registerBinaryMetaDataCallback(PxBinaryMetaDataCallback callback); + void getBinaryMetaData(PxOutputStream& stream) const; + const PxSerializer* getSerializer(PxType type) const; + const char* getSerializerName(PxU32 index) const; + PxType getSerializerType(PxU32 index) const; + PxU32 getNbSerializers() const { return mSerializers.size(); } + //repx + void registerRepXSerializer(PxType type, PxRepXSerializer& serializer); + PxRepXSerializer* getRepXSerializer(const char* typeName) const; + PxRepXSerializer* unregisterRepXSerializer(PxType type); + + protected: + SerializationRegistry &operator=(const SerializationRegistry &); + private: + typedef Ps::CoalescedHashMap<PxType, PxSerializer*> SerializerMap; + typedef Ps::HashMap<PxType, PxRepXSerializer*> RepXSerializerMap; + + PxPhysics& mPhysics; + SerializerMap mSerializers; + RepXSerializerMap mRepXSerializers; + Ps::Array<PxBinaryMetaDataCallback> mMetaDataCallbacks; + }; + + void sortCollection(Cm::Collection& collection, SerializationRegistry& sr, bool isRepx); +} // Sn + +} // physx + + + +#endif + diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnJointRepXSerializer.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnJointRepXSerializer.cpp new file mode 100644 index 00000000..94d60453 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnJointRepXSerializer.cpp @@ -0,0 +1,137 @@ +// 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 "PxMetaDataObjects.h" +#include "PxExtensionMetaDataObjects.h" +#include "ExtJointMetaDataExtensions.h" +#include "SnRepXSerializerImpl.h" +#include "PxJointRepXSerializer.h" + +namespace physx { + + template<typename TJointType> + inline TJointType* createJoint( PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1 ) + { + PX_UNUSED(physics); + PX_UNUSED(actor0); + PX_UNUSED(actor1); + PX_UNUSED(localFrame0); + PX_UNUSED(localFrame1); + return NULL; + } + + template<> + inline PxD6Joint* createJoint<PxD6Joint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxD6JointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<> + inline PxDistanceJoint* createJoint<PxDistanceJoint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxDistanceJointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<> + inline PxFixedJoint* createJoint<PxFixedJoint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxFixedJointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<> + inline PxPrismaticJoint* createJoint<PxPrismaticJoint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxPrismaticJointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<> + inline PxRevoluteJoint* createJoint<PxRevoluteJoint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxRevoluteJointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<> + inline PxSphericalJoint* createJoint<PxSphericalJoint>(PxPhysics& physics, + PxRigidActor* actor0, const PxTransform& localFrame0, + PxRigidActor* actor1, const PxTransform& localFrame1) + { + return PxSphericalJointCreate( physics, actor0, localFrame0, actor1, localFrame1 ); + } + + template<typename TJointType> + PxRepXObject PxJointRepXSerializer<TJointType>::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PxRigidActor* actor0 = NULL; + PxRigidActor* actor1 = NULL; + PxTransform localPose0 = PxTransform(PxIdentity); + PxTransform localPose1 = PxTransform(PxIdentity); + bool ok = true; + if ( inReader.gotoChild( "Actors" ) ) + { + ok = readReference<PxRigidActor>( inReader, *inCollection, "actor0", actor0 ); + ok &= readReference<PxRigidActor>( inReader, *inCollection, "actor1", actor1 ); + inReader.leaveChild(); + } + TJointType* theJoint = !ok ? NULL : createJoint<TJointType>( inArgs.physics, actor0, localPose0, actor1, localPose1 ); + + if ( theJoint ) + { + PxConstraint* constraint = theJoint->getConstraint(); + PX_ASSERT( constraint ); + inCollection->add( *constraint ); + this->fileToObjectImpl( theJoint, inReader, inAllocator, inArgs, inCollection ); + } + return PxCreateRepXObject(theJoint); + } + + template<typename TJointType> + void PxJointRepXSerializer<TJointType>::objectToFileImpl( const TJointType* inObj, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& ) + { + writeAllProperties( inObj, inWriter, inTempBuffer, *inCollection ); + } + + // explicit instantiations + template struct PxJointRepXSerializer<PxFixedJoint>; + template struct PxJointRepXSerializer<PxDistanceJoint>; + template struct PxJointRepXSerializer<PxD6Joint>; + template struct PxJointRepXSerializer<PxPrismaticJoint>; + template struct PxJointRepXSerializer<PxRevoluteJoint>; + template struct PxJointRepXSerializer<PxSphericalJoint>; +} diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnPxStreamOperators.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnPxStreamOperators.h new file mode 100644 index 00000000..efca5662 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnPxStreamOperators.h @@ -0,0 +1,134 @@ +// 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_PXSTREAMOPERATORS_H +#define PX_PXSTREAMOPERATORS_H + +#include "foundation/PxVec3.h" +#include "foundation/PxTransform.h" +#include "foundation/PxBounds3.h" +#include "PxFiltering.h" + +#include "PsString.h" + +namespace physx +{ + static inline PxU32 strLenght( const char* inStr ) + { + return inStr ? PxU32(strlen(inStr)) : 0; + } +} + +namespace physx // ADL requires we put the operators in the same namespace as the underlying type of PxOutputStream +{ + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const char* inString ) + { + if ( inString && *inString ) + { + ioStream.write( inString, PxU32(strlen(inString)) ); + } + return ioStream; + } + + template<typename TDataType> + inline PxOutputStream& toStream( PxOutputStream& ioStream, const char* inFormat, const TDataType inData ) + { + char buffer[128] = { 0 }; + Ps::snprintf( buffer, 128, inFormat, inData ); + ioStream << buffer; + return ioStream; + } + + struct endl_obj {}; + //static endl_obj endl; + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, bool inData ) { ioStream << (inData ? "true" : "false"); return ioStream; } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxI32 inData ) { return toStream( ioStream, "%d", inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxU16 inData ) { return toStream( ioStream, "%u", PxU32(inData) ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxU8 inData ) { return toStream( ioStream, "%u", PxU32(inData) ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, char inData ) { return toStream( ioStream, "%c", inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxU32 inData ) { return toStream( ioStream, "%u", inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxU64 inData ) { return toStream( ioStream, "%" PX_PRIu64, inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const void* inData ) { return ioStream << PX_PROFILE_POINTER_TO_U64( inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxF32 inData ) { return toStream( ioStream, "%g", PxF64(inData) ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, PxF64 inData ) { return toStream( ioStream, "%g", inData ); } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, endl_obj) { return ioStream << "\n"; } + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const PxVec3& inData ) + { + ioStream << inData[0]; + ioStream << " "; + ioStream << inData[1]; + ioStream << " "; + ioStream << inData[2]; + return ioStream; + } + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const PxQuat& inData ) + { + ioStream << inData.x; + ioStream << " "; + ioStream << inData.y; + ioStream << " "; + ioStream << inData.z; + ioStream << " "; + ioStream << inData.w; + return ioStream; + } + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const PxTransform& inData ) + { + ioStream << inData.q; + ioStream << " "; + ioStream << inData.p; + return ioStream; + } + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const PxBounds3& inData ) + { + ioStream << inData.minimum; + ioStream << " "; + ioStream << inData.maximum; + return ioStream; + } + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, const PxFilterData& inData ) + { + ioStream << inData.word0 << " " << inData.word1 << " " << inData.word2 << " " << inData.word3; + return ioStream; + } + + inline PxOutputStream& operator << ( PxOutputStream& ioStream, struct PxMetaDataPlane& inData ) + { + ioStream << inData.normal; + ioStream << " "; + ioStream << inData.distance; + return ioStream; + } +} + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX1_0Defaults.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX1_0Defaults.h new file mode 100644 index 00000000..31ad950e --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX1_0Defaults.h @@ -0,0 +1,245 @@ +// 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. + + DEFINE_REPX_DEFAULT_PROPERTY("PxBoxGeometry.HalfExtents", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphereGeometry.Radius", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.ConvexMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.MeshFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.TriangleMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightField", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.RowScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.ColumnScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightFieldFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Length", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Mass", "1000" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Speed", "10" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DynamicFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.StaticFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DynamicFrictionV", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.StaticFrictionV", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DirOfAnisotropy", "1 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.FrictionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.RestitutionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.LocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.SimulationFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.QueryFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.ContactOffset", "0.02" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.RestOffset", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Flags", "eSIMULATION_SHAPE|eSCENE_QUERY_SHAPE|eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Mass", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MassSpaceInertiaTensor", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearDamping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularDamping", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MaxAngularVelocity", "7" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SleepEnergyThreshold", "0.005" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ContactReportThreshold", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.RigidDynamicFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ParentPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ChildPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetOrientation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.InternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ExternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.yLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.zLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.lower", "-0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.upper", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Mass", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.MassSpaceInertiaTensor", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.MaxProjectionIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SeparationTolerance", "0.1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.InternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.ExternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eX", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eY", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eZ", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eTWIST", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING1", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING2", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Value", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DrivePosition", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.linear", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.angular", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MinDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MaxDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Tolerance", "0.025" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.DistanceJointFlags", "eMAX_DISTANCE_ENABLED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveVelocity", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveGearRatio", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.RevoluteJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.ContactDistance", "0.01" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Upper", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Lower", "-3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.PrismaticJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.UserData", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.SphericalJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("THEEND", "false" ) diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_1Defaults.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_1Defaults.h new file mode 100644 index 00000000..a3e52a73 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_1Defaults.h @@ -0,0 +1,274 @@ +// 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. + + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Length", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Mass", "1000" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Speed", "10" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxBoxGeometry.HalfExtents", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphereGeometry.Radius", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.ConvexMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.MeshFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.TriangleMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightField", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.RowScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.ColumnScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightFieldFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DynamicFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.StaticFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DynamicFrictionV", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.StaticFrictionV", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DirOfAnisotropy", "1 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.FrictionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.RestitutionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.LocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.SimulationFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.QueryFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.ContactOffset", "0.02" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.RestOffset", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Flags", "eSIMULATION_SHAPE|eSCENE_QUERY_SHAPE|eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Mass", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MassSpaceInertiaTensor", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearDamping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularDamping", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MaxAngularVelocity", "7" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SleepThreshold", "0.005" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ContactReportThreshold", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.RigidDynamicFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ParentPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ChildPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetOrientation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.InternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ExternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.yLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.zLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TangentialSpring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TangentialDamping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimitContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.lower", "-0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.upper", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimitContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Mass", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.MassSpaceInertiaTensor", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.MaxProjectionIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SeparationTolerance", "0.1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.InternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.ExternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SleepThreshold", "0.005" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eX", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eY", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eZ", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eTWIST", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING1", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING2", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Value", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DrivePosition", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.linear", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.angular", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MinDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MaxDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Tolerance", "0.025" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.DistanceJointFlags", "eMAX_DISTANCE_ENABLED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveVelocity", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveGearRatio", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.RevoluteJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.ContactDistance", "0.01" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Upper", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Lower", "-3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.PrismaticJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.SphericalJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.MotionConstraintScaleBias.scale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.MotionConstraintScaleBias.bias", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ExternalAcceleration", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.DampingCoefficient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.SolverFrequency", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.SleepLinearVelocity", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("THEEND", "false" ) diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_2Defaults.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_2Defaults.h new file mode 100644 index 00000000..f3959504 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepX3_2Defaults.h @@ -0,0 +1,313 @@ +// 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. + + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Length", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Mass", "1000" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTolerancesScale.Speed", "10" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxBoxGeometry.HalfExtents", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphereGeometry.Radius", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxConvexMeshGeometry.ConvexMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Scale", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.Scale.Rotation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.MeshFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxTriangleMeshGeometry.TriangleMesh", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightField", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.RowScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.ColumnScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxHeightFieldGeometry.HeightFieldFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.DynamicFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.StaticFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.FrictionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxMaterial.RestitutionCombineMode", "eAVERAGE" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.LocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.SimulationFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.QueryFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.ContactOffset", "0.02" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.RestOffset", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Flags", "eSIMULATION_SHAPE|eSCENE_QUERY_SHAPE|eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxShape.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidStatic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.Mass", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MassSpaceInertiaTensor", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.LinearDamping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.AngularDamping", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.MaxAngularVelocity", "7" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SleepThreshold", "0.005" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.ContactReportThreshold", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRigidDynamic.RigidDynamicFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ParentPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ChildPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetOrientation", "0 0 0 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TargetVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.InternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.ExternalCompliance", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.yLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimit.zLimit", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TangentialSpring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TangentialDamping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimitContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.SwingLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.lower", "-0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimit.upper", "0.78539816339" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimitEnabled", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationJoint.TwistLimitContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.CMassLocalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.Mass", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.MassSpaceInertiaTensor", "1 1 1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.LinearVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulationLink.AngularVelocity", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.MaxProjectionIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SeparationTolerance", "0.1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.InternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.ExternalDriveIterations", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minPositionIters", "4" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SolverIterationCounts.minVelocityIters", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.SleepThreshold", "0.005" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxArticulation.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eX", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eY", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eZ", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eTWIST", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING1", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Motion.eSWING2", "eLOCKED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.LinearLimit.Value", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.TwistLimit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.SwingLimit.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eX.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eY.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eZ.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSWING.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eTWIST.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.ForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.Drive.eSLERP.Flags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DrivePosition", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.linear", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.DriveVelocity.angular", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxD6Joint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxFixedJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MinDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.MaxDistance", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Tolerance", "0.025" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxDistanceJoint.DistanceJointFlags", "eMAX_DISTANCE_ENABLED" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Upper", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.Limit.Lower", "-1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveVelocity", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveForceLimit", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.DriveGearRatio", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.RevoluteJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxRevoluteJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.ContactDistance", "0.01" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Upper", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.Limit.Lower", "-3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.PrismaticJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxPrismaticJoint.ProjectionAngularTolerance", "3.14159" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Actors.actor0", "8887040" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Actors.actor1", "8887456" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LocalPose.eACTOR0", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LocalPose.eACTOR1", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.force", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.BreakForce.torque", "3.40282e+038" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ConstraintFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Restitution", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Spring", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ContactDistance", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.YAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.LimitCone.ZAngle", "1.5708" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.SphericalJointFlags", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxSphericalJoint.ProjectionLinearTolerance", "1e+010" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.Name", "" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ClientBehaviorBits", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.MotionConstraintScaleBias.scale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.MotionConstraintScaleBias.bias", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.GlobalPose", "0 0 0 1 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.ExternalAcceleration", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.DampingCoefficient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.SolverFrequency", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.SleepLinearVelocity", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.InertiaScale", "1" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.FrictionCoefficient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.DragCoefficient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxCloth.CollisionMassScale", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ExternalAcceleration", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ParticleMass", "0.001" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.Restitution", "0.5" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.DynamicFriction", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.StaticFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.SimulationFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.MaxMotionDistance", "0.06" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.RestOffset", "0.004" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ContactOffset", "0.008" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.GridSize", "0.96" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ProjectionPlane", "0 0 1 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ParticleReadDataFlags", "ePOSITION_BUFFER|eFLAGS_BUFFER" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleSystem.ParticleBaseFlags", "eCOLLISION_WITH_DYNAMIC_ACTORS|eENABLED|ePER_PARTICLE_REST_OFFSET|ePER_PARTICLE_COLLISION_CACHE_HINT") + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ActorFlags", "eVISUALIZATION" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.DominanceGroup", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.OwnerClient", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.Damping", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ExternalAcceleration", "0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ParticleMass", "0.001" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.Restitution", "0.5" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.DynamicFriction", "0.05" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.StaticFriction", "0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.SimulationFilterData", "0 0 0 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.MaxMotionDistance", "0.06" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.RestOffset", "0.004" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ContactOffset", "0.008" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.GridSize", "0.64" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ProjectionPlane", "0 0 1 0" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.Stiffness", "20" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.Viscosity", "6" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.RestParticleDistance", "0.02" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ParticleReadDataFlags", "ePOSITION_BUFFER|eFLAGS_BUFFER" ) + DEFINE_REPX_DEFAULT_PROPERTY("PxParticleFluid.ParticleBaseFlags", "eCOLLISION_WITH_DYNAMIC_ACTORS|eENABLED|ePER_PARTICLE_REST_OFFSET|ePER_PARTICLE_COLLISION_CACHE_HINT") + DEFINE_REPX_DEFAULT_PROPERTY("PxAggregate.SelfCollision", "false" ) + DEFINE_REPX_DEFAULT_PROPERTY("THEEND", "false" ) diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCollection.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCollection.h new file mode 100644 index 00000000..b479754d --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCollection.h @@ -0,0 +1,173 @@ +// 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_REPXCOLLECTION_H +#define PX_REPXCOLLECTION_H + +#include "common/PxTolerancesScale.h" +#include "PxRepXSerializer.h" + +namespace physx { namespace Sn { + + struct XmlNode; + + struct RepXCollectionItem + { + PxRepXObject liveObject; + XmlNode* descriptor; + RepXCollectionItem( PxRepXObject inItem = PxRepXObject(), XmlNode* inDescriptor = NULL ) + : liveObject( inItem ) + , descriptor( inDescriptor ) + { + } + }; + + struct RepXDefaultEntry + { + const char* name; + const char* value; + RepXDefaultEntry( const char* pn, const char* val ) : name( pn ), value( val ){} + }; + + /** + * The result of adding an object to the collection. + */ + struct RepXAddToCollectionResult + { + enum Enum + { + Success, + SerializerNotFound, + InvalidParameters, //Null data passed in. + AlreadyInCollection + }; + + PxSerialObjectId collectionId; + Enum result; + + RepXAddToCollectionResult( Enum inResult = Success, const PxSerialObjectId inId = 0 ) + : collectionId( inId ) + , result( inResult ) + { + } + bool isValid() { return result == Success && collectionId != 0; } + }; + /** + * A RepX collection contains a set of static data objects that can be transformed + * into live objects. It uses RepX serializer to do two transformations: + * live object <-> collection object (descriptor) + * collection object <-> file system. + * + * A live object is considered to be something live in the physics + * world such as a material or a rigidstatic. + * + * A collection object is a piece of data from which a live object + * of identical characteristics can be created. + * + * Clients need to pass PxCollection so that objects can resolve + * references. In addition, objects must be added in an order such that + * references can be resolved in the first place. So objects must be added + * to the collection *after* objects they are dependent upon. + * + * When deserializing from a file, the collection will allocate char*'s that will + * not be freed when the collection itself is freed. The user must be responsible + * for these character allocations. + */ + class RepXCollection + { + protected: + virtual ~RepXCollection(){} + + public: + virtual void destroy() = 0; + + /** + * Set the scale on this collection. The scale is saved with the collection. + * + * If the scale wasn't set, it will be invalid. + */ + virtual void setTolerancesScale( const PxTolerancesScale& inScale ) = 0; + + /** + * Get the scale that was set at collection creation time or at load time. + * If this is a loaded file and the source data does not contain a scale + * this value will be invalid (PxTolerancesScale::isValid()). + */ + virtual PxTolerancesScale getTolerancesScale() const = 0; + + /** + * Set the up vector on this collection. The up vector is saved with the collection. + * + * If the up vector wasn't set, it will be (0,0,0). + */ + virtual void setUpVector( const PxVec3& inUpVector ) = 0; + + /** + * If the up vector wasn't set, it will be (0,0,0). Else this will be the up vector + * optionally set when the collection was created. + */ + virtual PxVec3 getUpVector() const = 0; + + virtual const char* getVersion() = 0; + static const char* getLatestVersion(); + + //Necessary accessor functions for translation/upgrading. + virtual const RepXCollectionItem* begin() const = 0; + virtual const RepXCollectionItem* end() const = 0; + + + //Performs a deep copy of the repx node. + virtual XmlNode* copyRepXNode( const XmlNode* srcNode ) = 0; + + virtual void addCollectionItem( RepXCollectionItem inItem ) = 0; + + //Create a new repx node with this name. Its value is unset. + virtual XmlNode& createRepXNode( const char* name ) = 0; + + virtual RepXCollection& createCollection( const char* inVersionStr ) = 0; + //Release this when finished. + virtual XmlReaderWriter& createNodeEditor() = 0; + + virtual PxAllocatorCallback& getAllocator() = 0; + + virtual bool instantiateCollection( PxRepXInstantiationArgs& inArgs, PxCollection& inPxCollection ) = 0; + + + virtual RepXAddToCollectionResult addRepXObjectToCollection( const PxRepXObject& inObject, PxCollection* inCollection, PxRepXInstantiationArgs& inArgs ) = 0; + + /** + * Save this collection out to a file stream. Uses the RepX serialize to perform + * collection object->file conversions. + * + * /param[in] inStream Write-only stream to save collection out to. + */ + virtual void save( PxOutputStream& inStream ) = 0; + }; +} } + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.cpp new file mode 100644 index 00000000..104e521c --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.cpp @@ -0,0 +1,1158 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PxPhysicsAPI.h" +#include "PxMetaDataObjects.h" +#include "CmIO.h" +#include "SnPxStreamOperators.h" +#include "PsUtilities.h" +#include "SnXmlImpl.h" +#include "SnXmlSerializer.h" +#include "SnXmlDeserializer.h" +#include "SnRepXCoreSerializer.h" + +using namespace physx::Sn; +namespace physx { + typedef PxProfileHashMap< const PxSerialObjectId, const PxArticulationLink* > TArticulationLinkLinkMap; + typedef PxReadOnlyPropertyInfo<PxPropertyInfoName::PxArticulationLink_InboundJoint, PxArticulationLink, PxArticulationJoint *> TIncomingJointPropType; + + //************************************************************* + // Actual RepXSerializer implementations for PxMaterial + //************************************************************* + PxMaterial* PxMaterialRepXSerializer::allocateObject( PxRepXInstantiationArgs& inArgs ) + { + return inArgs.physics.createMaterial(0, 0, 0); + } + + PxRepXObject PxShapeRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PxProfileAllocatorWrapper wrapper( inAllocator.getAllocator() ); + TReaderNameStack names( wrapper ); + PxProfileArray<PxU32> contexts( wrapper ); + bool hadError = false; + RepXVisitorReader<PxShape> theVisitor( names, contexts, inArgs, inReader, NULL, inAllocator, *inCollection, hadError ); + + Ps::Array<PxMaterial*> materials; + PxGeometry* geometry = NULL; + parseShape( theVisitor, geometry, materials ); + if(hadError) + return PxRepXObject(); + PxShape *theShape = inArgs.physics.createShape( *geometry, materials.begin(), Ps::to16(materials.size()) ); + + switch(geometry->getType()) + { + case PxGeometryType::eSPHERE : + static_cast<PxSphereGeometry*>(geometry)->~PxSphereGeometry(); + break; + case PxGeometryType::ePLANE : + static_cast<PxPlaneGeometry*>(geometry)->~PxPlaneGeometry(); + break; + case PxGeometryType::eCAPSULE : + static_cast<PxCapsuleGeometry*>(geometry)->~PxCapsuleGeometry(); + break; + case PxGeometryType::eBOX : + static_cast<PxBoxGeometry*>(geometry)->~PxBoxGeometry(); + break; + case PxGeometryType::eCONVEXMESH : + static_cast<PxConvexMeshGeometry*>(geometry)->~PxConvexMeshGeometry(); + break; + case PxGeometryType::eTRIANGLEMESH : + static_cast<PxTriangleMeshGeometry*>(geometry)->~PxTriangleMeshGeometry(); + break; + case PxGeometryType::eHEIGHTFIELD : + static_cast<PxHeightFieldGeometry*>(geometry)->~PxHeightFieldGeometry(); + break; + + case PxGeometryType::eGEOMETRY_COUNT: + case PxGeometryType::eINVALID: + PX_ASSERT(0); + } + inAllocator.getAllocator().deallocate(geometry); + + bool ret = readAllProperties( inArgs, inReader, theShape, inAllocator, *inCollection ); + + return ret ? PxCreateRepXObject(theShape) : PxRepXObject(); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxTriangleMesh + //************************************************************* + + template<typename TTriIndexElem> + inline void writeTriangle( MemoryBuffer& inTempBuffer, const Triangle<TTriIndexElem>& inTriangle ) + { + inTempBuffer << inTriangle.mIdx0 + << " " << inTriangle.mIdx1 + << " " << inTriangle.mIdx2; + } + + PxU32 materialAccess( const PxTriangleMesh* inMesh, PxU32 inIndex ) { return inMesh->getTriangleMaterialIndex( inIndex ); } + template<typename TDataType> + void writeDatatype( MemoryBuffer& inTempBuffer, const TDataType& inType ) { inTempBuffer << inType; } + + void PxBVH33TriangleMeshRepXSerializer::objectToFileImpl( const PxBVH33TriangleMesh* mesh, PxCollection* /*inCollection*/, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& inArgs ) + { + bool hasMatIndex = mesh->getTriangleMaterialIndex(0) != 0xffff; + PxU32 numVertices = mesh->getNbVertices(); + const PxVec3* vertices = mesh->getVertices(); + writeBuffer( inWriter, inTempBuffer, 2, vertices, numVertices, "Points", writePxVec3 ); + bool isU16 = mesh->getTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES ? true : false; + PxU32 triCount = mesh->getNbTriangles(); + const void* indices = mesh->getTriangles(); + if ( isU16 ) + writeBuffer( inWriter, inTempBuffer, 2, reinterpret_cast<const Triangle<PxU16>* >( indices ), triCount, "Triangles", writeTriangle<PxU16> ); + else + writeBuffer( inWriter, inTempBuffer, 2, reinterpret_cast<const Triangle<PxU32>* >( indices ), triCount, "Triangles", writeTriangle<PxU32> ); + if ( hasMatIndex ) + writeBuffer( inWriter, inTempBuffer, 6, mesh, materialAccess, triCount, "materialIndices", writeDatatype<PxU32> ); + + //Cooked stream + PxTriangleMeshDesc meshDesc; + meshDesc.points.count = numVertices; + meshDesc.points.data = vertices; + meshDesc.points.stride = sizeof(PxVec3); + meshDesc.triangles.count = triCount; + meshDesc.triangles.data = indices; + meshDesc.triangles.stride = isU16?3*sizeof(PxU16):3*sizeof(PxU32); + + if(isU16) + { + meshDesc.triangles.stride = sizeof(PxU16)*3; + meshDesc.flags |= PxMeshFlag::e16_BIT_INDICES; + } + else + { + meshDesc.triangles.stride = sizeof(PxU32)*3; + } + + if(hasMatIndex) + { + PxMaterialTableIndex* materialIndices = new PxMaterialTableIndex[triCount]; + for(PxU32 i = 0; i < triCount; i++) + materialIndices[i] = mesh->getTriangleMaterialIndex(i); + + meshDesc.materialIndices.data = materialIndices; + meshDesc.materialIndices.stride = sizeof(PxMaterialTableIndex); + + } + + if(inArgs.cooker != NULL) + { + TMemoryPoolManager theManager(mAllocator); + MemoryBuffer theTempBuf( &theManager ); + theTempBuf.clear(); + inArgs.cooker->cookTriangleMesh( meshDesc, theTempBuf ); + + writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype<PxU8> ); + } + + delete []meshDesc.materialIndices.data; + } + + PxRepXObject PxBVH33TriangleMeshRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* /*inCollection*/ ) + { + //We can't do a simple inverse; we *have* to cook data to get a mesh. + PxTriangleMeshDesc theDesc; + readStridedBufferProperty<PxVec3>( inReader, "points", theDesc.points, inAllocator); + readStridedBufferProperty<Triangle<PxU32> >( inReader, "triangles", theDesc.triangles, inAllocator); + PxU32 triCount; + readStridedBufferProperty<PxMaterialTableIndex>( inReader, "materialIndices", theDesc.materialIndices, triCount, inAllocator); + PxStridedData cookedData; + cookedData.stride = sizeof(PxU8); + PxU32 dataSize; + readStridedBufferProperty<PxU8>( inReader, "CookedData", cookedData, dataSize, inAllocator); + + TMemoryPoolManager theManager(inAllocator.getAllocator()); + MemoryBuffer theTempBuf( &theManager ); + +// PxTriangleMesh* theMesh = NULL; + PxBVH33TriangleMesh* theMesh = NULL; + + if(dataSize != 0) + { + theTempBuf.write(cookedData.data, dataSize*sizeof(PxU8)); +// theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); + theMesh = static_cast<PxBVH33TriangleMesh*>(inArgs.physics.createTriangleMesh( theTempBuf )); + } + + if(theMesh == NULL) + { + PX_ASSERT(inArgs.cooker); + theTempBuf.clear(); + + { + PxCookingParams params = inArgs.cooker->getParams(); + params.midphaseDesc = PxMeshMidPhase::eBVH33; + inArgs.cooker->setParams(params); + } + + inArgs.cooker->cookTriangleMesh( theDesc, theTempBuf ); +// theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); + theMesh = static_cast<PxBVH33TriangleMesh*>(inArgs.physics.createTriangleMesh( theTempBuf )); + } + + return PxCreateRepXObject( theMesh ); + } + + void PxBVH34TriangleMeshRepXSerializer::objectToFileImpl( const PxBVH34TriangleMesh* mesh, PxCollection* /*inCollection*/, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& inArgs ) + { + bool hasMatIndex = mesh->getTriangleMaterialIndex(0) != 0xffff; + PxU32 numVertices = mesh->getNbVertices(); + const PxVec3* vertices = mesh->getVertices(); + writeBuffer( inWriter, inTempBuffer, 2, vertices, numVertices, "Points", writePxVec3 ); + bool isU16 = mesh->getTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES ? true : false; + PxU32 triCount = mesh->getNbTriangles(); + const void* indices = mesh->getTriangles(); + if ( isU16 ) + writeBuffer( inWriter, inTempBuffer, 2, reinterpret_cast<const Triangle<PxU16>* >( indices ), triCount, "Triangles", writeTriangle<PxU16> ); + else + writeBuffer( inWriter, inTempBuffer, 2, reinterpret_cast<const Triangle<PxU32>* >( indices ), triCount, "Triangles", writeTriangle<PxU32> ); + if ( hasMatIndex ) + writeBuffer( inWriter, inTempBuffer, 6, mesh, materialAccess, triCount, "materialIndices", writeDatatype<PxU32> ); + + //Cooked stream + PxTriangleMeshDesc meshDesc; + meshDesc.points.count = numVertices; + meshDesc.points.data = vertices; + meshDesc.points.stride = sizeof(PxVec3); + meshDesc.triangles.count = triCount; + meshDesc.triangles.data = indices; + meshDesc.triangles.stride = isU16?3*sizeof(PxU16):3*sizeof(PxU32); + + if(isU16) + { + meshDesc.triangles.stride = sizeof(PxU16)*3; + meshDesc.flags |= PxMeshFlag::e16_BIT_INDICES; + } + else + { + meshDesc.triangles.stride = sizeof(PxU32)*3; + } + + if(hasMatIndex) + { + PxMaterialTableIndex* materialIndices = new PxMaterialTableIndex[triCount]; + for(PxU32 i = 0; i < triCount; i++) + materialIndices[i] = mesh->getTriangleMaterialIndex(i); + + meshDesc.materialIndices.data = materialIndices; + meshDesc.materialIndices.stride = sizeof(PxMaterialTableIndex); + + } + + if(inArgs.cooker != NULL) + { + TMemoryPoolManager theManager(mAllocator); + MemoryBuffer theTempBuf( &theManager ); + theTempBuf.clear(); + inArgs.cooker->cookTriangleMesh( meshDesc, theTempBuf ); + + writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype<PxU8> ); + } + + delete []meshDesc.materialIndices.data; + } + + PxRepXObject PxBVH34TriangleMeshRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* /*inCollection*/ ) + { + //We can't do a simple inverse; we *have* to cook data to get a mesh. + PxTriangleMeshDesc theDesc; + readStridedBufferProperty<PxVec3>( inReader, "points", theDesc.points, inAllocator); + readStridedBufferProperty<Triangle<PxU32> >( inReader, "triangles", theDesc.triangles, inAllocator); + PxU32 triCount; + readStridedBufferProperty<PxMaterialTableIndex>( inReader, "materialIndices", theDesc.materialIndices, triCount, inAllocator); + PxStridedData cookedData; + cookedData.stride = sizeof(PxU8); + PxU32 dataSize; + readStridedBufferProperty<PxU8>( inReader, "CookedData", cookedData, dataSize, inAllocator); + + TMemoryPoolManager theManager(inAllocator.getAllocator()); + MemoryBuffer theTempBuf( &theManager ); + +// PxTriangleMesh* theMesh = NULL; + PxBVH34TriangleMesh* theMesh = NULL; + + if(dataSize != 0) + { + theTempBuf.write(cookedData.data, dataSize*sizeof(PxU8)); +// theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); + theMesh = static_cast<PxBVH34TriangleMesh*>(inArgs.physics.createTriangleMesh( theTempBuf )); + } + + if(theMesh == NULL) + { + PX_ASSERT(inArgs.cooker); + theTempBuf.clear(); + + { + PxCookingParams params = inArgs.cooker->getParams(); + params.midphaseDesc = PxMeshMidPhase::eBVH34; + inArgs.cooker->setParams(params); + } + + inArgs.cooker->cookTriangleMesh( theDesc, theTempBuf ); +// theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); + theMesh = static_cast<PxBVH34TriangleMesh*>(inArgs.physics.createTriangleMesh( theTempBuf )); + } + + return PxCreateRepXObject(theMesh); + } + + + //************************************************************* + // Actual RepXSerializer implementations for PxHeightField + //************************************************************* + void PxHeightFieldRepXSerializer::objectToFileImpl( const PxHeightField* inHeightField, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + PxHeightFieldDesc theDesc; + + theDesc.nbRows = inHeightField->getNbRows(); + theDesc.nbColumns = inHeightField->getNbColumns(); + theDesc.format = inHeightField->getFormat(); + theDesc.samples.stride = inHeightField->getSampleStride(); + theDesc.samples.data = NULL; + theDesc.thickness = inHeightField->getThickness(); + theDesc.convexEdgeThreshold = inHeightField->getConvexEdgeThreshold(); + theDesc.flags = inHeightField->getFlags(); + + PxU32 theCellCount = inHeightField->getNbRows() * inHeightField->getNbColumns(); + PxU32 theSampleStride = sizeof( PxHeightFieldSample ); + PxU32 theSampleBufSize = theCellCount * theSampleStride; + PxHeightFieldSample* theSamples = reinterpret_cast< PxHeightFieldSample*> ( inTempBuffer.mManager->allocate( theSampleBufSize ) ); + inHeightField->saveCells( theSamples, theSampleBufSize ); + theDesc.samples.data = theSamples; + writeAllProperties( &theDesc, inWriter, inTempBuffer, *inCollection ); + writeStridedBufferProperty<PxHeightFieldSample>( inWriter, inTempBuffer, "samples", theDesc.samples, theDesc.nbRows * theDesc.nbColumns, 6, writeHeightFieldSample); + inTempBuffer.mManager->deallocate( reinterpret_cast<PxU8*>(theSamples) ); + } + + PxRepXObject PxHeightFieldRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PX_ASSERT(inArgs.cooker); + PxHeightFieldDesc theDesc; + readAllProperties( inArgs, inReader, &theDesc, inAllocator, *inCollection ); + //Now read the data... + PxU32 count = 0; //ignored becaues numRows and numColumns tells the story + readStridedBufferProperty<PxHeightFieldSample>( inReader, "samples", theDesc.samples, count, inAllocator); + PxHeightField* retval = inArgs.cooker->createHeightField( theDesc, inArgs.physics.getPhysicsInsertionCallback() ); + return PxCreateRepXObject(retval); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxConvexMesh + //************************************************************* + void PxConvexMeshRepXSerializer::objectToFileImpl( const PxConvexMesh* mesh, PxCollection* /*inCollection*/, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& inArgs ) + { + writeBuffer( inWriter, inTempBuffer, 2, mesh->getVertices(), mesh->getNbVertices(), "points", writePxVec3 ); + + if(inArgs.cooker != NULL) + { + //Cache cooked Data + PxConvexMeshDesc theDesc; + theDesc.points.data = mesh->getVertices(); + theDesc.points.stride = sizeof(PxVec3); + theDesc.points.count = mesh->getNbVertices(); + + theDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; + TMemoryPoolManager theManager(mAllocator); + MemoryBuffer theTempBuf( &theManager ); + inArgs.cooker->cookConvexMesh( theDesc, theTempBuf ); + + writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype<PxU8> ); + } + + } + + //Conversion from scene object to descriptor. + PxRepXObject PxConvexMeshRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* /*inCollection*/) + { + PxConvexMeshDesc theDesc; + readStridedBufferProperty<PxVec3>( inReader, "points", theDesc.points, inAllocator); + theDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; + + PxStridedData cookedData; + cookedData.stride = sizeof(PxU8); + PxU32 dataSize; + readStridedBufferProperty<PxU8>( inReader, "CookedData", cookedData, dataSize, inAllocator); + + TMemoryPoolManager theManager(inAllocator.getAllocator()); + MemoryBuffer theTempBuf( &theManager ); + + PxConvexMesh* theMesh = NULL; + + if(dataSize != 0) + { + theTempBuf.write(cookedData.data, dataSize*sizeof(PxU8)); + theMesh = inArgs.physics.createConvexMesh( theTempBuf ); + } + + if(theMesh == NULL) + { + PX_ASSERT(inArgs.cooker); + theTempBuf.clear(); + + inArgs.cooker->cookConvexMesh( theDesc, theTempBuf ); + theMesh = inArgs.physics.createConvexMesh( theTempBuf ); + } + + return PxCreateRepXObject(theMesh); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxRigidStatic + //************************************************************* + PxRigidStatic* PxRigidStaticRepXSerializer::allocateObject( PxRepXInstantiationArgs& inArgs ) + { + return inArgs.physics.createRigidStatic( PxTransform(PxIdentity) ); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxRigidDynamic + //************************************************************* + PxRigidDynamic* PxRigidDynamicRepXSerializer::allocateObject( PxRepXInstantiationArgs& inArgs ) + { + return inArgs.physics.createRigidDynamic( PxTransform(PxIdentity) ); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxArticulation + //************************************************************* + void PxArticulationRepXSerializer::objectToFileImpl( const PxArticulation* inObj, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + TNameStack nameStack( inTempBuffer.mManager->mWrapper ); + Sn::TArticulationLinkLinkMap linkMap( inTempBuffer.mManager->mWrapper ); + RepXVisitorWriter<PxArticulation> writer( nameStack, inWriter, inObj, inTempBuffer, *inCollection, &linkMap ); + RepXPropertyFilter<RepXVisitorWriter<PxArticulation> > theOp( writer ); + visitAllProperties<PxArticulation>( theOp ); + } + PxArticulation* PxArticulationRepXSerializer::allocateObject( PxRepXInstantiationArgs& inArgs ) { return inArgs.physics.createArticulation(); } + + //************************************************************* + // Actual RepXSerializer implementations for PxAggregate + //************************************************************* + void PxAggregateRepXSerializer::objectToFileImpl( const PxAggregate* data, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + PxArticulationLink *link = NULL; + inWriter.addAndGotoChild( "Actors" ); + for(PxU32 i = 0; i < data->getNbActors(); ++i) + { + PxActor* actor; + + if(data->getActors(&actor, 1, i)) + { + link = actor->is<PxArticulationLink>(); + } + + if(link && !link->getInboundJoint() ) + { + writeProperty( inWriter, *inCollection, inTempBuffer, "PxArticulationRef", &link->getArticulation()); + } + else if( !link ) + { + PxSerialObjectId theId = 0; + + theId = inCollection->getId( *actor ); + if( theId == 0 ) + theId = PX_PROFILE_POINTER_TO_U64( actor ); + + writeProperty( inWriter, *inCollection, inTempBuffer, "PxActorRef", theId ); + } + } + + inWriter.leaveChild( ); + + writeProperty( inWriter, *inCollection, inTempBuffer, "NumActors", data->getNbActors() ); + writeProperty( inWriter, *inCollection, inTempBuffer, "MaxNbActors", data->getMaxNbActors() ); + writeProperty( inWriter, *inCollection, inTempBuffer, "SelfCollision", data->getSelfCollision() ); + + writeAllProperties( data, inWriter, inTempBuffer, *inCollection ); + } + + PxRepXObject PxAggregateRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PxU32 numActors; + readProperty( inReader, "NumActors", numActors ); + PxU32 maxNbActors; + readProperty( inReader, "MaxNbActors", maxNbActors ); + + bool selfCollision; + bool ret = readProperty( inReader, "SelfCollision", selfCollision ); + + PxAggregate* theAggregate = inArgs.physics.createAggregate(maxNbActors, selfCollision); + ret &= readAllProperties( inArgs, inReader, theAggregate, inAllocator, *inCollection ); + + inReader.pushCurrentContext(); + if ( inReader.gotoChild( "Actors" ) ) + { + inReader.pushCurrentContext(); + for( bool matSuccess = inReader.gotoFirstChild(); matSuccess; + matSuccess = inReader.gotoNextSibling() ) + { + const char* actorType = inReader.getCurrentItemName(); + if ( 0 == physx::shdfnd::stricmp( actorType, "PxActorRef" ) ) + { + PxActor *actor = NULL; + ret &= readReference<PxActor>( inReader, *inCollection, actor ); + + if(actor) + { + PxScene *currScene = actor->getScene(); + if(currScene) + { + currScene->removeActor(*actor); + } + theAggregate->addActor(*actor); + } + } + else if ( 0 == physx::shdfnd::stricmp( actorType, "PxArticulationRef" ) ) + { + PxArticulation* articulation = NULL; + ret &= readReference<PxArticulation>( inReader, *inCollection, articulation ); + if(articulation) + { + PxScene *currScene = articulation->getScene(); + if(currScene) + { + currScene->removeArticulation(*articulation); + } + theAggregate->addArticulation(*articulation); + } + } + } + inReader.popCurrentContext(); + inReader.leaveChild(); + } + inReader.popCurrentContext(); + + return ret ? PxCreateRepXObject(theAggregate) : PxRepXObject(); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxClothFabric + //************************************************************* +#if PX_USE_CLOTH_API + + void writeFabricPhase( PxOutputStream& stream, const PxClothFabricPhase& phase ) + { + const PxU32ToName* conv = PxEnumTraits<PxClothFabricPhaseType::Enum>().NameConversion; + for ( ; conv->mName != NULL; ++conv ) + if ( conv->mValue == PxU32(phase.phaseType) ) + stream << conv->mName; + stream << " " << phase.setIndex; + } + + namespace Sn { + template<> struct StrToImpl<PxClothFabricPhase> + { + void strto( PxClothFabricPhase& datatype, const char*& ioData ) + { + char buffer[512]; + eatwhite( ioData ); + nullTerminateWhite(ioData, buffer, 512 ); + + const PxU32ToName* conv = PxEnumTraits<PxClothFabricPhaseType::Enum>().NameConversion; + for ( ; conv->mName != NULL; ++conv ) + if ( 0 == physx::shdfnd::stricmp( buffer, conv->mName ) ) + datatype = static_cast<PxClothFabricPhaseType::Enum>( conv->mValue ); + + StrToImpl<PxU32>().strto( datatype.setIndex, ioData ); + } + }; + } + + void PxClothFabricRepXSerializer::objectToFileImpl( const PxClothFabric* data, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + + PxProfileAllocatorWrapper& wrapper( inTempBuffer.mManager->getWrapper() ); + PxU32 numParticles = data->getNbParticles(); + PxU32 numPhases = data->getNbPhases(); + PxU32 numRestvalues = data->getNbRestvalues(); + PxU32 numSets = data->getNbSets(); + PxU32 numIndices = data->getNbParticleIndices(); + PxU32 numTethers = data->getNbTethers(); + + PxProfileArray<PxU8> dataBuffer( wrapper ); + PxU32 numInts = PxMax(PxMax(numIndices, numRestvalues), numTethers); + dataBuffer.resize( PxU32(PxMax( PxMax( numInts * sizeof(PxU32), numTethers * sizeof(PxReal) ), + numPhases * sizeof(PxClothFabricPhase)) ) ); + + PxClothFabricPhase* phasePtr( reinterpret_cast<PxClothFabricPhase*>( dataBuffer.begin() ) ); + PxU32* indexPtr( reinterpret_cast<PxU32*>( dataBuffer.begin() ) ); + + writeProperty( inWriter, *inCollection, inTempBuffer, "NbParticles", numParticles ); + + data->getPhases( phasePtr, numPhases ); + writeBuffer( inWriter, inTempBuffer, 18, phasePtr, PtrAccess<PxClothFabricPhase>, numPhases, "Phases", writeFabricPhase ); + + PX_COMPILE_TIME_ASSERT( sizeof( PxReal ) == sizeof( PxU32 ) ); + PxReal* realPtr = reinterpret_cast< PxReal* >( indexPtr ); + data->getRestvalues( realPtr, numRestvalues ); + writeBuffer( inWriter, inTempBuffer, 18, realPtr, PtrAccess<PxReal>, numRestvalues, "Restvalues", BasicDatatypeWrite<PxReal> ); + + data->getSets( indexPtr, numSets ); + writeBuffer( inWriter, inTempBuffer, 18, indexPtr, PtrAccess<PxU32>, numSets, "Sets", BasicDatatypeWrite<PxU32> ); + + data->getParticleIndices( indexPtr, numIndices ); + writeBuffer( inWriter, inTempBuffer, 18, indexPtr, PtrAccess<PxU32>, numIndices, "ParticleIndices", BasicDatatypeWrite<PxU32> ); + + data->getTetherAnchors( indexPtr, numTethers ); + writeBuffer( inWriter, inTempBuffer, 18, indexPtr, PtrAccess<PxU32>, numTethers, "TetherAnchors", BasicDatatypeWrite<PxU32> ); + + data->getTetherLengths( realPtr, numTethers ); + writeBuffer( inWriter, inTempBuffer, 18, realPtr, PtrAccess<PxReal>, numTethers, "TetherLengths", BasicDatatypeWrite<PxReal> ); + } + + //Conversion from scene object to descriptor. + PxRepXObject PxClothFabricRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* /*inCollection*/) + { + PxU32 strideIgnored = 0; + + PxClothFabricDesc desc; + + readProperty( inReader, "NbParticles", desc.nbParticles ); + + readStridedBufferProperty<PxClothFabricPhase>( inReader, "Phases", const_cast<PxClothFabricPhase*&>(desc.phases), strideIgnored, desc.nbPhases, inAllocator ); + + PxU32 numRestvalues = 0; + readStridedBufferProperty<PxF32>( inReader, "Restvalues", const_cast<PxF32*&>(desc.restvalues), strideIgnored, numRestvalues, inAllocator ); + + readStridedBufferProperty<PxU32>( inReader, "Sets", const_cast<PxU32*&>(desc.sets), strideIgnored, desc.nbSets, inAllocator ); + + PxU32 numIndices = 0; + readStridedBufferProperty<PxU32>( inReader, "ParticleIndices", const_cast<PxU32*&>(desc.indices), strideIgnored, numIndices, inAllocator ); + + readStridedBufferProperty<PxU32>( inReader, "TetherAnchors", const_cast<PxU32*&>(desc.tetherAnchors), strideIgnored, desc.nbTethers, inAllocator ); + readStridedBufferProperty<PxF32>( inReader, "TetherLengths", const_cast<PxF32*&>(desc.tetherLengths), strideIgnored, desc.nbTethers, inAllocator ); + + PxClothFabric* newFabric = inArgs.physics.createClothFabric( desc ); + + PX_ASSERT( newFabric ); + return PxCreateRepXObject(newFabric); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxCloth + //************************************************************* + void clothParticleWriter( PxOutputStream& stream, const PxClothParticle& particle ) + { + stream << particle.pos << " " << particle.invWeight; + } + + namespace Sn { + template<> struct StrToImpl<PxClothParticle> + { + void strto( PxClothParticle& datatype, const char*& ioData ) + { + StrToImpl<PxF32>().strto( datatype.pos[0], ioData ); + StrToImpl<PxF32>().strto( datatype.pos[1], ioData ); + StrToImpl<PxF32>().strto( datatype.pos[2], ioData ); + StrToImpl<PxF32>().strto( datatype.invWeight, ioData ); + } + }; + + template<> struct StrToImpl<PxClothCollisionSphere> + { + void strto( PxClothCollisionSphere& datatype, const char*& ioData ) + { + StrToImpl<PxF32>().strto( datatype.pos[0], ioData ); + StrToImpl<PxF32>().strto( datatype.pos[1], ioData ); + StrToImpl<PxF32>().strto( datatype.pos[2], ioData ); + StrToImpl<PxF32>().strto( datatype.radius, ioData ); + } + }; + + template<> struct StrToImpl<PxClothCollisionPlane> + { + void strto( PxClothCollisionPlane& datatype, const char*& ioData ) + { + StrToImpl<PxF32>().strto( datatype.normal[0], ioData ); + StrToImpl<PxF32>().strto( datatype.normal[1], ioData ); + StrToImpl<PxF32>().strto( datatype.normal[2], ioData ); + StrToImpl<PxF32>().strto( datatype.distance, ioData ); + } + }; + + template<> struct StrToImpl<PxClothCollisionTriangle> + { + void strto( PxClothCollisionTriangle& datatype, const char*& ioData ) + { + StrToImpl<PxVec3>().strto( datatype.vertex0, ioData ); + StrToImpl<PxVec3>().strto( datatype.vertex1, ioData ); + StrToImpl<PxVec3>().strto( datatype.vertex2, ioData ); + } + }; + + template<> struct StrToImpl<PxVec4> + { + void strto( PxVec4& datatype, const char*& ioData ) + { + StrToImpl<PxF32>().strto( datatype.x, ioData ); + StrToImpl<PxF32>().strto( datatype.y, ioData ); + StrToImpl<PxF32>().strto( datatype.z, ioData ); + StrToImpl<PxF32>().strto( datatype.w, ioData ); + } + }; + + template<> struct StrToImpl<PxClothParticleMotionConstraint> + { + void strto( PxClothParticleMotionConstraint& datatype, const char*& ioData ) + { + StrToImpl<PxVec3>().strto( datatype.pos, ioData ); + StrToImpl<PxF32>().strto( datatype.radius, ioData ); + } + }; + + template<> struct StrToImpl<PxClothParticleSeparationConstraint> + { + void strto( PxClothParticleSeparationConstraint& datatype, const char*& ioData ) + { + StrToImpl<PxVec3>().strto( datatype.pos, ioData ); + StrToImpl<PxF32>().strto( datatype.radius, ioData ); + } + }; + + } + + void clothSphereWriter( PxOutputStream& stream, const PxClothCollisionSphere& sphere ) + { + stream << sphere.pos << " " << sphere.radius; + } + + void clothPlaneWriter( PxOutputStream& stream, const PxClothCollisionPlane& plane ) + { + stream << plane.normal << " " << plane.distance; + } + + void clothTriangleWriter( PxOutputStream& stream, const PxClothCollisionTriangle& triangle ) + { + stream << triangle.vertex0 << " " << triangle.vertex1 << " " << triangle.vertex2; + } + + void PxClothRepXSerializer::objectToFileImpl( const PxCloth* data, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + PxClothParticleData* readData( data->lockParticleData() ); + writeBuffer( inWriter, inTempBuffer, 4, readData->particles, PtrAccess<PxClothParticle>, data->getNbParticles(), "Particles", clothParticleWriter ); + readData->unlock(); + + writeReference( inWriter, *inCollection, "Fabric", data->getFabric() ); + + PxProfileArray<PxU8> dataBuffer( inTempBuffer.mManager->getWrapper() ); + + // collision data + const PxCloth& cloth = *data; + PxU32 numSpheres = cloth.getNbCollisionSpheres(); + PxU32 numIndices = 2*cloth.getNbCollisionCapsules(); + PxU32 numPlanes = cloth.getNbCollisionPlanes(); + PxU32 numConvexes = cloth.getNbCollisionConvexes(); + PxU32 numTriangles = cloth.getNbCollisionTriangles(); + + PxU32 sphereBytes = numSpheres * sizeof( PxClothCollisionSphere ); + PxU32 pairBytes = numIndices * sizeof( PxU32 ); + PxU32 planesBytes = numPlanes * sizeof(PxClothCollisionPlane); + PxU32 convexBytes = numConvexes * sizeof(PxU32); + PxU32 triangleBytes = numTriangles * sizeof(PxClothCollisionTriangle); + + dataBuffer.resize( sphereBytes + pairBytes + planesBytes + convexBytes + triangleBytes); + PxClothCollisionSphere* spheresBuffer = reinterpret_cast<PxClothCollisionSphere*>( dataBuffer.begin() ); + PxU32* indexBuffer = reinterpret_cast<PxU32*>(spheresBuffer + numSpheres); + PxClothCollisionPlane* planeBuffer = reinterpret_cast<PxClothCollisionPlane*>(indexBuffer + numIndices); + PxU32* convexBuffer = reinterpret_cast<PxU32*>(planeBuffer + numPlanes); + PxClothCollisionTriangle* trianglesBuffer = reinterpret_cast<PxClothCollisionTriangle*>(convexBuffer + numConvexes); + + data->getCollisionData( spheresBuffer, indexBuffer, planeBuffer, convexBuffer, trianglesBuffer ); + writeBuffer( inWriter, inTempBuffer, 4, spheresBuffer, PtrAccess<PxClothCollisionSphere>, numSpheres, "CollisionSpheres", clothSphereWriter ); + writeBuffer( inWriter, inTempBuffer, 18, indexBuffer, PtrAccess<PxU32>, numIndices, "CollisionSpherePairs", BasicDatatypeWrite<PxU32> ); + writeBuffer( inWriter, inTempBuffer, 4, planeBuffer, PtrAccess<PxClothCollisionPlane>, numPlanes, "CollisionPlanes", clothPlaneWriter ); + writeBuffer( inWriter, inTempBuffer, 18, convexBuffer, PtrAccess<PxU32>, numConvexes, "CollisionConvexMasks", BasicDatatypeWrite<PxU32> ); + writeBuffer( inWriter, inTempBuffer, 4, trianglesBuffer, PtrAccess<PxClothCollisionTriangle>, numTriangles, "CollisionTriangles", clothTriangleWriter ); + + // particle accelerations + PxU32 numParticleAccelerations = cloth.getNbParticleAccelerations(); + PxU32 sizeParticleAccelerations = sizeof(PxVec4)*numParticleAccelerations; + if (dataBuffer.size() < sizeParticleAccelerations) + dataBuffer.resize(sizeof(PxClothParticle)*numParticleAccelerations); + + PxVec4* particleAccelerations = reinterpret_cast<PxVec4*>(dataBuffer.begin()); + cloth.getParticleAccelerations(particleAccelerations); + writeBuffer (inWriter, inTempBuffer, 4, reinterpret_cast<PxClothParticle*>(particleAccelerations), PtrAccess<PxClothParticle>, numParticleAccelerations, "ParticleAccelerations", clothParticleWriter ); + + //self collision indices + PxU32* particleCollisionIndices = reinterpret_cast<PxU32*>(dataBuffer.begin()); + PxU32 numSelfCollisionIndices = cloth.getNbSelfCollisionIndices(); + PxU32 sizeSelfCollisionIndices = sizeof(PxU32)*numSelfCollisionIndices; + if (dataBuffer.size() < sizeSelfCollisionIndices) + dataBuffer.resize(sizeSelfCollisionIndices); + data->getSelfCollisionIndices( particleCollisionIndices ); + writeBuffer( inWriter, inTempBuffer, 18, particleCollisionIndices, PtrAccess<PxU32>, numSelfCollisionIndices, "SelfCollisionIndices", BasicDatatypeWrite<PxU32> ); + + // motion constraints + PxClothParticleMotionConstraint* motionConstraints = reinterpret_cast<PxClothParticleMotionConstraint*>(dataBuffer.begin()); + PxU32 numMotionConstraints = cloth.getNbMotionConstraints(); + PxU32 sizeMotionConstraints = sizeof(PxVec4)*numMotionConstraints; + if (dataBuffer.size() < sizeMotionConstraints) + dataBuffer.resize(sizeof(PxClothParticle)*numMotionConstraints); + data->getMotionConstraints( motionConstraints ); + writeBuffer (inWriter, inTempBuffer, 4, reinterpret_cast<PxClothParticle*>(motionConstraints), PtrAccess<PxClothParticle>, numMotionConstraints, "MotionConstraints", clothParticleWriter ); + + // separation positions + PxU32 numSeparationConstraints= cloth.getNbSeparationConstraints(); + PxU32 restSeparationConstraints = sizeof(PxVec4)*numSeparationConstraints; + if (dataBuffer.size() < restSeparationConstraints) + dataBuffer.resize(sizeof(PxClothParticle)*numSeparationConstraints); + PxClothParticleSeparationConstraint* separationConstraints = reinterpret_cast<PxClothParticleSeparationConstraint*>(dataBuffer.begin()); + cloth.getSeparationConstraints(separationConstraints); + writeBuffer (inWriter, inTempBuffer, 4, reinterpret_cast<PxClothParticle*>(separationConstraints), PtrAccess<PxClothParticle>, numSeparationConstraints, "SeparationConstraints", clothParticleWriter ); + + // rest positions + PxU32 numRestPositions = cloth.getNbRestPositions(); + PxU32 restPositionSize = sizeof(PxVec4)*numRestPositions; + if (dataBuffer.size() < restPositionSize) + dataBuffer.resize(sizeof(PxClothParticle)*numRestPositions); + + PxVec4* restPositions = reinterpret_cast<PxVec4*>(dataBuffer.begin()); + cloth.getRestPositions(restPositions); + writeBuffer (inWriter, inTempBuffer, 4, reinterpret_cast<PxClothParticle*>(restPositions), PtrAccess<PxClothParticle>, numRestPositions, "RestPositions", clothParticleWriter ); + + // virtual particles + PxU32 numVirtualParticles = data->getNbVirtualParticles(); + PxU32 numWeightTableEntries = data->getNbVirtualParticleWeights(); + + PxU32 totalNeeded = static_cast<PxU32>( PxMax( numWeightTableEntries * sizeof( PxVec3 ), numVirtualParticles * 4 * sizeof( PxU32 ) ) ); + if ( dataBuffer.size() < totalNeeded ) + dataBuffer.resize( totalNeeded ); + + PxVec3* weightTableEntries = reinterpret_cast<PxVec3*>( dataBuffer.begin() ); + data->getVirtualParticleWeights( weightTableEntries ); + writeBuffer( inWriter, inTempBuffer, 6, weightTableEntries, PtrAccess<PxVec3>, numWeightTableEntries, "VirtualParticleWeights", BasicDatatypeWrite<PxVec3> ); + PxU32* virtualParticles = reinterpret_cast<PxU32*>( dataBuffer.begin() ); + data->getVirtualParticles( virtualParticles ); + writeBuffer( inWriter, inTempBuffer, 18, virtualParticles, PtrAccess<PxU32>, numVirtualParticles * 4, "VirtualParticles", BasicDatatypeWrite<PxU32> ); + + // Now write the rest of the object data that the meta data generator got. + writeAllProperties( data, inWriter, inTempBuffer, *inCollection ); + } + + PxRepXObject PxClothRepXSerializer::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PxU32 strideIgnored; + PxU32 numParticles; + PxClothParticle* particles = NULL; + + PxU32 numSpheres; + PxClothCollisionSphere* spheres = NULL; + PxU32 numCapsules; + PxU32* capsules = NULL; + PxU32 numPlanes; + PxClothCollisionPlane* planes = NULL; + PxU32 numConvexMasks; + PxU32* convexMasks = NULL; + PxU32 numTriangles; + PxClothCollisionTriangle* triangles = NULL; + + PxVec4* particleAccelerations = NULL; + PxU32 numParticleAccelerations = 0; + PxU32* selfCollisionIndices = NULL; + PxU32 numSelfCollisionIndices = 0; + PxClothParticleMotionConstraint* particleMotionConstraint = NULL; + PxU32 numParticleMotionConstraint = 0; + PxClothParticleSeparationConstraint* separationConstraints = NULL; + PxU32 numSeparationConstraints = 0; + + PxVec4* restPositions = NULL; + PxU32 numRestPositions; + PxU32 numVirtualParticleWeights; + PxU32 numParticleIndices = 0; + PxVec3* virtualParticleWeights = NULL; + PxU32* virtualParticles = NULL; + PxClothFlags flags; + PxClothFabric* fabric = NULL; + + readReference<PxClothFabric>( inReader, *inCollection, "Fabric", fabric ); + + if ( fabric == NULL ) + return PxRepXObject(); + + readStridedBufferProperty<PxClothParticle>( inReader, "Particles", particles, strideIgnored, numParticles, inAllocator ); + + readStridedBufferProperty<PxClothCollisionSphere>( inReader, "CollisionSpheres", spheres, strideIgnored, numSpheres, inAllocator ); + readStridedBufferProperty<PxU32>( inReader, "CollisionSpherePairs", capsules, strideIgnored, numCapsules, inAllocator ); + readStridedBufferProperty<PxClothCollisionPlane>( inReader, "CollisionPlanes", planes, strideIgnored, numPlanes, inAllocator ); + readStridedBufferProperty<PxU32>( inReader, "CollisionConvexMasks", convexMasks, strideIgnored, numConvexMasks, inAllocator ); + readStridedBufferProperty<PxClothCollisionTriangle>( inReader, "CollisionTriangles", triangles, strideIgnored, numTriangles, inAllocator ); + + readFlagsProperty( inReader, inAllocator, "ClothFlags", PxEnumTraits<PxClothFlag::Enum>().NameConversion, flags ); + + readStridedBufferProperty<PxVec4>( inReader, "ParticleAccelerations", particleAccelerations, strideIgnored, numParticleAccelerations, inAllocator ); + readStridedBufferProperty<PxU32>( inReader, "SelfCollisionIndices", selfCollisionIndices, strideIgnored, numSelfCollisionIndices, inAllocator ); + readStridedBufferProperty<PxClothParticleMotionConstraint>( inReader, "MotionConstraints", particleMotionConstraint, strideIgnored, numParticleMotionConstraint, inAllocator ); + readStridedBufferProperty<PxClothParticleSeparationConstraint>( inReader, "SeparationConstraints", separationConstraints, strideIgnored, numSeparationConstraints, inAllocator ); + readStridedBufferProperty<PxVec4>( inReader, "RestPositions", restPositions, strideIgnored, numRestPositions, inAllocator ); + + readStridedBufferProperty<PxVec3>( inReader, "VirtualParticleWeights", virtualParticleWeights, strideIgnored, numVirtualParticleWeights, inAllocator ); + readStridedBufferProperty<PxU32>( inReader, "VirtualParticles", virtualParticles, strideIgnored, numParticleIndices, inAllocator ); + + PxTransform initialPose( PxIdentity ); + PxCloth* cloth = inArgs.physics.createCloth( initialPose, *fabric, reinterpret_cast<PxClothParticle*>( particles ), flags ); + bool ret = readAllProperties( inArgs, inReader, cloth, inAllocator, *inCollection ); + + if( numSelfCollisionIndices ) + { + cloth->setSelfCollisionIndices( selfCollisionIndices, numSelfCollisionIndices ); + } + if( numParticleMotionConstraint ) + { + cloth->setMotionConstraints( particleMotionConstraint ); + } + if( numSeparationConstraints ) + { + cloth->setSeparationConstraints( separationConstraints ); + } + if( numParticleAccelerations ) + { + cloth->setParticleAccelerations(particleAccelerations); + } + + cloth->setCollisionSpheres(spheres, numSpheres); + while(numCapsules > 0) + { + PxU32 first = *capsules++, second = *capsules++; + cloth->addCollisionCapsule(first, second); + numCapsules -= 2; + } + + cloth->setCollisionPlanes(planes, numPlanes); + while(numConvexMasks-- > 0) + { + cloth->addCollisionConvex(*convexMasks++); + } + + cloth->setCollisionTriangles(triangles, numTriangles); + + if (numRestPositions) + cloth->setRestPositions(restPositions); + + PxU32 numVirtualParticles = numParticleIndices /4; + if ( numVirtualParticles && numVirtualParticleWeights ) + { + cloth->setVirtualParticles( numVirtualParticles, reinterpret_cast<PxU32*>( virtualParticles ), + numVirtualParticleWeights, reinterpret_cast<PxVec3*>( virtualParticleWeights ) ); + } + + return ret ? PxCreateRepXObject(cloth) : PxRepXObject(); + } +#endif // PX_USE_CLOTH_API + +#if PX_USE_PARTICLE_SYSTEM_API + template<typename TParticleType> + inline TParticleType* createParticles( PxPhysics& physics, PxU32 maxParticles, bool perParticleRestOffset ) + { + PX_UNUSED(physics); + PX_UNUSED(maxParticles); + PX_UNUSED(perParticleRestOffset); + return NULL; + } + + template<> + inline PxParticleSystem* createParticles<PxParticleSystem>(PxPhysics& physics, PxU32 maxParticles, bool perParticleRestOffset) + { + return physics.createParticleSystem( maxParticles, perParticleRestOffset ); + } + + template<> + inline PxParticleFluid* createParticles<PxParticleFluid>(PxPhysics& physics, PxU32 maxParticles, bool perParticleRestOffset) + { + return physics.createParticleFluid( maxParticles, perParticleRestOffset ); + } + + //************************************************************* + // Actual RepXSerializer implementations for PxParticleSystem & PxParticleFluid + //************************************************************* + template<typename TParticleType> + void PxParticleRepXSerializer<TParticleType>::objectToFileImpl( const TParticleType* data, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + PxParticleReadData* readData( const_cast<TParticleType*>( data )->lockParticleReadData() ); + writeProperty( inWriter, *inCollection, inTempBuffer, "NbParticles", readData->nbValidParticles ); + writeProperty( inWriter, *inCollection, inTempBuffer, "ValidParticleRange", readData->validParticleRange ); + PxParticleReadDataFlags readFlags(data->getParticleReadDataFlags()); + + if(readData->validParticleRange > 0) + { + writeBuffer( inWriter, inTempBuffer, 8 , readData->validParticleBitmap, PtrAccess<PxU32>, ((readData->validParticleRange-1) >> 5) + 1 ,"ValidParticleBitmap", BasicDatatypeWrite<PxU32> ); + + writeStridedBufferProperty<PxVec3>( inWriter, inTempBuffer, "Positions", readData->positionBuffer, readData->nbValidParticles, 6, writePxVec3); + + if(readFlags & PxParticleReadDataFlag::eVELOCITY_BUFFER) + { + writeStridedBufferProperty<PxVec3>( inWriter, inTempBuffer, "Velocities", readData->velocityBuffer, readData->nbValidParticles, 6, writePxVec3); + } + if(readFlags & PxParticleReadDataFlag::eREST_OFFSET_BUFFER) + { + writeStridedBufferProperty<PxF32>( inWriter, inTempBuffer, "RestOffsets", readData->restOffsetBuffer, readData->nbValidParticles, 6, BasicDatatypeWrite<PxF32>); + } + if(readFlags & PxParticleReadDataFlag::eFLAGS_BUFFER) + { + writeStridedFlagsProperty<PxParticleFlags>( inWriter, inTempBuffer, "Flags", readData->flagsBuffer, readData->nbValidParticles, 6, PxEnumTraits<PxParticleFlag::Enum>().NameConversion); + } + } + readData->unlock(); + + writeProperty( inWriter, *inCollection, inTempBuffer, "MaxParticles", data->getMaxParticles() ); + + PxParticleBaseFlags baseFlags(data->getParticleBaseFlags()); + writeFlagsProperty( inWriter, inTempBuffer, "ParticleBaseFlags", baseFlags, PxEnumTraits<PxParticleBaseFlag::Enum>().NameConversion ); + + writeFlagsProperty( inWriter, inTempBuffer, "ParticleReadDataFlags", readFlags, PxEnumTraits<PxParticleReadDataFlag::Enum>().NameConversion ); + + PxVec3 normal; + PxReal distance; + data->getProjectionPlane(normal, distance); + PxMetaDataPlane plane(normal, distance); + writeProperty( inWriter, *inCollection, inTempBuffer, "ProjectionPlane", plane); + + writeAllProperties( data, inWriter, inTempBuffer, *inCollection ); + } + + template<typename TParticleType> + PxRepXObject PxParticleRepXSerializer<TParticleType>::fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + PxU32 strideIgnored = 0; + PxU32 numParticles = 0; + readProperty( inReader, "NbParticles", numParticles ); + + PxU32 validParticleRange = 0; + readProperty( inReader, "ValidParticleRange", validParticleRange ); + + PxU32 numWrite; + PxU32* tempValidParticleBitmap = NULL; + readStridedBufferProperty<PxU32>( inReader, "ValidParticleBitmap", tempValidParticleBitmap, strideIgnored, numWrite, inAllocator ); + PxU32 *validParticleBitmap = reinterpret_cast<PxU32*>( tempValidParticleBitmap ); + + PxVec3* tempPosBuf = NULL; + readStridedBufferProperty<PxVec3>( inReader, "Positions", tempPosBuf, strideIgnored, numWrite, inAllocator ); + PxStrideIterator<const PxVec3> posBuffer(reinterpret_cast<const PxVec3*> (tempPosBuf)); + + PxVec3* tempVelBuf = NULL; + readStridedBufferProperty<PxVec3>( inReader, "Velocities", tempVelBuf, strideIgnored, numWrite, inAllocator ); + PxStrideIterator<const PxVec3> velBuffer(reinterpret_cast<const PxVec3*> (tempVelBuf)); + + PxF32* tempRestBuf = NULL; + readStridedBufferProperty<PxF32>( inReader, "RestOffsets", tempRestBuf, strideIgnored, numWrite, inAllocator ); + PxStrideIterator<const PxF32> restBuffer(reinterpret_cast<const PxF32*> (tempRestBuf)); + + PxU32* tempFlagBuf = NULL; + readStridedFlagsProperty<PxU32>( inReader, "Flags", tempFlagBuf, strideIgnored, numWrite, inAllocator , PxEnumTraits<PxParticleFlag::Enum>().NameConversion); + PxStrideIterator<const PxU32> flagBuffer(reinterpret_cast<const PxU32*> (tempFlagBuf)); + + Ps::Array<PxU32> validIndexBuf; + Ps::Array<PxVec3> validPosBuf, validVelBuf; + Ps::Array<PxF32> validRestBuf; + Ps::Array<PxU32> validFlagBuf; + + bool perParticleRestOffset = !!tempRestBuf; + bool bVelBuff = !!tempVelBuf; + bool bFlagBuff = !!tempFlagBuf; + + if (validParticleRange > 0) + { + for (PxU32 w = 0; w <= (validParticleRange-1) >> 5; w++) + { + for (PxU32 b = validParticleBitmap[w]; b; b &= b-1) + { + PxU32 index = (w<<5|physx::shdfnd::lowestSetBit(b)); + validIndexBuf.pushBack(index); + validPosBuf.pushBack(posBuffer[index]); + if(bVelBuff) + validVelBuf.pushBack(velBuffer[index]); + if(perParticleRestOffset) + validRestBuf.pushBack(restBuffer[index]); + if(bFlagBuff) + validFlagBuf.pushBack(flagBuffer[index]); + } + } + + PX_ASSERT(validIndexBuf.size() == numParticles); + + PxU32 maxParticleNum; + bool ret = readProperty( inReader, "MaxParticles", maxParticleNum ); + TParticleType* theParticle( createParticles<TParticleType>( inArgs.physics, maxParticleNum, perParticleRestOffset ) ); + PX_ASSERT( theParticle ); + ret &= readAllProperties( inArgs, inReader, theParticle, inAllocator, *inCollection ); + + PxParticleBaseFlags baseFlags; + ret &= readFlagsProperty( inReader, inAllocator, "ParticleBaseFlags", PxEnumTraits<PxParticleBaseFlag::Enum>().NameConversion, baseFlags ); + + PxU32 flagData = 1; + for(PxU32 i = 0; i < 16; i++) + { + flagData = PxU32(1 << i); + if( !(flagData & PxParticleBaseFlag::ePER_PARTICLE_REST_OFFSET) && (!!(PxU32(baseFlags) & flagData)) ) + { + theParticle->setParticleBaseFlag(PxParticleBaseFlag::Enum(flagData), true); + } + } + + PxParticleReadDataFlags readFlags; + ret &= readFlagsProperty( inReader, inAllocator, "ParticleReadDataFlags", PxEnumTraits<PxParticleReadDataFlag::Enum>().NameConversion, readFlags ); + for(PxU32 i = 0; i < 16; i++) + { + flagData = PxU32(1 << i); + if( !!(PxU32(readFlags) & flagData) ) + { + theParticle->setParticleReadDataFlag(PxParticleReadDataFlag::Enum(flagData), true); + } + } + + PxParticleCreationData creationData; + creationData.numParticles = numParticles; + creationData.indexBuffer = PxStrideIterator<const PxU32>(validIndexBuf.begin()); + creationData.positionBuffer = PxStrideIterator<const PxVec3>(validPosBuf.begin()); + if(bVelBuff) + creationData.velocityBuffer = PxStrideIterator<const PxVec3>(validVelBuf.begin()); + if(perParticleRestOffset) + creationData.restOffsetBuffer = PxStrideIterator<const PxF32>(validRestBuf.begin()); + if(bFlagBuff) + creationData.flagBuffer = PxStrideIterator<const PxU32>(validFlagBuf.begin()); + + theParticle->createParticles(creationData); + + return ret ? PxCreateRepXObject(theParticle) : PxRepXObject(); + } + else + { + Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::createCollectionFromXml: PxParticleRepXSerializer: " + "Xml field \"ValidParticleRange\" is zero!"); + return PxRepXObject(); + } + } + // explicit instantiations + template struct PxParticleRepXSerializer<PxParticleSystem>; + template struct PxParticleRepXSerializer<PxParticleFluid>; +#endif // #if PX_USE_PARTICLE_SYSTEM_API +} diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.h new file mode 100644 index 00000000..edd61210 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXCoreSerializer.h @@ -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. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#ifndef SN_REPX_CORE_SERIALIZER_H +#define SN_REPX_CORE_SERIALIZER_H +/** \addtogroup RepXSerializers + @{ +*/ +#include "foundation/PxSimpleTypes.h" +#include "SnRepXSerializerImpl.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + template<typename TLiveType> + struct RepXSerializerImpl; + + class XmlReader; + class XmlMemoryAllocator; + class XmlWriter; + class MemoryBuffer; + + struct PxMaterialRepXSerializer : RepXSerializerImpl<PxMaterial> + { + PxMaterialRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxMaterial>( inCallback ) {} + virtual PxMaterial* allocateObject( PxRepXInstantiationArgs& ); + }; + + struct PxShapeRepXSerializer : public RepXSerializerImpl<PxShape> + { + PxShapeRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxShape>( inCallback ) {} + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxShape* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + + struct PxBVH33TriangleMeshRepXSerializer : public RepXSerializerImpl<PxBVH33TriangleMesh> + { + PxBVH33TriangleMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxBVH33TriangleMesh>( inCallback ) {} + virtual void objectToFileImpl( const PxBVH33TriangleMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxBVH33TriangleMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + struct PxBVH34TriangleMeshRepXSerializer : public RepXSerializerImpl<PxBVH34TriangleMesh> + { + PxBVH34TriangleMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxBVH34TriangleMesh>( inCallback ) {} + virtual void objectToFileImpl( const PxBVH34TriangleMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxBVH34TriangleMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + + struct PxHeightFieldRepXSerializer : public RepXSerializerImpl<PxHeightField> + { + PxHeightFieldRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxHeightField>( inCallback ) {} + virtual void objectToFileImpl( const PxHeightField*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxHeightField* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + + struct PxConvexMeshRepXSerializer : public RepXSerializerImpl<PxConvexMesh> + { + PxConvexMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxConvexMesh>( inCallback ) {} + virtual void objectToFileImpl( const PxConvexMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxConvexMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + + struct PxRigidStaticRepXSerializer : public RepXSerializerImpl<PxRigidStatic> + { + PxRigidStaticRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxRigidStatic>( inCallback ) {} + virtual PxRigidStatic* allocateObject( PxRepXInstantiationArgs& ); + }; + + struct PxRigidDynamicRepXSerializer : public RepXSerializerImpl<PxRigidDynamic> + { + PxRigidDynamicRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxRigidDynamic>( inCallback ) {} + virtual PxRigidDynamic* allocateObject( PxRepXInstantiationArgs& ); + }; + + struct PxArticulationRepXSerializer : public RepXSerializerImpl<PxArticulation> + { + PxArticulationRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxArticulation>( inCallback ) {} + virtual void objectToFileImpl( const PxArticulation*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxArticulation* allocateObject( PxRepXInstantiationArgs& ); + }; + + struct PxAggregateRepXSerializer : public RepXSerializerImpl<PxAggregate> + { + PxAggregateRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxAggregate>( inCallback ) {} + virtual void objectToFileImpl( const PxAggregate*, PxCollection*, XmlWriter& , MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxAggregate* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + +#if PX_USE_CLOTH_API + struct PxClothFabricRepXSerializer : public RepXSerializerImpl<PxClothFabric> + { + PxClothFabricRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxClothFabric>( inCallback ) {} + virtual void objectToFileImpl( const PxClothFabric*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxClothFabric* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; + + struct PxClothRepXSerializer : public RepXSerializerImpl<PxCloth> + { + PxClothRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<PxCloth>( inCallback ) {} + virtual void objectToFileImpl( const PxCloth*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual PxCloth* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; +#endif + +#if PX_USE_PARTICLE_SYSTEM_API + template<typename TParticleType> + struct PxParticleRepXSerializer : RepXSerializerImpl<TParticleType> + { + PxParticleRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl<TParticleType>( inCallback ) {} + virtual void objectToFileImpl( const TParticleType*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); + virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); + virtual TParticleType* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } + }; +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif +/** @} */ + diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXSerializerImpl.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXSerializerImpl.h new file mode 100644 index 00000000..08fe861a --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXSerializerImpl.h @@ -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. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#ifndef PX_REPX_SERIALIZER_IMPL_H +#define PX_REPX_SERIALIZER_IMPL_H + +#include "PsUserAllocated.h" +#include "SnXmlVisitorWriter.h" +#include "SnXmlVisitorReader.h" + +namespace physx { + using namespace Sn; + + /** + * The repx serializer impl takes the raw, untyped repx extension interface + * and implements the simpler functions plus does the reinterpret-casts required + * for any object to implement the serializer safely. + */ + template<typename TLiveType> + struct RepXSerializerImpl : public PxRepXSerializer, shdfnd::UserAllocated + { + protected: + RepXSerializerImpl( const RepXSerializerImpl& inOther ); + RepXSerializerImpl& operator=( const RepXSerializerImpl& inOther ); + + public: + PxAllocatorCallback& mAllocator; + + RepXSerializerImpl( PxAllocatorCallback& inAllocator ) + : mAllocator( inAllocator ) + { + } + + virtual const char* getTypeName() { return PxTypeInfo<TLiveType>::name(); } + + virtual void objectToFile( const PxRepXObject& inLiveObject, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& inArgs ) + { + const TLiveType* theObj = reinterpret_cast<const TLiveType*>( inLiveObject.serializable ); + objectToFileImpl( theObj, inCollection, inWriter, inTempBuffer, inArgs ); + } + + virtual PxRepXObject fileToObject( XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + TLiveType* theObj( allocateObject( inArgs ) ); + if ( theObj ) + if(fileToObjectImpl( theObj, inReader, inAllocator, inArgs, inCollection )) + return PxCreateRepXObject(theObj); + return PxRepXObject(); + } + + virtual void objectToFileImpl( const TLiveType* inObj, PxCollection* inCollection, XmlWriter& inWriter, MemoryBuffer& inTempBuffer, PxRepXInstantiationArgs& /*inArgs*/) + { + writeAllProperties( inObj, inWriter, inTempBuffer, *inCollection ); + } + + virtual bool fileToObjectImpl( TLiveType* inObj, XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection ) + { + return readAllProperties( inArgs, inReader, inObj, inAllocator, *inCollection ); + } + + virtual TLiveType* allocateObject( PxRepXInstantiationArgs& inArgs ) = 0; + }; +} + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.cpp new file mode 100644 index 00000000..5eb2f40e --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.cpp @@ -0,0 +1,444 @@ +// 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 "CmPhysXCommon.h" +#include "SnXmlImpl.h" +#include "SnXmlReader.h" +#include "SnXmlMemoryAllocator.h" +#include "PsFoundation.h" +#include "SnRepXCollection.h" +#include "SnRepXUpgrader.h" + +using namespace physx::profile; + +namespace physx { namespace Sn { + + #define DEFINE_REPX_DEFAULT_PROPERTY( name, val ) RepXDefaultEntry( name, val ), + + static RepXDefaultEntry gRepX1_0Defaults[] = { + #include "SnRepX1_0Defaults.h" + }; + static PxU32 gNumRepX1_0Default = sizeof( gRepX1_0Defaults ) / sizeof ( *gRepX1_0Defaults ); + + static RepXDefaultEntry gRepX3_1Defaults[] = { + #include "SnRepX3_1Defaults.h" + }; + static PxU32 gNumRepX3_1Defaults = sizeof( gRepX3_1Defaults ) / sizeof ( *gRepX3_1Defaults ); + + static RepXDefaultEntry gRepX3_2Defaults[] = { + #include "SnRepX3_2Defaults.h" + }; + static PxU32 gNumRepX3_2Defaults = sizeof( gRepX3_2Defaults ) / sizeof ( *gRepX3_2Defaults ); + + inline const char* nextPeriod( const char* str ) + { + for( ++str; str && *str && *str != '.'; ++str ); //empty loop intentional + return str; + } + + inline bool safeStrEq(const char* lhs, const char* rhs) + { + if (lhs == rhs) + return true; + //If they aren't equal, and one of them is null, + //then they can't be equal. + //This is assuming that the null char* is not equal to + //the empty "" char*. + if (!lhs || !rhs) + return false; + + return ::strcmp(lhs, rhs) == 0; + } + + typedef PxProfileHashMap<const char*, PxU32> TNameOffsetMap; + + void setMissingPropertiesToDefault( XmlNode* topNode, XmlReaderWriter& editor, const RepXDefaultEntry* defaults, PxU32 numDefaults, TNameOffsetMap& map ) + { + for ( XmlNode* child = topNode->mFirstChild; child != NULL; child = child->mNextSibling ) + setMissingPropertiesToDefault( child, editor, defaults, numDefaults, map ); + + const TNameOffsetMap::Entry* entry( map.find( topNode->mName ) ); + if ( entry ) + { + XmlReaderWriter& theReader( editor ); + theReader.setNode( *topNode ); + char nameBuffer[512] = {0}; + size_t nameLen = strlen( topNode->mName ); + //For each default property entry for this node type. + for ( const RepXDefaultEntry* item = defaults + entry->second; strncmp( item->name, topNode->mName, nameLen ) == 0; ++item ) + { + bool childAdded = false; + const char* nameStart = item->name + nameLen; + ++nameStart; + theReader.pushCurrentContext(); + const char* str = nameStart; + while( *str ) + { + const char *period = nextPeriod( str ); + size_t len = size_t(PxMin( period - str, ptrdiff_t(1023) )); //can't be too careful these days. + memcpy( nameBuffer, str, len ); + nameBuffer[len] = 0; + if ( theReader.gotoChild( nameBuffer ) == false ) + { + childAdded = true; + theReader.addOrGotoChild( nameBuffer ); + } + if (*period ) + str = period + 1; + else + str = period; + } + if ( childAdded ) + theReader.setCurrentItemValue( item->value ); + theReader.popCurrentContext(); + } + } + } + + + static void setMissingPropertiesToDefault( RepXCollection& collection, XmlReaderWriter& editor, const RepXDefaultEntry* defaults, PxU32 numDefaults ) + { + PxProfileAllocatorWrapper wrapper( collection.getAllocator() ); + //Release all strings at once, instead of piece by piece + XmlMemoryAllocatorImpl alloc( collection.getAllocator() ); + //build a hashtable of the initial default value strings. + TNameOffsetMap nameOffsets( wrapper ); + for ( PxU32 idx = 0; idx < numDefaults; ++idx ) + { + const RepXDefaultEntry& item( defaults[idx] ); + size_t nameLen = 0; + const char* periodPtr = nextPeriod (item.name); + for ( ; periodPtr && *periodPtr; ++periodPtr ) if( *periodPtr == '.' ) break; + if ( periodPtr == NULL || *periodPtr != '.' ) continue; + nameLen = size_t(periodPtr - item.name); + char* newMem = reinterpret_cast<char*>(alloc.allocate( PxU32(nameLen + 1) )); + memcpy( newMem, item.name, nameLen ); + newMem[nameLen] = 0; + + if ( nameOffsets.find( newMem ) ) + alloc.deallocate( reinterpret_cast<PxU8*>(newMem) ); + else + nameOffsets.insert( newMem, idx ); + } + //Run through each collection item, and recursively find it and its children + //If an object's name is in the hash map, check and add any properties that don't exist. + //else return. + for ( const RepXCollectionItem* item = collection.begin(), *end = collection.end(); item != end; ++ item ) + { + RepXCollectionItem theItem( *item ); + setMissingPropertiesToDefault( theItem.descriptor, editor, defaults, numDefaults, nameOffsets ); + } + } + + struct RecursiveTraversal + { + RecursiveTraversal(XmlReaderWriter& editor): mEditor(editor) {} + void traverse() + { + mEditor.pushCurrentContext(); + updateNode(); + for(bool exists = mEditor.gotoFirstChild(); exists; exists = mEditor.gotoNextSibling()) + traverse(); + mEditor.popCurrentContext(); + } + virtual void updateNode() = 0; + virtual ~RecursiveTraversal() {} + XmlReaderWriter& mEditor; + protected: + RecursiveTraversal& operator=(const RecursiveTraversal&){return *this;} + }; + + + RepXCollection& RepXUpgrader::upgrade10CollectionTo3_1Collection(RepXCollection& src) + { + XmlReaderWriter& editor( src.createNodeEditor() ); + setMissingPropertiesToDefault(src, editor, gRepX1_0Defaults, gNumRepX1_0Default ); + + + RepXCollection* dest = &src.createCollection("3.1.1"); + + for ( const RepXCollectionItem* item = src.begin(), *end = src.end(); item != end; ++ item ) + { + //either src or dest could do the copy operation, it doesn't matter who does it. + RepXCollectionItem newItem( item->liveObject, src.copyRepXNode( item->descriptor ) ); + editor.setNode( *const_cast<XmlNode*>( newItem.descriptor ) ); + //Some old files have this name in their system. + editor.renameProperty( "MassSpaceInertia", "MassSpaceInertiaTensor" ); + editor.renameProperty( "SleepEnergyThreshold", "SleepThreshold" ); + + if ( strstr( newItem.liveObject.typeName, "Joint" ) || strstr( newItem.liveObject.typeName, "joint" ) ) + { + //Joints changed format a bit. old joints looked like: + /* + <Actor0 >1627536</Actor0> + <Actor1 >1628368</Actor1> + <LocalPose0 >0 0 0 1 0.5 0.5 0.5</LocalPose0> + <LocalPose1 >0 0 0 1 0.3 0.3 0.3</LocalPose1>*/ + //New joints look like: + /* + <Actors > + <actor0 >58320336</actor0> + <actor1 >56353568</actor1> + </Actors> + <LocalPose > + <eACTOR0 >0 0 0 1 0.5 0.5 0.5</eACTOR0> + <eACTOR1 >0 0 0 1 0.3 0.3 0.3</eACTOR1> + </LocalPose> + */ + const char* actor0, *actor1, *lp0, *lp1; + editor.readAndRemoveProperty( "Actor0", actor0 ); + editor.readAndRemoveProperty( "Actor1", actor1 ); + editor.readAndRemoveProperty( "LocalPose0", lp0 ); + editor.readAndRemoveProperty( "LocalPose1", lp1 ); + + editor.addOrGotoChild( "Actors" ); + editor.writePropertyIfNotEmpty( "actor0", actor0 ); + editor.writePropertyIfNotEmpty( "actor1", actor1 ); + editor.leaveChild(); + + editor.addOrGotoChild( "LocalPose" ); + editor.writePropertyIfNotEmpty( "eACTOR0", lp0 ); + editor.writePropertyIfNotEmpty( "eACTOR1", lp1 ); + editor.leaveChild(); + } + + + + //now desc owns the new node. Collections share a single allocation pool, however, + //which will get destroyed when all the collections referencing it are destroyed themselves. + //Data on nodes is shared between nodes, but the node structure itself is allocated. + dest->addCollectionItem( newItem ); + } + editor.release(); + src.destroy(); + return *dest; + } + + RepXCollection& RepXUpgrader::upgrade3_1CollectionTo3_2Collection(RepXCollection& src) + { + XmlReaderWriter& editor( src.createNodeEditor() ); + setMissingPropertiesToDefault(src, editor, gRepX3_1Defaults, gNumRepX3_1Defaults ); + + RepXCollection* dest = &src.createCollection("3.2.0"); + + for ( const RepXCollectionItem* item = src.begin(), *end = src.end(); item != end; ++ item ) + { + //either src or dest could do the copy operation, it doesn't matter who does it. + RepXCollectionItem newItem( item->liveObject, src.copyRepXNode( item->descriptor ) ); + editor.setNode( *const_cast<XmlNode*>( newItem.descriptor ) ); + + if ( strstr( newItem.liveObject.typeName, "PxMaterial" ) ) + { + editor.removeChild( "DynamicFrictionV" ); + editor.removeChild( "StaticFrictionV" ); + editor.removeChild( "dirOfAnisotropy" ); + } + //now desc owns the new node. Collections share a single allocation pool, however, + //which will get destroyed when all the collections referencing it are destroyed themselves. + //Data on nodes is shared between nodes, but the node structure itself is allocated. + dest->addCollectionItem( newItem ); + } + editor.release(); + src.destroy(); + return *dest; + } + + RepXCollection& RepXUpgrader::upgrade3_2CollectionTo3_3Collection(RepXCollection& src) + { + XmlReaderWriter& editor( src.createNodeEditor() ); + setMissingPropertiesToDefault(src, editor, gRepX3_2Defaults, gNumRepX3_2Defaults ); + + RepXCollection* dest = &src.createCollection("3.3.0"); + + + + struct RenameSpringToStiffness : public RecursiveTraversal + { + RenameSpringToStiffness(XmlReaderWriter& editor_): RecursiveTraversal(editor_) {} + + void updateNode() + { + mEditor.renameProperty("Spring", "Stiffness"); + mEditor.renameProperty("TangentialSpring", "TangentialStiffness"); + } + }; + + + struct UpdateArticulationSwingLimit : public RecursiveTraversal + { + UpdateArticulationSwingLimit(XmlReaderWriter& editor_): RecursiveTraversal(editor_) {} + + void updateNode() + { + if(!Ps::stricmp(mEditor.getCurrentItemName(), "yLimit") && !Ps::stricmp(mEditor.getCurrentItemValue(), "0")) + mEditor.setCurrentItemValue("0.785398"); + + if(!Ps::stricmp(mEditor.getCurrentItemName(), "zLimit") && !Ps::stricmp(mEditor.getCurrentItemValue(), "0")) + mEditor.setCurrentItemValue("0.785398"); + + if(!Ps::stricmp(mEditor.getCurrentItemName(), "TwistLimit")) + { + mEditor.gotoFirstChild(); + PxReal lower = PxReal(strtod(mEditor.getCurrentItemValue(), NULL)); + mEditor.gotoNextSibling(); + PxReal upper = PxReal(strtod(mEditor.getCurrentItemValue(), NULL)); + mEditor.leaveChild(); + if(lower>=upper) + { + mEditor.writePropertyIfNotEmpty("lower", "-0.785398"); + mEditor.writePropertyIfNotEmpty("upper", "0.785398"); + } + } + } + }; + + + for ( const RepXCollectionItem* item = src.begin(), *end = src.end(); item != end; ++ item ) + { + //either src or dest could do the copy operation, it doesn't matter who does it. + RepXCollectionItem newItem( item->liveObject, src.copyRepXNode( item->descriptor ) ); + + + if ( strstr( newItem.liveObject.typeName, "PxCloth" ) || strstr( newItem.liveObject.typeName, "PxClothFabric" ) ) + { + physx::shdfnd::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "Didn't suppot PxCloth upgrate from 3.2 to 3.3! "); + continue; + } + + if ( strstr( newItem.liveObject.typeName, "PxParticleSystem" ) || strstr( newItem.liveObject.typeName, "PxParticleFluid" ) ) + { + editor.setNode( *const_cast<XmlNode*>( newItem.descriptor ) ); + editor.renameProperty( "PositionBuffer", "Positions" ); + editor.renameProperty( "VelocityBuffer", "Velocities" ); + editor.renameProperty( "RestOffsetBuffer", "RestOffsets" ); + } + + if(strstr(newItem.liveObject.typeName, "PxPrismaticJoint" ) + || strstr(newItem.liveObject.typeName, "PxRevoluteJoint") + || strstr(newItem.liveObject.typeName, "PxSphericalJoint") + || strstr(newItem.liveObject.typeName, "PxD6Joint") + || strstr(newItem.liveObject.typeName, "PxArticulation")) + { + editor.setNode( *const_cast<XmlNode*>( newItem.descriptor ) ); + RenameSpringToStiffness(editor).traverse(); + } + + if(strstr(newItem.liveObject.typeName, "PxArticulation")) + { + editor.setNode( *const_cast<XmlNode*>( newItem.descriptor ) ); + UpdateArticulationSwingLimit(editor).traverse(); + } + + + + //now dest owns the new node. Collections share a single allocation pool, however, + //which will get destroyed when all the collections referencing it are destroyed themselves. + //Data on nodes is shared between nodes, but the node structure itself is allocated. + + dest->addCollectionItem( newItem ); + + } + editor.release(); + src.destroy(); + + return *dest; + } + + RepXCollection& RepXUpgrader::upgrade3_3CollectionTo3_4Collection(RepXCollection& src) + { + RepXCollection* dest = &src.createCollection("3.4.0"); + + for ( const RepXCollectionItem* item = src.begin(), *end = src.end(); item != end; ++ item ) + { + if(strstr(item->liveObject.typeName, "PxTriangleMesh")) + { + PxRepXObject newMeshRepXObj("PxBVH33TriangleMesh", item->liveObject.serializable, item->liveObject.id); + XmlNode* newMeshNode = src.copyRepXNode( item->descriptor ); + newMeshNode->mName = "PxBVH33TriangleMesh"; + RepXCollectionItem newMeshItem(newMeshRepXObj, newMeshNode); + dest->addCollectionItem( newMeshItem ); + continue; + } + + RepXCollectionItem newItem( item->liveObject, src.copyRepXNode( item->descriptor ) ); + dest->addCollectionItem( newItem ); + } + src.destroy(); + return *dest; + } + + RepXCollection& RepXUpgrader::upgradeCollection(RepXCollection& src) + { + const char* srcVersion = src.getVersion(); + if( safeStrEq( srcVersion, RepXCollection::getLatestVersion() )) + return src; + + static const char* oldVersions[] = {"1.0", + "3.1", + "3.1.1", + "3.2.0", + "3.3.0", + "3.3.1", + "3.3.2" + };//should be increase order + + PxU32 grade = UINT16_MAX; + const PxU32 count = sizeof(oldVersions)/sizeof(oldVersions[0]); + for (PxU32 i=0; i<count; i++) + { + if( safeStrEq( srcVersion, oldVersions[i] )) + { + grade = i; + break; + } + } + + typedef RepXCollection& (*UPGRADE_FUNCTION)(RepXCollection& src); + + UPGRADE_FUNCTION procs[count] = + { + upgrade10CollectionTo3_1Collection, + NULL, + upgrade3_1CollectionTo3_2Collection, + upgrade3_2CollectionTo3_3Collection, + NULL, + NULL, + upgrade3_3CollectionTo3_4Collection, + }; + + RepXCollection* dest = &src; + for( PxU32 j = grade; j < count; j++ ) + { + if( procs[j] ) + dest = &(procs[j])(*dest); + } + + return *dest; + } +} } diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.h new file mode 100644 index 00000000..9baf270c --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnRepXUpgrader.h @@ -0,0 +1,53 @@ +// 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_REPX_UPGRADER_H +#define PX_REPX_UPGRADER_H + +#include "foundation/PxSimpleTypes.h" + +namespace physx { namespace Sn { + class RepXCollection; + + class RepXUpgrader + { + public: + //If a new collection is created, the source collection is destroyed. + //Thus you only need to release the new collection. + //This holds for all of the upgrade functions. + //So be aware, that the argument to these functions may not be valid + //after they are called, but the return value always will be valid. + static RepXCollection& upgradeCollection( RepXCollection& src ); + static RepXCollection& upgrade10CollectionTo3_1Collection( RepXCollection& src ); + static RepXCollection& upgrade3_1CollectionTo3_2Collection( RepXCollection& src ); + static RepXCollection& upgrade3_2CollectionTo3_3Collection( RepXCollection& src ); + static RepXCollection& upgrade3_3CollectionTo3_4Collection( RepXCollection& src ); + }; +} } + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnSimpleXmlWriter.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnSimpleXmlWriter.h new file mode 100644 index 00000000..6f63fefc --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnSimpleXmlWriter.h @@ -0,0 +1,257 @@ +// 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_SIMPLEXMLWRITER_H +#define PX_SIMPLEXMLWRITER_H + +#include "PsArray.h" +#include "SnXmlMemoryPoolStreams.h" +#include "CmPhysXCommon.h" + +namespace physx { namespace Sn { + class SimpleXmlWriter + { + public: + + struct STagWatcher + { + typedef SimpleXmlWriter TXmlWriterType; + TXmlWriterType& mWriter; + STagWatcher( const STagWatcher& inOther ); + STagWatcher& operator-( const STagWatcher& inOther ); + STagWatcher( TXmlWriterType& inWriter, const char* inTagName ) + : mWriter( inWriter ) + { + mWriter.beginTag( inTagName ); + } + ~STagWatcher() { mWriter.endTag(); } + protected: + STagWatcher& operator=(const STagWatcher&); + }; + + virtual ~SimpleXmlWriter(){} + virtual void beginTag( const char* inTagname ) = 0; + virtual void endTag() = 0; + virtual void addAttribute( const char* inName, const char* inValue ) = 0; + virtual void writeContentTag( const char* inTag, const char* inContent ) = 0; + virtual void addContent( const char* inContent ) = 0; + virtual PxU32 tabCount() = 0; + private: + SimpleXmlWriter& operator=(const SimpleXmlWriter&); + }; + + template<typename TStreamType> + class SimpleXmlWriterImpl : public SimpleXmlWriter + { + PxProfileAllocatorWrapper mWrapper; + TStreamType& mStream; + SimpleXmlWriterImpl( const SimpleXmlWriterImpl& inOther ); + SimpleXmlWriterImpl& operator=( const SimpleXmlWriterImpl& inOther ); + PxProfileArray<const char*> mTags; + bool mTagOpen; + PxU32 mInitialTagDepth; + public: + + SimpleXmlWriterImpl( TStreamType& inStream, PxAllocatorCallback& inAllocator, PxU32 inInitialTagDepth = 0 ) + : mWrapper( inAllocator ) + , mStream( inStream ) + , mTags( mWrapper ) + , mTagOpen( false ) + , mInitialTagDepth( inInitialTagDepth ) + { + } + virtual ~SimpleXmlWriterImpl() + { + while( mTags.size() ) + endTag(); + } + PxU32 tabCount() { return mTags.size() + mInitialTagDepth; } + + void writeTabs( PxU32 inSize ) + { + inSize += mInitialTagDepth; + for ( PxU32 idx =0; idx < inSize; ++idx ) + mStream << "\t"; + } + void beginTag( const char* inTagname ) + { + closeTag(); + writeTabs(mTags.size()); + mTags.pushBack( inTagname ); + mStream << "<" << inTagname; + mTagOpen = true; + } + void addAttribute( const char* inName, const char* inValue ) + { + PX_ASSERT( mTagOpen ); + mStream << " " << inName << "=" << "\"" << inValue << "\""; + } + void closeTag(bool useNewline = true) + { + if ( mTagOpen ) + { + mStream << " " << ">"; + if (useNewline ) + mStream << "\n"; + } + mTagOpen = false; + } + void doEndOpenTag() + { + mStream << "</" << mTags.back() << ">" << "\n"; + } + void endTag() + { + PX_ASSERT( mTags.size() ); + if ( mTagOpen ) + mStream << " " << "/>" << "\n"; + else + { + writeTabs(mTags.size()-1); + doEndOpenTag(); + } + mTagOpen = false; + mTags.popBack(); + } + + static bool IsNormalizableWhitespace(char c) { return c == 0x9 || c == 0xA || c == 0xD; } + static bool IsValidXmlCharacter(char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } + + void addContent( const char* inContent ) + { + closeTag(false); + //escape xml + for( ; *inContent; inContent++ ) + { + switch (*inContent) + { + case '<': + mStream << "<"; + break; + case '>': + mStream << ">"; + break; + case '&': + mStream << "&"; + break; + case '\'': + mStream << "'"; + break; + case '"': + mStream << """; + break; + default: + if (IsValidXmlCharacter(*inContent)) { + if (IsNormalizableWhitespace(*inContent)) + { + char s[32]; + Ps::snprintf(s, 32, "&#x%02X;", unsigned(*inContent)); + mStream << s; + } + else + mStream << *inContent; + } + break; + } + } + } + + void writeContentTag( const char* inTag, const char* inContent ) + { + beginTag( inTag ); + addContent( inContent ); + doEndOpenTag(); + mTags.popBack(); + } + void insertXml( const char* inXml ) + { + closeTag(); + mStream << inXml; + } + }; + + struct BeginTag + { + const char* mTagName; + BeginTag( const char* inTagName ) + : mTagName( inTagName ) { } + }; + + struct EndTag + { + EndTag() {} + }; + + struct Att + { + const char* mAttName; + const char* mAttValue; + Att( const char* inAttName, const char* inAttValue ) + : mAttName( inAttName ) + , mAttValue( inAttValue ) { } + }; + + struct Content + { + const char* mContent; + Content( const char* inContent ) + : mContent( inContent ) { } + }; + + + struct ContentTag + { + const char* mTagName; + const char* mContent; + ContentTag( const char* inTagName, const char* inContent ) + : mTagName( inTagName ) + , mContent( inContent ) { } + }; + + inline SimpleXmlWriter& operator<<( SimpleXmlWriter& inWriter, const BeginTag& inTag ) { inWriter.beginTag( inTag.mTagName ); return inWriter; } + inline SimpleXmlWriter& operator<<( SimpleXmlWriter& inWriter, const EndTag& inTag ) { PX_UNUSED(inTag); inWriter.endTag(); return inWriter; } + inline SimpleXmlWriter& operator<<( SimpleXmlWriter& inWriter, const Att& inTag ) { inWriter.addAttribute(inTag.mAttName, inTag.mAttValue); return inWriter; } + inline SimpleXmlWriter& operator<<( SimpleXmlWriter& inWriter, const Content& inTag ) { inWriter.addContent(inTag.mContent); return inWriter; } + inline SimpleXmlWriter& operator<<( SimpleXmlWriter& inWriter, const ContentTag& inTag ) { inWriter.writeContentTag(inTag.mTagName, inTag.mContent); return inWriter; } + + inline void writeProperty( SimpleXmlWriter& inWriter, MemoryBuffer& tempBuffer, const char* inPropName ) + { + PxU8 data = 0; + tempBuffer.write( &data, sizeof(PxU8) ); + inWriter.writeContentTag( inPropName, reinterpret_cast<const char*>( tempBuffer.mBuffer ) ); + tempBuffer.clear(); + } + + template<typename TDataType> + inline void writeProperty( SimpleXmlWriter& inWriter, MemoryBuffer& tempBuffer, const char* inPropName, TDataType inValue ) + { + tempBuffer << inValue; + writeProperty( inWriter, tempBuffer, inPropName ); + } +} } +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlDeserializer.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlDeserializer.h new file mode 100644 index 00000000..fdb29359 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlDeserializer.h @@ -0,0 +1,188 @@ +// 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_XML_DESERIALIZER_H +#define PX_XML_DESERIALIZER_H + +#include "SnXmlVisitorReader.h" + +namespace physx { namespace Sn { + + //Definitions needed internally in the Serializer headers. + template<typename TTriIndexElem> + struct Triangle + { + TTriIndexElem mIdx0; + TTriIndexElem mIdx1; + TTriIndexElem mIdx2; + Triangle( TTriIndexElem inIdx0 = 0, TTriIndexElem inIdx1 = 0, TTriIndexElem inIdx2 = 0) + : mIdx0( inIdx0 ) + , mIdx1( inIdx1 ) + , mIdx2( inIdx2 ) + { + } + }; + + struct XmlMemoryAllocateMemoryPoolAllocator + { + XmlMemoryAllocator* mAllocator; + XmlMemoryAllocateMemoryPoolAllocator( XmlMemoryAllocator* inAlloc ) : mAllocator( inAlloc ) {} + + PxU8* allocate( PxU32 inSize ) { return mAllocator->allocate( inSize ); } + void deallocate( PxU8* inMem ) { mAllocator->deallocate( inMem ); } + }; + + inline void strtoLong( Triangle<PxU32>& ioDatatype,const char*& ioData ) + { + strto( ioDatatype.mIdx0, ioData ); + strto( ioDatatype.mIdx1, ioData ); + strto( ioDatatype.mIdx2, ioData ); + } + + inline void strtoLong( PxHeightFieldSample& ioDatatype,const char*& ioData ) + { + PxU32 tempData; + strto( tempData, ioData ); + if ( isBigEndian() ) + { + PxU32& theItem(tempData); + PxU32 theDest = 0; + PxU8* theReadPtr( reinterpret_cast< PxU8* >( &theItem ) ); + PxU8* theWritePtr( reinterpret_cast< PxU8* >( &theDest ) ); + //A height field sample is a 16 bit number + //followed by two bytes. + + //We write this out as a 32 bit integer, LE. + //Thus, on a big endian, we need to move the bytes + //around a bit. + //LE - 1 2 3 4 + //BE - 4 3 2 1 - after convert from xml number + //Correct BE - 2 1 3 4, just like LE but with the 16 number swapped + theWritePtr[0] = theReadPtr[2]; + theWritePtr[1] = theReadPtr[3]; + theWritePtr[2] = theReadPtr[1]; + theWritePtr[3] = theReadPtr[0]; + theItem = theDest; + } + ioDatatype = *reinterpret_cast<PxHeightFieldSample*>( &tempData ); + } + + template<typename TDataType> + inline void readStridedFlagsProperty( XmlReader& ioReader, const char* inPropName, TDataType*& outData, PxU32& outStride, PxU32& outCount, XmlMemoryAllocator& inAllocator, + const PxU32ToName* inConversions) + { + const char* theSrcData; + outStride = sizeof( TDataType ); + outData = NULL; + outCount = 0; + if ( ioReader.read( inPropName, theSrcData ) ) + { + XmlMemoryAllocateMemoryPoolAllocator tempAllocator( &inAllocator ); + MemoryBufferBase<XmlMemoryAllocateMemoryPoolAllocator> tempBuffer( &tempAllocator ); + + if ( theSrcData ) + { + static PxU32 theCount = 0; + ++theCount; + char* theStartData = const_cast< char*>( copyStr( &tempAllocator, theSrcData ) ); + char* aData = strtok(theStartData, " \n"); + while( aData ) + { + TDataType tempValue; + stringToFlagsType( aData, inAllocator, tempValue, inConversions ); + aData = strtok(NULL," \n"); + tempBuffer.write( &tempValue, sizeof(TDataType) ); + } + outData = reinterpret_cast< TDataType* >( tempBuffer.mBuffer ); + outCount = tempBuffer.mWriteOffset / sizeof( TDataType ); + tempAllocator.deallocate( reinterpret_cast<PxU8*>(theStartData) ); + } + tempBuffer.releaseBuffer(); + } + } + + template<typename TDataType> + inline void readStridedBufferProperty( XmlReader& ioReader, const char* inPropName, TDataType*& outData, PxU32& outStride, PxU32& outCount, XmlMemoryAllocator& inAllocator) + { + const char* theSrcData; + outStride = sizeof( TDataType ); + outData = NULL; + outCount = 0; + if ( ioReader.read( inPropName, theSrcData ) ) + { + XmlMemoryAllocateMemoryPoolAllocator tempAllocator( &inAllocator ); + MemoryBufferBase<XmlMemoryAllocateMemoryPoolAllocator> tempBuffer( &tempAllocator ); + + if ( theSrcData ) + { + static PxU32 theCount = 0; + ++theCount; + char* theStartData = const_cast< char*>( copyStr( &tempAllocator, theSrcData ) ); + const char* theData = theStartData; + PxU32 theLen = strLenght( theData ); + const char* theEndData = theData + theLen; + while( theData < theEndData ) + { + //These buffers are whitespace delimited. + TDataType theType; + strtoLong( theType, theData ); + tempBuffer.write( &theType, sizeof(theType) ); + } + outData = reinterpret_cast< TDataType* >( tempBuffer.mBuffer ); + outCount = tempBuffer.mWriteOffset / sizeof( TDataType ); + tempAllocator.deallocate( reinterpret_cast<PxU8*>(theStartData) ); + } + tempBuffer.releaseBuffer(); + } + } + + template<typename TDataType> + inline void readStridedBufferProperty( XmlReader& ioReader, const char* inPropName, PxStridedData& ioData, PxU32& outCount, XmlMemoryAllocator& inAllocator) + { + TDataType* tempData = NULL; + readStridedBufferProperty<TDataType>( ioReader, inPropName, tempData, ioData.stride, outCount, inAllocator ); + ioData.data = tempData; + } + + template<typename TDataType> + inline void readStridedBufferProperty( XmlReader& ioReader, const char* inPropName, PxTypedStridedData<TDataType>& ioData, PxU32& outCount, XmlMemoryAllocator& inAllocator) + { + TDataType* tempData = NULL; + readStridedBufferProperty<TDataType>( ioReader, inPropName, tempData, ioData.stride, outCount, inAllocator ); + ioData.data = reinterpret_cast<PxMaterialTableIndex*>( tempData ); + } + + template<typename TDataType> + inline void readStridedBufferProperty( XmlReader& ioReader, const char* inPropName, PxBoundedData& ioData, XmlMemoryAllocator& inAllocator) + { + return readStridedBufferProperty<TDataType>( ioReader, inPropName, ioData, ioData.count, inAllocator ); + } + +} } + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlImpl.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlImpl.h new file mode 100644 index 00000000..1718cc86 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlImpl.h @@ -0,0 +1,242 @@ +// 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_XML_IMPL_H +#define PX_XML_IMPL_H + +#include "SnXmlMemoryPool.h" +#include "PsString.h" + +namespace physx { namespace Sn { + +typedef CMemoryPoolManager TMemoryPoolManager; + +namespace snXmlImpl { + + inline PxU32 strLen( const char* inStr ) + { + PxU32 len = 0; + if ( inStr ) + { + while ( *inStr ) + { + ++len; + ++inStr; + } + } + return len; + } +} + inline const char* copyStr( PxAllocatorCallback& inAllocator, const char* inStr ) + { + if ( inStr && *inStr ) + { + PxU32 theLen = snXmlImpl::strLen( inStr ); + //The memory will never be released by repx. If you want it released, you need to pass in a custom allocator + //that tracks all allocations and releases unreleased allocations yourself. + char* dest = reinterpret_cast<char* >( inAllocator.allocate( theLen + 1, "Repx::const char*", __FILE__, __LINE__ ) ); + memcpy( dest, inStr, theLen ); + dest[theLen] = 0; + return dest; + } + return ""; + } + + template<typename TManagerType> + inline const char* copyStr( TManagerType* inMgr, const char* inStr ) + { + if ( inStr && *inStr ) + { + PxU32 theLen = snXmlImpl::strLen( inStr ); + char* dest = reinterpret_cast<char* >( inMgr->allocate( theLen + 1 ) ); + memcpy( dest, inStr, theLen ); + dest[theLen] = 0; + return dest; + } + return ""; + } + + inline void releaseStr( TMemoryPoolManager* inMgr, const char* inStr, PxU32 ) + { + if ( inStr && *inStr ) + { + inMgr->deallocate( reinterpret_cast< PxU8* >( const_cast<char*>( inStr ) ) ); + } + } + + inline void releaseStr( TMemoryPoolManager* inMgr, const char* inStr ) + { + if ( inStr && *inStr ) + { + PxU32 theLen = snXmlImpl::strLen( inStr ); + releaseStr( inMgr, inStr, theLen ); + } + } + + struct XmlNode + { + const char* mName; //Never released until all collections are released + const char* mData; //Never released until all collections are released + + XmlNode* mNextSibling; + XmlNode* mPreviousSibling; + XmlNode* mFirstChild; + XmlNode* mParent; + XmlNode( const XmlNode& ); + XmlNode& operator=( const XmlNode& ); + + PX_INLINE void initPtrs() + { + mNextSibling = NULL; + mPreviousSibling = NULL; + mFirstChild = NULL; + mParent = NULL; + } + + PX_INLINE XmlNode( const char* inName = "", const char* inData = "" ) + : mName( inName ) + , mData( inData ) + { initPtrs(); } + + void addChild( XmlNode* inItem ) + { + inItem->mParent = this; + if ( mFirstChild == NULL ) + mFirstChild = inItem; + else + { + XmlNode* theNode = mFirstChild; + //Follow the chain till the end. + while( theNode->mNextSibling != NULL ) + theNode = theNode->mNextSibling; + theNode->mNextSibling = inItem; + inItem->mPreviousSibling = theNode; + } + } + + PX_INLINE XmlNode* findChildByName( const char* inName ) + { + for ( XmlNode* theNode = mFirstChild; theNode; theNode = theNode->mNextSibling ) + { + XmlNode* theRepXNode = theNode; + if ( physx::shdfnd::stricmp( theRepXNode->mName, inName ) == 0 ) + return theNode; + } + return NULL; + } + + PX_INLINE void orphan() + { + if ( mParent ) + { + if ( mParent->mFirstChild == this ) + mParent->mFirstChild = mNextSibling; + } + if ( mPreviousSibling ) + mPreviousSibling->mNextSibling = mNextSibling; + if ( mNextSibling ) + mNextSibling->mPreviousSibling = mPreviousSibling; + if ( mFirstChild ) + mFirstChild->mParent = NULL; + initPtrs(); + } + }; + + inline XmlNode* allocateRepXNode( TMemoryPoolManager* inManager, const char* inName, const char* inData ) + { + XmlNode* retval = inManager->allocate<XmlNode>(); + retval->mName = copyStr( inManager, inName ); + retval->mData = copyStr( inManager, inData ); + return retval; + } + + inline void release( TMemoryPoolManager* inManager, XmlNode* inNode ) + { + //We *don't* release the strings associated with the node + //because they could be shared. Instead, we just let them 'leak' + //in some sense, at least until the memory manager itself is deleted. + //DO NOT UNCOMMENT THE LINES BELOW!! + //releaseStr( inManager, inNode->mName ); + //releaseStr( inManager, inNode->mData ); + inManager->deallocate( inNode ); + } + + static PX_INLINE void releaseNodeAndChildren( TMemoryPoolManager* inManager, XmlNode* inNode ) + { + if ( inNode->mFirstChild ) + { + XmlNode* childNode( inNode->mFirstChild ); + while( childNode ) + { + XmlNode* _node( childNode ); + childNode = _node->mNextSibling; + releaseNodeAndChildren( inManager, _node ); + } + } + inNode->orphan(); + release( inManager, inNode ); + } + + static XmlNode* copyRepXNodeAndSiblings( TMemoryPoolManager* inManager, const XmlNode* inNode, XmlNode* inParent ); + + static XmlNode* copyRepXNode( TMemoryPoolManager* inManager, const XmlNode* inNode, XmlNode* inParent = NULL ) + { + XmlNode* newNode( allocateRepXNode( inManager, NULL, NULL ) ); + newNode->mName = inNode->mName; //Some light structural sharing + newNode->mData = inNode->mData; //Some light structural sharing + newNode->mParent = inParent; + if ( inNode->mFirstChild ) + newNode->mFirstChild = copyRepXNodeAndSiblings( inManager, inNode->mFirstChild, newNode ); + return newNode; + } + + static XmlNode* copyRepXNodeAndSiblings( TMemoryPoolManager* inManager, const XmlNode* inNode, XmlNode* inParent ) + { + XmlNode* sibling = inNode->mNextSibling; + if ( sibling ) sibling = copyRepXNodeAndSiblings( inManager, sibling, inParent ); + XmlNode* newNode = copyRepXNode( inManager, inNode, inParent ); + newNode->mNextSibling = sibling; + if ( sibling ) sibling->mPreviousSibling = newNode; + return newNode; + } + + inline bool isBigEndian() { int i = 1; return *(reinterpret_cast<char*>(&i))==0; } + + + struct NameStackEntry + { + const char* mName; + bool mOpen; + NameStackEntry( const char* nm ) : mName( nm ), mOpen( false ) {} + }; + + typedef PxProfileArray<NameStackEntry> TNameStack; +} } + + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryAllocator.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryAllocator.h new file mode 100644 index 00000000..8172a312 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryAllocator.h @@ -0,0 +1,129 @@ +// 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_XML_MEMORY_ALLOCATOR_H +#define PX_XML_MEMORY_ALLOCATOR_H + +#include "foundation/PxSimpleTypes.h" + +namespace physx { + + class XmlMemoryAllocator + { + protected: + virtual ~XmlMemoryAllocator(){} + public: + virtual PxU8* allocate(PxU32 inSize) = 0; + virtual void deallocate( PxU8* inMem ) = 0; + virtual PxAllocatorCallback& getAllocator() = 0; + template<typename TObjectType> + TObjectType* allocate() + { + TObjectType* retval = reinterpret_cast< TObjectType* >( allocate( sizeof( TObjectType ) ) ); + new (retval) TObjectType(); + return retval; + } + + template<typename TObjectType, typename TArgType> + TObjectType* allocate(const TArgType &arg) + { + TObjectType* retval = reinterpret_cast< TObjectType* >( allocate( sizeof( TObjectType ) ) ); + new (retval) TObjectType(arg); + return retval; + } + + template<typename TObjectType> + void deallocate( TObjectType* inObject ) + { + deallocate( reinterpret_cast<PxU8*>( inObject ) ); + } + template<typename TObjectType> + inline TObjectType* batchAllocate(PxU32 inCount ) + { + TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) * inCount ) ); + for ( PxU32 idx = 0; idx < inCount; ++idx ) + { + new (retval + idx) TObjectType(); + } + return retval; + } + + template<typename TObjectType, typename TArgType> + inline TObjectType* batchAllocate(PxU32 inCount, const TArgType &arg) + { + TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) * inCount ) ); + for ( PxU32 idx = 0; idx < inCount; ++idx ) + { + new (retval + idx) TObjectType(arg); + } + return retval; + } + + + //Duplicate function definition for gcc. + template<typename TObjectType> + inline TObjectType* batchAllocate(TObjectType*, PxU32 inCount ) + { + TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) * inCount ) ); + for ( PxU32 idx = 0; idx < inCount; ++idx ) + { + new (retval + idx) TObjectType(); + } + return retval; + } + }; + + struct XmlMemoryAllocatorImpl : public XmlMemoryAllocator + { + Sn::TMemoryPoolManager mManager; + + XmlMemoryAllocatorImpl( PxAllocatorCallback& inAllocator ) + : mManager( inAllocator ) + { + } + XmlMemoryAllocatorImpl &operator=(const XmlMemoryAllocatorImpl &); + virtual PxAllocatorCallback& getAllocator() + { + return mManager.getWrapper().getAllocator(); + } + + virtual PxU8* allocate(PxU32 inSize ) + { + if ( !inSize ) + return NULL; + + return mManager.allocate( inSize ); + } + virtual void deallocate( PxU8* inMem ) + { + if ( inMem ) + mManager.deallocate( inMem ); + } + }; +} +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPool.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPool.h new file mode 100644 index 00000000..2c1177e3 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPool.h @@ -0,0 +1,373 @@ +// 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_XML_MEMORYPOOL_H +#define PX_XML_MEMORYPOOL_H + +#include "foundation/PxAssert.h" +#include "PsArray.h" +#include "PxProfileAllocatorWrapper.h" + +namespace physx { + + using namespace physx::profile; + + /** + * Linked list used to store next node ptr. + */ + struct SMemPoolNode + { + SMemPoolNode* mNextNode; + }; + + /** + * Template arguments are powers of two. + * A very fast memory pool that is not memory efficient. It contains a vector of pointers + * to blocks of memory along with a linked list of free sections. All sections are + * of the same size so allocating memory is very fast, there isn't a linear search + * through blocks of indeterminate size. It also means there is memory wasted + * when objects aren't sized to powers of two. + */ + template<PxU8 TItemSize + , PxU8 TItemCount > + class CMemoryPool + { + typedef PxProfileArray<PxU8*> TPxU8PtrList; + + PxProfileAllocatorWrapper& mWrapper; + TPxU8PtrList mAllMemory; + SMemPoolNode* mFirstFreeNode; + public: + CMemoryPool(PxProfileAllocatorWrapper& inWrapper) + : mWrapper( inWrapper ) + , mAllMemory( inWrapper ) + , mFirstFreeNode( NULL ) + {} + ~CMemoryPool() + { + TPxU8PtrList::ConstIterator theEnd = mAllMemory.end(); + for ( TPxU8PtrList::ConstIterator theIter = mAllMemory.begin(); + theIter != theEnd; + ++theIter ) + { + PxU8* thePtr = *theIter; + mWrapper.getAllocator().deallocate( thePtr ); + } + mAllMemory.clear(); + mFirstFreeNode = NULL; + } + //Using deallocated memory to hold the pointers to the next amount of memory. + PxU8* allocate() + { + if ( mFirstFreeNode ) + { + PxU8* retval = reinterpret_cast<PxU8*>(mFirstFreeNode); + mFirstFreeNode = mFirstFreeNode->mNextNode; + return retval; + } + PxU32 itemSize = GetItemSize(); + PxU32 itemCount = 1 << TItemCount; + //No free nodes, make some more. + PxU8* retval = reinterpret_cast<PxU8*>(mWrapper.getAllocator().allocate( itemCount * itemSize, "RepX fixed-size memory pool", __FILE__, __LINE__ )); + PxU8* dataPtr = retval + itemSize; + //Free extra chunks + for( PxU32 idx = 1; idx < itemCount; ++idx, dataPtr += itemSize ) + deallocate( dataPtr ); + mAllMemory.pushBack(retval); + return retval; + } + void deallocate( PxU8* inData ) + { + SMemPoolNode* nodePtr = reinterpret_cast<SMemPoolNode*>(inData); + nodePtr->mNextNode = mFirstFreeNode; + mFirstFreeNode = nodePtr; + } + //We have to have at least a pointer's worth of memory + inline PxU32 GetItemSize() { return sizeof(SMemPoolNode) << TItemSize; } + }; + + typedef PxU32 TMemAllocSizeType; + + struct SVariableMemPoolNode : SMemPoolNode + { + TMemAllocSizeType mSize; + SVariableMemPoolNode* NextNode() { return static_cast< SVariableMemPoolNode* >( mNextNode ); } + }; + + /** + * Manages variable sized allocations. + * Keeps track of freed allocations in a insertion sorted + * list. Allocating new memory traverses the list linearly. + * This object will split nodes if the node is more than + * twice as large as the request memory allocation. + */ + class CVariableMemoryPool + { + typedef PxProfileHashMap<TMemAllocSizeType, SVariableMemPoolNode*> TFreeNodeMap; + typedef PxProfileArray<PxU8*> TPxU8PtrList; + PxProfileAllocatorWrapper& mWrapper; + TPxU8PtrList mAllMemory; + TFreeNodeMap mFreeNodeMap; + PxU32 mMinAllocationSize; + + CVariableMemoryPool &operator=(const CVariableMemoryPool &); + + public: + CVariableMemoryPool(PxProfileAllocatorWrapper& inWrapper, PxU32 inMinAllocationSize = 0x20 ) + : mWrapper( inWrapper ) + , mAllMemory( inWrapper ) + , mFreeNodeMap( inWrapper) + , mMinAllocationSize( inMinAllocationSize ) + {} + + ~CVariableMemoryPool() + { + TPxU8PtrList::ConstIterator theEnd = mAllMemory.end(); + for ( TPxU8PtrList::ConstIterator theIter = mAllMemory.begin(); + theIter != theEnd; + ++theIter ) + { + PxU8* thePtr = *theIter; + mWrapper.getAllocator().deallocate( thePtr ); + } + mAllMemory.clear(); + mFreeNodeMap.clear(); + } + PxU8* MarkMem( PxU8* inMem, TMemAllocSizeType inSize ) + { + PX_ASSERT( inSize >= sizeof( SVariableMemPoolNode ) ); + SVariableMemPoolNode* theMem = reinterpret_cast<SVariableMemPoolNode*>( inMem ); + theMem->mSize = inSize; + return reinterpret_cast< PxU8* >( theMem + 1 ); + } + //Using deallocated memory to hold the pointers to the next amount of memory. + PxU8* allocate( PxU32 size ) + { + //Ensure we can place the size of the memory at the start + //of the memory block. + //Kai: to reduce the size of hash map, the requested size is aligned to 128 bytes + PxU32 theRequestedSize = (size + sizeof(SVariableMemPoolNode) + 127) & ~127; + + TFreeNodeMap::Entry* entry = const_cast<TFreeNodeMap::Entry*>( mFreeNodeMap.find( theRequestedSize ) ); + if ( NULL != entry ) + { + SVariableMemPoolNode* theNode = entry->second; + PX_ASSERT( NULL != theNode ); + PX_ASSERT( theNode->mSize == theRequestedSize ); + entry->second = theNode->NextNode(); + if (entry->second == NULL) + mFreeNodeMap.erase( theRequestedSize ); + + return reinterpret_cast< PxU8* >( theNode + 1 ); + } + + if ( theRequestedSize < mMinAllocationSize ) + theRequestedSize = mMinAllocationSize; + + //No large enough free nodes, make some more. + PxU8* retval = reinterpret_cast<PxU8*>(mWrapper.getAllocator().allocate( size_t(theRequestedSize), "RepX variable sized memory pool", __FILE__, __LINE__ )); + //If we allocated it, we free it. + mAllMemory.pushBack( retval ); + return MarkMem( retval, theRequestedSize ); + } + + //The size is stored at the beginning of the memory block. + void deallocate( PxU8* inData ) + { + SVariableMemPoolNode* theData = reinterpret_cast< SVariableMemPoolNode* >( inData ) - 1; + TMemAllocSizeType theSize = theData->mSize; + AddFreeMem( reinterpret_cast< PxU8* >( theData ), theSize ); + } + + void CheckFreeListInvariant( SVariableMemPoolNode* inNode ) + { + if ( inNode && inNode->mNextNode ) + { + PX_ASSERT( inNode->mSize <= inNode->NextNode()->mSize ); + } + } + + void AddFreeMem( PxU8* inMemory, TMemAllocSizeType inSize ) + { + PX_ASSERT( inSize >= sizeof( SVariableMemPoolNode ) ); + SVariableMemPoolNode* theNewNode = reinterpret_cast< SVariableMemPoolNode* >( inMemory ); + theNewNode->mNextNode = NULL; + theNewNode->mSize = inSize; + TFreeNodeMap::Entry* entry = const_cast<TFreeNodeMap::Entry*>( mFreeNodeMap.find( inSize ) ); + if (NULL != entry) + { + theNewNode->mNextNode = entry->second; + entry->second = theNewNode; + } + else + { + mFreeNodeMap.insert( inSize, theNewNode ); + } + } + }; + + /** + * The manager keeps a list of memory pools for different sizes of allocations. + * Anything too large simply gets allocated using the new operator. + * This doesn't mark the memory with the size of the allocated memory thus + * allowing much more efficient allocation of small items. For large enough + * allocations, it does mark the size. + * + * When using as a general memory manager, you need to wrap this class with + * something that actually does mark the returned allocation with the size + * of the allocation. + */ + class CMemoryPoolManager + { + CMemoryPoolManager &operator=(const CMemoryPoolManager &); + + public: + PxProfileAllocatorWrapper mWrapper; + + //CMemoryPool<0,8> m0ItemPool; + //CMemoryPool<1,8> m1ItemPool; + //CMemoryPool<2,8> m2ItemPool; + //CMemoryPool<3,8> m3ItemPool; + //CMemoryPool<4,8> m4ItemPool; + //CMemoryPool<5,8> m5ItemPool; + //CMemoryPool<6,8> m6ItemPool; + //CMemoryPool<7,8> m7ItemPool; + //CMemoryPool<8,8> m8ItemPool; + CVariableMemoryPool mVariablePool; + CMemoryPoolManager( PxAllocatorCallback& inAllocator ) + : mWrapper( inAllocator ) + //, m0ItemPool( mWrapper ) + //, m1ItemPool( mWrapper ) + //, m2ItemPool( mWrapper ) + //, m3ItemPool( mWrapper ) + //, m4ItemPool( mWrapper ) + //, m5ItemPool( mWrapper ) + //, m6ItemPool( mWrapper ) + //, m7ItemPool( mWrapper ) + //, m8ItemPool( mWrapper ) + , mVariablePool( mWrapper ) + { + } + PxProfileAllocatorWrapper& getWrapper() { return mWrapper; } + inline PxU8* allocate( PxU32 inSize ) + { + /* + if ( inSize <= m0ItemPool.GetItemSize() ) + return m0ItemPool.allocate(); + if ( inSize <= m1ItemPool.GetItemSize() ) + return m1ItemPool.allocate(); + if ( inSize <= m2ItemPool.GetItemSize() ) + return m2ItemPool.allocate(); + if ( inSize <= m3ItemPool.GetItemSize() ) + return m3ItemPool.allocate(); + if ( inSize <= m4ItemPool.GetItemSize() ) + return m4ItemPool.allocate(); + if ( inSize <= m5ItemPool.GetItemSize() ) + return m5ItemPool.allocate(); + if ( inSize <= m6ItemPool.GetItemSize() ) + return m6ItemPool.allocate(); + if ( inSize <= m7ItemPool.GetItemSize() ) + return m7ItemPool.allocate(); + if ( inSize <= m8ItemPool.GetItemSize() ) + return m8ItemPool.allocate(); + */ + return mVariablePool.allocate( inSize ); + } + inline void deallocate( PxU8* inMemory ) + { + if ( inMemory == NULL ) + return; + /* + if ( inSize <= m0ItemPool.GetItemSize() ) + m0ItemPool.deallocate(inMemory); + else if ( inSize <= m1ItemPool.GetItemSize() ) + m1ItemPool.deallocate(inMemory); + else if ( inSize <= m2ItemPool.GetItemSize() ) + m2ItemPool.deallocate(inMemory); + else if ( inSize <= m3ItemPool.GetItemSize() ) + m3ItemPool.deallocate(inMemory); + else if ( inSize <= m4ItemPool.GetItemSize() ) + m4ItemPool.deallocate(inMemory); + else if ( inSize <= m5ItemPool.GetItemSize() ) + m5ItemPool.deallocate(inMemory); + else if ( inSize <= m6ItemPool.GetItemSize() ) + m6ItemPool.deallocate(inMemory); + else if ( inSize <= m7ItemPool.GetItemSize() ) + m7ItemPool.deallocate(inMemory); + else if ( inSize <= m8ItemPool.GetItemSize() ) + m8ItemPool.deallocate(inMemory); + else + */ + mVariablePool.deallocate(inMemory); + } + /** + * allocate an object. Calls constructor on the new memory. + */ + template<typename TObjectType> + inline TObjectType* allocate() + { + TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) ) ); + new (retval)TObjectType(); + return retval; + } + + /** + * deallocate an object calling the destructor on the object. + * This *must* be the concrete type, it cannot be a generic type. + */ + template<typename TObjectType> + inline void deallocate( TObjectType* inObject ) + { + inObject->~TObjectType(); + deallocate( reinterpret_cast<PxU8*>(inObject) ); + } + + /** + * allocate an object. Calls constructor on the new memory. + */ + template<typename TObjectType> + inline TObjectType* BatchAllocate(PxU32 inCount ) + { + TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) * inCount ) ); + return retval; + } + + /** + * deallocate an object calling the destructor on the object. + * This *must* be the concrete type, it cannot be a generic type. + */ + template<typename TObjectType> + inline void BatchDeallocate( TObjectType* inObject, PxU32 inCount ) + { + PX_UNUSED(inCount); + deallocate( reinterpret_cast<PxU8*>(inObject) ); + } + }; +} + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPoolStreams.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPoolStreams.h new file mode 100644 index 00000000..375d1e2d --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlMemoryPoolStreams.h @@ -0,0 +1,173 @@ +// 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_XML_MEMORY_POOL_STREAMS_H +#define PX_XML_MEMORY_POOL_STREAMS_H + +#include "foundation/PxTransform.h" +#include "foundation/PxIO.h" +#include "SnXmlMemoryPool.h" +#include "CmPhysXCommon.h" + +namespace physx { + + template<typename TDataType> + struct XmlDefaultValue + { + bool force_compile_error; + }; + + +#define XML_DEFINE_DEFAULT_VALUE(type, defVal ) \ + template<> \ + struct XmlDefaultValue<type> \ + { \ + type getDefaultValue() { return type(defVal); } \ + }; + + XML_DEFINE_DEFAULT_VALUE(PxU8, 0) + XML_DEFINE_DEFAULT_VALUE(PxI8, 0) + XML_DEFINE_DEFAULT_VALUE(PxU16, 0) + XML_DEFINE_DEFAULT_VALUE(PxI16, 0) + XML_DEFINE_DEFAULT_VALUE(PxU32, 0) + XML_DEFINE_DEFAULT_VALUE(PxI32, 0) + XML_DEFINE_DEFAULT_VALUE(PxU64, 0) + XML_DEFINE_DEFAULT_VALUE(PxI64, 0) + XML_DEFINE_DEFAULT_VALUE(PxF32, 0) + XML_DEFINE_DEFAULT_VALUE(PxF64, 0) + +#undef XML_DEFINE_DEFAULT_VALUE + + template<> + struct XmlDefaultValue<PxVec3> + { + PxVec3 getDefaultValue() { return PxVec3( 0,0,0 ); } + }; + + template<> + struct XmlDefaultValue<PxTransform> + { + PxTransform getDefaultValue() { return PxTransform(PxIdentity); } + }; + + template<> + struct XmlDefaultValue<PxQuat> + { + PxQuat getDefaultValue() { return PxQuat(PxIdentity); } + }; + +/** + * Mapping of PxOutputStream to a memory pool manager. + * Allows write-then-read semantics of a set of + * data. Can safely write up to 4GB of data; then you + * will silently fail... + */ + +template<typename TAllocatorType> +struct MemoryBufferBase : public PxOutputStream, public PxInputStream +{ + TAllocatorType* mManager; + mutable PxU32 mWriteOffset; + mutable PxU32 mReadOffset; + PxU8* mBuffer; + PxU32 mCapacity; + + + MemoryBufferBase( TAllocatorType* inManager ) + : mManager( inManager ) + , mWriteOffset( 0 ) + , mReadOffset( 0 ) + , mBuffer( NULL ) + , mCapacity( 0 ) + { + } + virtual ~MemoryBufferBase() + { + mManager->deallocate( mBuffer ); + } + PxU8* releaseBuffer() + { + clear(); + mCapacity = 0; + PxU8* retval(mBuffer); + mBuffer = NULL; + return retval; + } + void clear() + { + mWriteOffset = mReadOffset = 0; + } + + virtual PxU32 read(void* dest, PxU32 count) + { + bool fits = ( mReadOffset + count ) <= mWriteOffset; + PX_ASSERT( fits ); + if ( fits ) + { + memcpy( dest, mBuffer + mReadOffset, count ); + mReadOffset += count; + return count; + } + return 0; + } + + inline void checkCapacity( PxU32 inNewCapacity ) + { + if ( mCapacity < inNewCapacity ) + { + PxU32 newCapacity = 32; + while( newCapacity < inNewCapacity ) + newCapacity = newCapacity << 1; + + PxU8* newData( mManager->allocate( newCapacity ) ); + if ( mWriteOffset ) + memcpy( newData, mBuffer, mWriteOffset ); + mManager->deallocate( mBuffer ); + mBuffer = newData; + mCapacity = newCapacity; + } + } + + virtual PxU32 write(const void* src, PxU32 count) + { + checkCapacity( mWriteOffset + count ); + memcpy( mBuffer + mWriteOffset, src, count ); + mWriteOffset += count; + return count; + } +}; + +class MemoryBuffer : public MemoryBufferBase<CMemoryPoolManager > +{ +public: + MemoryBuffer( CMemoryPoolManager* inManager ) : MemoryBufferBase<CMemoryPoolManager >( inManager ) {} +}; + +} + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlReader.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlReader.h new file mode 100644 index 00000000..88053d96 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlReader.h @@ -0,0 +1,130 @@ +// 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_XML_READER_H +#define PX_XML_READER_H + +#include "foundation/PxSimpleTypes.h" +#include "extensions/PxRepXSimpleType.h" + +namespace physx { + namespace Sn { struct XmlNode; } + + /** + * Reader used to read data out of the repx format. + */ + class XmlReader + { + protected: + virtual ~XmlReader(){} + public: + /** Read a key-value pair out of the database */ + virtual bool read( const char* inName, const char*& outData ) = 0; + /** Read an object id out of the database */ + virtual bool read( const char* inName, PxSerialObjectId& outId ) = 0; + /** Goto a child element by name. That child becomes this reader's context */ + virtual bool gotoChild( const char* inName ) = 0; + /** Goto the first child regardless of name */ + virtual bool gotoFirstChild() = 0; + /** Goto the next sibling regardless of name */ + virtual bool gotoNextSibling() = 0; + /** Count all children of the current object */ + virtual PxU32 countChildren() = 0; + /** Get the name of the current item */ + virtual const char* getCurrentItemName() = 0; + /** Get the value of the current item */ + virtual const char* getCurrentItemValue() = 0; + /** Leave the current child */ + virtual bool leaveChild() = 0; + /** Get reader for the parental object */ + virtual XmlReader* getParentReader() = 0; + + /** + * Ensures we don't leave the reader in an odd state + * due to not leaving a given child + */ + virtual void pushCurrentContext() = 0; + /** Pop the current context back to where it during push*/ + virtual void popCurrentContext() = 0; + }; + + //Used when upgrading a repx collection + class XmlReaderWriter : public XmlReader + { + public: + //Clears the stack of nodes (push/pop current node reset) + //and sets the current node to inNode. + virtual void setNode( Sn::XmlNode& node ) = 0; + //If the child exists, add it. + //the either way goto that child. + virtual void addOrGotoChild( const char* name ) = 0; + //Value is copied into the collection, inValue has no further references + //to it. + virtual void setCurrentItemValue( const char* value ) = 0; + //Removes the child but does not release the char* name or char* data ptrs. + //Those pointers are never released and are shared among collections. + //Thus copying nodes is cheap and safe. + virtual bool removeChild( const char* name ) = 0; + virtual void release() = 0; + + bool renameProperty( const char* oldName, const char* newName ) + { + if ( gotoChild( oldName ) ) + { + const char* value = getCurrentItemValue(); + leaveChild(); + removeChild( oldName ); + addOrGotoChild( newName ); + setCurrentItemValue( value ); + leaveChild(); + return true; + } + return false; + } + bool readAndRemoveProperty( const char* name, const char*& outValue ) + { + bool retval = read( name, outValue ); + if ( retval ) removeChild( name ); + return retval; + } + + bool writePropertyIfNotEmpty( const char* name, const char* value ) + { + if ( value && *value ) + { + addOrGotoChild( name ); + setCurrentItemValue( value ); + leaveChild(); + return true; + } + return false; + } + }; + +} +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerialization.cpp b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerialization.cpp new file mode 100644 index 00000000..af86eafd --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerialization.cpp @@ -0,0 +1,834 @@ +// 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 "SnXmlImpl.h" +#include "PsHash.h" +#include "PsHashMap.h" +#include "SnSimpleXmlWriter.h" +#include "PsSort.h" +#include "PsFastXml.h" +#include "PsString.h" +#include "SnXmlMemoryPool.h" +#include "PxExtensionMetaDataObjects.h" +#include "SnXmlVisitorWriter.h" +#include "SnXmlVisitorReader.h" +#include "SnXmlMemoryAllocator.h" +#include "SnXmlStringToType.h" +#include "PsString.h" +#include "SnRepXCollection.h" +#include "SnRepXUpgrader.h" +#include "../SnSerializationRegistry.h" +#include "PsFoundation.h" +#include "CmCollection.h" + +using namespace physx; +using namespace Sn; + +using namespace physx::profile; //for the foundation wrapper system. + +namespace physx { namespace Sn { + + class XmlNodeWriter : public SimpleXmlWriter + { + XmlMemoryAllocatorImpl& mParseAllocator; + XmlNode* mCurrentNode; + XmlNode* mTopNode; + PxU32 mTabCount; + + public: + XmlNodeWriter( XmlMemoryAllocatorImpl& inAllocator, PxU32 inTabCount = 0 ) + : mParseAllocator( inAllocator ) + , mCurrentNode( NULL ) + , mTopNode( NULL ) + , mTabCount( inTabCount ) + {} + XmlNodeWriter& operator=(const XmlNodeWriter&); + virtual ~XmlNodeWriter(){} + void onNewNode( XmlNode* newNode ) + { + if ( mCurrentNode != NULL ) + mCurrentNode->addChild( newNode ); + if ( mTopNode == NULL ) + mTopNode = newNode; + mCurrentNode = newNode; + ++mTabCount; + } + + XmlNode* getTopNode() const { return mTopNode; } + + virtual void beginTag( const char* inTagname ) + { + onNewNode( allocateRepXNode( &mParseAllocator.mManager, inTagname, NULL ) ); + } + virtual void endTag() + { + if ( mCurrentNode ) + mCurrentNode = mCurrentNode->mParent; + if ( mTabCount ) + --mTabCount; + } + virtual void addAttribute( const char*, const char* ) + { + PX_ASSERT( false ); + } + virtual void writeContentTag( const char* inTag, const char* inContent ) + { + onNewNode( allocateRepXNode( &mParseAllocator.mManager, inTag, inContent ) ); + endTag(); + } + virtual void addContent( const char* inContent ) + { + if ( mCurrentNode->mData ) + releaseStr( &mParseAllocator.mManager, mCurrentNode->mData ); + mCurrentNode->mData = copyStr( &mParseAllocator.mManager, inContent ); + } + virtual PxU32 tabCount() { return mTabCount; } + }; + + struct XmlWriterImpl : public XmlWriter + { + PxU32 mTagDepth; + SimpleXmlWriter* mWriter; + MemoryBuffer* mMemBuffer; + + XmlWriterImpl( SimpleXmlWriter* inWriter, MemoryBuffer* inMemBuffer ) + : mTagDepth( 0 ) + , mWriter( inWriter ) + , mMemBuffer( inMemBuffer ) + { + } + ~XmlWriterImpl() + { + while( mTagDepth ) + { + --mTagDepth; + mWriter->endTag(); + } + } + virtual void write( const char* inName, const char* inData ) + { + mWriter->writeContentTag( inName, inData ); + } + virtual void write( const char* inName, const PxRepXObject& inLiveObject ) + { + (*mMemBuffer) << inLiveObject.id; + writeProperty( *mWriter, *mMemBuffer, inName ); + } + virtual void addAndGotoChild( const char* inName ) + { + mWriter->beginTag( inName ); + mTagDepth++; + } + virtual void leaveChild() + { + if ( mTagDepth ) + { + mWriter->endTag(); + --mTagDepth; + } + } + }; + + struct XmlParseArgs + { + XmlMemoryAllocatorImpl* mAllocator; + PxProfileArray<RepXCollectionItem>* mCollection; + + XmlParseArgs( XmlMemoryAllocatorImpl* inAllocator + , PxProfileArray<RepXCollectionItem>* inCollection) + : mAllocator( inAllocator ) + , mCollection( inCollection ) + { + } + }; + + struct XmlNodeReader : public XmlReaderWriter + { + PxProfileAllocatorWrapper mWrapper; + CMemoryPoolManager& mManager; + XmlNode* mCurrentNode; + XmlNode* mTopNode; + PxProfileArray<XmlNode*> mContext; + XmlNodeReader( XmlNode* inCurrentNode, PxAllocatorCallback& inAllocator, CMemoryPoolManager& nodePoolManager ) + : mWrapper( inAllocator ) + , mManager( nodePoolManager ) + , mCurrentNode( inCurrentNode ) + , mTopNode( inCurrentNode ) + , mContext( mWrapper ) + { + } + + //Does this node exist as data in the format. + virtual bool read( const char* inName, const char*& outData ) + { + XmlNode* theChild( mCurrentNode->findChildByName( inName ) ); + if ( theChild ) + { + outData = theChild->mData; + return outData && *outData; + } + return false; + } + + virtual bool read( const char* inName, PxSerialObjectId& outId ) + { + XmlNode* theChild( mCurrentNode->findChildByName( inName ) ); + if ( theChild ) + { + const char* theValue( theChild->mData ); + strto( outId, theValue ); + return true; + } + return false; + } + + virtual bool gotoChild( const char* inName ) + { + XmlNode* theChild( mCurrentNode->findChildByName( inName ) ); + if ( theChild ) + { + mCurrentNode =theChild; + return true; + } + return false; + } + virtual bool gotoFirstChild() + { + if ( mCurrentNode->mFirstChild ) + { + mCurrentNode = mCurrentNode->mFirstChild; + return true; + } + return false; + } + virtual bool gotoNextSibling() + { + if ( mCurrentNode->mNextSibling ) + { + mCurrentNode = mCurrentNode->mNextSibling; + return true; + } + return false; + } + virtual PxU32 countChildren() + { + PxU32 retval= 0; + for ( XmlNode* theChild = mCurrentNode->mFirstChild; theChild != NULL; theChild = theChild->mNextSibling ) + ++retval; + return retval; + } + virtual const char* getCurrentItemName() + { + return mCurrentNode->mName; + } + virtual const char* getCurrentItemValue() + { + return mCurrentNode->mData; + } + + virtual bool leaveChild() + { + if ( mCurrentNode != mTopNode && mCurrentNode->mParent ) + { + mCurrentNode = mCurrentNode->mParent; + return true; + } + return false; + } + + virtual void pushCurrentContext() + { + mContext.pushBack( mCurrentNode ); + } + virtual void popCurrentContext() + { + if ( mContext.size() ) + { + mCurrentNode = mContext.back(); + mContext.popBack(); + } + } + + virtual void setNode( XmlNode& inNode ) + { + mContext.clear(); + mCurrentNode = &inNode; + mTopNode = mCurrentNode; + } + + virtual XmlReader* getParentReader() + { + XmlReader* retval = PX_PLACEMENT_NEW((mWrapper.getAllocator().allocate(sizeof(XmlNodeReader), "createNodeEditor", __FILE__, __LINE__ )), XmlNodeReader) + ( mTopNode, mWrapper.getAllocator(), mManager ); + return retval; + } + + virtual void addOrGotoChild( const char* inName ) + { + if ( gotoChild( inName )== false ) + { + XmlNode* newNode = allocateRepXNode( &mManager, inName, NULL ); + mCurrentNode->addChild( newNode ); + mCurrentNode = newNode; + } + } + virtual void setCurrentItemValue( const char* inValue ) + { + mCurrentNode->mData = copyStr( &mManager, inValue ); + } + virtual bool removeChild( const char* name ) + { + XmlNode* theChild( mCurrentNode->findChildByName( name ) ); + if ( theChild ) + { + releaseNodeAndChildren( &mManager, theChild ); + return true; + } + return false; + } + virtual void release() { this->~XmlNodeReader(); mWrapper.getAllocator().deallocate(this); } + + private: + XmlNodeReader& operator=(const XmlNodeReader&); + }; + + PX_INLINE void freeNodeAndChildren( XmlNode* tempNode, TMemoryPoolManager& inManager ) + { + for( XmlNode* theNode = tempNode->mFirstChild; theNode != NULL; theNode = theNode->mNextSibling ) + freeNodeAndChildren( theNode, inManager ); + tempNode->orphan(); + release( &inManager, tempNode ); + } + + class XmlParser : public Ps::FastXml::Callback + { + XmlParseArgs mParseArgs; + //For parse time only allocations + XmlMemoryAllocatorImpl& mParseAllocator; + XmlNode* mCurrentNode; + XmlNode* mTopNode; + + public: + XmlParser( XmlParseArgs inArgs, XmlMemoryAllocatorImpl& inParseAllocator ) + : mParseArgs( inArgs ) + , mParseAllocator( inParseAllocator ) + , mCurrentNode( NULL ) + , mTopNode( NULL ) + { + } + + virtual ~XmlParser(){} + + virtual bool processComment(const char* /*comment*/) { return true; } + // 'element' is the name of the element that is being closed. + // depth is the recursion depth of this element. + // Return true to continue processing the XML file. + // Return false to stop processing the XML file; leaves the read pointer of the stream right after this close tag. + // The bool 'isError' indicates whether processing was stopped due to an error, or intentionally canceled early. + virtual bool processClose(const char* /*element*/,physx::PxU32 /*depth*/,bool& /*isError*/) + { + mCurrentNode = mCurrentNode->mParent; + return true; + } + + // return true to continue processing the XML document, false to skip. + virtual bool processElement( + const char *elementName, // name of the element + const char *elementData, // element data, null if none + const Ps::FastXml::AttributePairs& attr, // attributes + PxI32 /*lineno*/) + { + XmlNode* newNode = allocateRepXNode( &mParseAllocator.mManager, elementName, elementData ); + if ( mCurrentNode ) + mCurrentNode->addChild( newNode ); + mCurrentNode = newNode; + //Add the elements as children. + for( PxI32 item = 0; item < attr.getNbAttr(); item ++ ) + { + XmlNode* node = allocateRepXNode( &mParseAllocator.mManager, attr.getKey(PxU32(item)), attr.getValue(PxU32(item)) ); + mCurrentNode->addChild( node ); + } + if ( mTopNode == NULL ) mTopNode = newNode; + return true; + } + + XmlNode* getTopNode() { return mTopNode; } + + virtual void * allocate(PxU32 size) + { + if ( size ) + return mParseAllocator.allocate(size); + return NULL; + } + virtual void deallocate(void *mem) + { + if ( mem ) + mParseAllocator.deallocate(reinterpret_cast<PxU8*>(mem)); + } + + private: + XmlParser& operator=(const XmlParser&); + }; + + struct RepXCollectionSharedData + { + PxProfileAllocatorWrapper mWrapper; + XmlMemoryAllocatorImpl mAllocator; + PxU32 mRefCount; + + RepXCollectionSharedData( PxAllocatorCallback& inAllocator ) + : mWrapper( inAllocator ) + , mAllocator( inAllocator ) + , mRefCount( 0 ) + { + } + ~RepXCollectionSharedData() {} + + void addRef() { ++mRefCount;} + void release() + { + if ( mRefCount ) --mRefCount; + if ( !mRefCount ) { this->~RepXCollectionSharedData(); mWrapper.getAllocator().deallocate(this);} + } + }; + + struct SharedDataPtr + { + RepXCollectionSharedData* mData; + SharedDataPtr( RepXCollectionSharedData* inData ) + : mData( inData ) + { + mData->addRef(); + } + SharedDataPtr( const SharedDataPtr& inOther ) + : mData( inOther.mData ) + { + mData->addRef(); + } + SharedDataPtr& operator=( const SharedDataPtr& inOther ); + ~SharedDataPtr() + { + mData->release(); + mData = NULL; + } + RepXCollectionSharedData* operator->() { return mData; } + const RepXCollectionSharedData* operator->() const { return mData; } + }; + + class RepXCollectionImpl : public RepXCollection, public Ps::UserAllocated + { + SharedDataPtr mSharedData; + + XmlMemoryAllocatorImpl& mAllocator; + PxSerializationRegistry& mSerializationRegistry; + PxProfileArray<RepXCollectionItem> mCollection; + TMemoryPoolManager mSerializationManager; + MemoryBuffer mPropertyBuffer; + PxTolerancesScale mScale; + PxVec3 mUpVector; + const char* mVersionStr; + PxCollection* mPxCollection; + + public: + RepXCollectionImpl( PxSerializationRegistry& inRegistry, PxAllocatorCallback& inAllocator, PxCollection& inPxCollection ) + : mSharedData( &PX_NEW_REPX_SERIALIZER( RepXCollectionSharedData )) + , mAllocator( mSharedData->mAllocator ) + , mSerializationRegistry( inRegistry ) + , mCollection( mSharedData->mWrapper ) + , mSerializationManager( inAllocator ) + , mPropertyBuffer( &mSerializationManager ) + , mUpVector( 0,0,0 ) + , mVersionStr( getLatestVersion() ) + , mPxCollection( &inPxCollection ) + { + memset( &mScale, 0, sizeof( PxTolerancesScale ) ); + PX_ASSERT( mScale.isValid() == false ); + } + + RepXCollectionImpl( PxSerializationRegistry& inRegistry, const RepXCollectionImpl& inSrc, const char* inNewVersion ) + : mSharedData( inSrc.mSharedData ) + , mAllocator( mSharedData->mAllocator ) + , mSerializationRegistry( inRegistry ) + , mCollection( mSharedData->mWrapper ) + , mSerializationManager( mSharedData->mWrapper.getAllocator() ) + , mPropertyBuffer( &mSerializationManager ) + , mScale( inSrc.mScale ) + , mUpVector( inSrc.mUpVector ) + , mVersionStr( inNewVersion ) + , mPxCollection( NULL ) + { + } + + virtual ~RepXCollectionImpl() + { + PxU32 numItems = mCollection.size(); + for ( PxU32 idx = 0; idx < numItems; ++idx ) + { + XmlNode* theNode = mCollection[idx].descriptor; + releaseNodeAndChildren( &mAllocator.mManager, theNode ); + } + } + RepXCollectionImpl& operator=(const RepXCollectionImpl&); + + virtual void destroy() + { + PxProfileAllocatorWrapper tempWrapper( mSharedData->mWrapper.getAllocator() ); + this->~RepXCollectionImpl(); + tempWrapper.getAllocator().deallocate(this); + } + + virtual void setTolerancesScale(const PxTolerancesScale& inScale) { mScale = inScale; } + virtual PxTolerancesScale getTolerancesScale() const { return mScale; } + virtual void setUpVector( const PxVec3& inUpVector ) { mUpVector = inUpVector; } + virtual PxVec3 getUpVector() const { return mUpVector; } + + + PX_INLINE RepXCollectionItem findItemBySceneItem( const PxRepXObject& inObject ) const + { + //See if the object is in the collection + for ( PxU32 idx =0; idx < mCollection.size(); ++idx ) + if ( mCollection[idx].liveObject.serializable == inObject.serializable ) + return mCollection[idx]; + return RepXCollectionItem(); + } + + virtual RepXAddToCollectionResult addRepXObjectToCollection( const PxRepXObject& inObject, PxCollection* inCollection, PxRepXInstantiationArgs& inArgs ) + { + PX_ASSERT( inObject.serializable ); + PX_ASSERT( inObject.id ); + if ( inObject.serializable == NULL || inObject.id == 0 ) + return RepXAddToCollectionResult( RepXAddToCollectionResult::InvalidParameters ); + + PxRepXSerializer* theSerializer = mSerializationRegistry.getRepXSerializer( inObject.typeName ); + if ( theSerializer == NULL ) + return RepXAddToCollectionResult( RepXAddToCollectionResult::SerializerNotFound ); + + RepXCollectionItem existing = findItemBySceneItem( inObject ); + if ( existing.liveObject.serializable ) + return RepXAddToCollectionResult( RepXAddToCollectionResult::AlreadyInCollection, existing.liveObject.id ); + + XmlNodeWriter theXmlWriter( mAllocator, 1 ); + XmlWriterImpl theRepXWriter( &theXmlWriter, &mPropertyBuffer ); + { + SimpleXmlWriter::STagWatcher theWatcher( theXmlWriter, inObject.typeName ); + writeProperty( theXmlWriter, mPropertyBuffer, "Id", inObject.id ); + theSerializer->objectToFile( inObject, inCollection, theRepXWriter, mPropertyBuffer,inArgs ); + } + mCollection.pushBack( RepXCollectionItem( inObject, theXmlWriter.getTopNode() ) ); + return RepXAddToCollectionResult( RepXAddToCollectionResult::Success, inObject.id ); + } + + virtual bool instantiateCollection( PxRepXInstantiationArgs& inArgs, PxCollection& inCollection ) + { + for ( PxU32 idx =0; idx < mCollection.size(); ++idx ) + { + RepXCollectionItem theItem( mCollection[idx] ); + PxRepXSerializer* theSerializer = mSerializationRegistry.getRepXSerializer( theItem.liveObject.typeName ); + if (theSerializer ) + { + XmlNodeReader theReader( theItem.descriptor, mAllocator.getAllocator(), mAllocator.mManager ); + XmlMemoryAllocatorImpl instantiationAllocator( mAllocator.getAllocator() ); + PxRepXObject theLiveObject = theSerializer->fileToObject( theReader, instantiationAllocator, inArgs, &inCollection ); + if (theLiveObject.isValid()) + { + const PxBase* s = reinterpret_cast<const PxBase*>( theLiveObject.serializable ) ; + inCollection.add( *const_cast<PxBase*>(s), PxSerialObjectId( theItem.liveObject.id )); + } + else + return false; + } + else + { + Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, + "PxSerialization::createCollectionFromXml: " + "PxRepXSerializer missing for type %s", theItem.liveObject.typeName); + return false; + } + } + + return true; + } + + void saveXmlNode( XmlNode* inNode, SimpleXmlWriter& inWriter ) + { + XmlNode* theNode( inNode ); + if ( theNode->mData && *theNode->mData && theNode->mFirstChild == NULL ) + inWriter.writeContentTag( theNode->mName, theNode->mData ); + else + { + inWriter.beginTag( theNode->mName ); + if ( theNode->mData && *theNode->mData ) + inWriter.addContent( theNode->mData ); + for ( XmlNode* theChild = theNode->mFirstChild; + theChild != NULL; + theChild = theChild->mNextSibling ) + saveXmlNode( theChild, inWriter ); + inWriter.endTag(); + } + } + + virtual void save( PxOutputStream& inStream ) + { + SimpleXmlWriterImpl<PxOutputStream> theWriter( inStream, mAllocator.getAllocator() ); + theWriter.beginTag( "PhysX30Collection" ); + theWriter.addAttribute( "version", mVersionStr ); + { + XmlWriterImpl theRepXWriter( &theWriter, &mPropertyBuffer ); + writeProperty( theWriter, mPropertyBuffer, "UpVector", mUpVector ); + theRepXWriter.addAndGotoChild( "Scale" ); + writeAllProperties( &mScale, theRepXWriter, mPropertyBuffer, *mPxCollection); + theRepXWriter.leaveChild(); + } + for ( PxU32 idx =0; idx < mCollection.size(); ++idx ) + { + RepXCollectionItem theItem( mCollection[idx] ); + XmlNode* theNode( theItem.descriptor ); + saveXmlNode( theNode, theWriter ); + } + } + + void load( PxInputData& inFileBuf, SerializationRegistry& s ) + { + inFileBuf.seek(0); + XmlParser theParser( XmlParseArgs( &mAllocator, &mCollection ), mAllocator ); + Ps::FastXml* theFastXml = Ps::createFastXml( &theParser ); + theFastXml->processXml( inFileBuf ); + XmlNode* theTopNode = theParser.getTopNode(); + if ( theTopNode != NULL ) + { + { + + XmlMemoryAllocatorImpl instantiationAllocator( mAllocator.getAllocator() ); + XmlNodeReader theReader( theTopNode, mAllocator.getAllocator(), mAllocator.mManager ); + readProperty( theReader, "UpVector", mUpVector ); + if ( theReader.gotoChild( "Scale" ) ) + { + readAllProperties( PxRepXInstantiationArgs( s.getPhysics() ), theReader, &mScale, instantiationAllocator, *mPxCollection); + theReader.leaveChild(); + } + const char* verStr = NULL; + if ( theReader.read( "version", verStr ) ) + mVersionStr = verStr; + } + for ( XmlNode* theChild = theTopNode->mFirstChild; + theChild != NULL; + theChild = theChild->mNextSibling ) + { + if ( physx::shdfnd::stricmp( theChild->mName, "scale" ) == 0 + || physx::shdfnd::stricmp( theChild->mName, "version" ) == 0 + || physx::shdfnd::stricmp( theChild->mName, "upvector" ) == 0 ) + continue; + XmlNodeReader theReader( theChild, mAllocator.getAllocator(), mAllocator.mManager ); + PxRepXObject theObject; + theObject.typeName = theChild->mName; + theObject.serializable = NULL; + PxSerialObjectId theId = 0; + theReader.read( "Id", theId ); + theObject.id = theId; + mCollection.pushBack( RepXCollectionItem( theObject, theChild ) ); + } + } + else + { + Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + "Cannot parse any object from the input buffer, please check the input repx data."); + } + theFastXml->release(); + } + + virtual const char* getVersion() { return mVersionStr; } + + virtual const RepXCollectionItem* begin() const + { + return mCollection.begin(); + } + virtual const RepXCollectionItem* end() const + { + return mCollection.end(); + } + + virtual RepXCollection& createCollection( const char* inVersionStr ) + { + PxAllocatorCallback& allocator = mSharedData->mWrapper.getAllocator(); + RepXCollectionImpl* retval = PX_PLACEMENT_NEW((allocator.allocate(sizeof(RepXCollectionImpl), "createCollection", __FILE__, __LINE__ )), RepXCollectionImpl) ( mSerializationRegistry, *this, inVersionStr ); + + return *retval; + } + + //Performs a deep copy of the repx node. + virtual XmlNode* copyRepXNode( const XmlNode* srcNode ) + { + return physx::Sn::copyRepXNode( &mAllocator.mManager, srcNode ); + } + + virtual void addCollectionItem( RepXCollectionItem inItem ) + { + mCollection.pushBack( inItem ); + } + + virtual PxAllocatorCallback& getAllocator() { return mSharedData->mAllocator.getAllocator(); } + //Create a new repx node with this name. Its value is unset. + virtual XmlNode& createRepXNode( const char* name ) + { + XmlNode* newNode = allocateRepXNode( &mSharedData->mAllocator.mManager, name, NULL ); + return *newNode; + } + + //Release this when finished. + virtual XmlReaderWriter& createNodeEditor() + { + PxAllocatorCallback& allocator = mSharedData->mWrapper.getAllocator(); + XmlReaderWriter* retval = PX_PLACEMENT_NEW((allocator.allocate(sizeof(XmlNodeReader), "createNodeEditor", __FILE__, __LINE__ )), XmlNodeReader) ( NULL, allocator, mAllocator.mManager ); + return *retval; + } + }; + + const char* RepXCollection::getLatestVersion() + { +#define TOSTR_(x) #x +#define CONCAT_(a, b, c) TOSTR_(a.##b.##c) +#define MAKE_VERSION_STR(a,b,c) CONCAT_(a, b, c) + + return MAKE_VERSION_STR(PX_PHYSICS_VERSION_MAJOR,PX_PHYSICS_VERSION_MINOR,PX_PHYSICS_VERSION_BUGFIX); + + } + + static RepXCollection* create(SerializationRegistry& s, PxAllocatorCallback& inAllocator, PxCollection& inCollection ) + { + return PX_PLACEMENT_NEW((inAllocator.allocate(sizeof(RepXCollectionImpl), "RepXCollection::create", __FILE__, __LINE__ )), RepXCollectionImpl) ( s, inAllocator, inCollection ); + } + + static RepXCollection* create(SerializationRegistry& s, PxInputData &data, PxAllocatorCallback& inAllocator, PxCollection& inCollection ) + { + RepXCollectionImpl* theCollection = static_cast<RepXCollectionImpl*>( create(s, inAllocator, inCollection ) ); + theCollection->load( data, s ); + return theCollection; + } +} + + bool PxSerialization::serializeCollectionToXml( PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, PxCooking* cooking, const PxCollection* externalRefs, PxXmlMiscParameter* inArgs ) + { + if( !PxSerialization::isSerializable(collection, sr, const_cast<PxCollection*>(externalRefs)) ) + return false; + + bool bRet = true; + + SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr); + PxRepXInstantiationArgs args( sn.getPhysics(), cooking ); + + PxCollection* tmpCollection = PxCreateCollection(); + PX_ASSERT(tmpCollection); + + tmpCollection->add( collection ); + if(externalRefs) + { + tmpCollection->add(*const_cast<PxCollection*>(externalRefs)); + } + + PxAllocatorCallback& allocator = PxGetFoundation().getAllocatorCallback(); + Sn::RepXCollection* theRepXCollection = Sn::create(sn, allocator, *tmpCollection ); + + if(inArgs != NULL) + { + theRepXCollection->setTolerancesScale(inArgs->scale); + theRepXCollection->setUpVector(inArgs->upVector); + } + + PxU32 nbObjects = collection.getNbObjects(); + if( nbObjects ) + { + sortCollection( static_cast<Cm::Collection&>(collection), sn, true); + + for( PxU32 i = 0; i < nbObjects; i++ ) + { + PxBase& s = collection.getObject(i); + if( PxConcreteType::eSHAPE == s.getConcreteType() ) + { + PxShape& shape = static_cast<PxShape&>(s); + if( shape.isExclusive() ) + continue; + } + + PxSerialObjectId id = collection.getId(s); + if(id == PX_SERIAL_OBJECT_ID_INVALID) + id = static_cast<PxSerialObjectId>( reinterpret_cast<size_t>( &s )); + + PxRepXObject ro = PxCreateRepXObject( &s, id ); + if ( ro.serializable == NULL || ro.id == 0 ) + { + bRet = false; + break; + } + + theRepXCollection->addRepXObjectToCollection( ro, tmpCollection, args ); + } + } + tmpCollection->release(); + + theRepXCollection->save(outputStream); + theRepXCollection->destroy(); + + + return bRet; + } + + PxCollection* PxSerialization::createCollectionFromXml(PxInputData& inputData, PxCooking& cooking, PxSerializationRegistry& sr, const PxCollection* externalRefs, PxStringTable* stringTable, PxXmlMiscParameter* outArgs) + { + SerializationRegistry& sn = static_cast<SerializationRegistry&>(sr); + PxCollection* collection = PxCreateCollection(); + PX_ASSERT(collection); + + if( externalRefs ) + collection->add(*const_cast<PxCollection*>(externalRefs)); + + PxAllocatorCallback& allocator = PxGetFoundation().getAllocatorCallback(); + Sn::RepXCollection* theRepXCollection = Sn::create(sn, inputData, allocator, *collection); + theRepXCollection = &Sn::RepXUpgrader::upgradeCollection( *theRepXCollection ); + + PxRepXInstantiationArgs args( sn.getPhysics(), &cooking, stringTable ); + if( !theRepXCollection->instantiateCollection(args, *collection) ) + { + collection->release(); + theRepXCollection->destroy(); + return NULL; + } + + if( externalRefs ) + collection->remove(*const_cast<PxCollection*>(externalRefs)); + + if(outArgs != NULL) + { + outArgs->upVector = theRepXCollection->getUpVector(); + outArgs->scale = theRepXCollection->getTolerancesScale(); + } + + theRepXCollection->destroy(); + + return collection; + } +} diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerializer.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerializer.h new file mode 100644 index 00000000..9effab4f --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSerializer.h @@ -0,0 +1,117 @@ +// 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_XML_SERIALIZER_H +#define PX_XML_SERIALIZER_H + +#include "PxExtensionMetaDataObjects.h" +#include "SnXmlVisitorWriter.h" + +namespace physx { + +namespace Sn { + + void writeHeightFieldSample( PxOutputStream& inStream, const PxHeightFieldSample& inSample ) + { + PxU32 retval = 0; + PxU8* writePtr( reinterpret_cast< PxU8*>( &retval ) ); + const PxU8* inPtr( reinterpret_cast<const PxU8*>( &inSample ) ); + if ( isBigEndian() ) + { + //Height field samples are a + //16 bit integer followed by two bytes. + //right now, data is 2 1 3 4 + //We need a 32 bit integer that + //when read in by a LE system is 4 3 2 1. + //Thus, we need a BE integer that looks like: + //4 3 2 1 + + writePtr[0] = inPtr[3]; + writePtr[1] = inPtr[2]; + writePtr[2] = inPtr[0]; + writePtr[3] = inPtr[1]; + } + else + { + writePtr[0] = inPtr[0]; + writePtr[1] = inPtr[1]; + writePtr[2] = inPtr[2]; + writePtr[3] = inPtr[3]; + } + inStream << retval; + } + + + + template<typename TDataType, typename TWriteOperator> + inline void writeStridedBufferProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, const void* inData, PxU32 inStride, PxU32 inCount, PxU32 inItemsPerLine, TWriteOperator inOperator ) + { + PX_ASSERT( inStride == 0 || inStride == sizeof( TDataType ) ); + PX_UNUSED( inStride ); + writeBuffer( writer, tempBuffer + , inItemsPerLine, reinterpret_cast<const TDataType*>( inData ) + , inCount, inPropName, inOperator ); + } + + template<typename TDataType, typename TWriteOperator> + inline void writeStridedBufferProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, const PxStridedData& inData, PxU32 inCount, PxU32 inItemsPerLine, TWriteOperator inOperator ) + { + writeStridedBufferProperty<TDataType>( writer, tempBuffer, inPropName, inData.data, inData.stride, inCount, inItemsPerLine, inOperator ); + } + + template<typename TDataType, typename TWriteOperator> + inline void writeStridedBufferProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, const PxTypedStridedData<TDataType>& inData, PxU32 inCount, PxU32 inItemsPerLine, TWriteOperator inOperator ) + { + writeStridedBufferProperty<TDataType>( writer, tempBuffer, inPropName, inData.data, inData.stride, inCount, inItemsPerLine, inOperator ); + } + + template<typename TDataType, typename TWriteOperator> + inline void writeStridedBufferProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, const PxBoundedData& inData, PxU32 inItemsPerLine, TWriteOperator inWriteOperator ) + { + writeStridedBufferProperty<TDataType>( writer, tempBuffer, inPropName, inData, inData.count, inItemsPerLine, inWriteOperator ); + } + + template<typename TDataType, typename TWriteOperator> + inline void writeStridedBufferProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, PxStrideIterator<const TDataType>& inData, PxU32 inCount, PxU32 inItemsPerLine, TWriteOperator inWriteOperator ) + { + writeStrideBuffer<TDataType>(writer, tempBuffer + , inItemsPerLine, inData, PtrAccess<TDataType> + , inCount, inPropName, inData.stride(), inWriteOperator ); + } + + template<typename TDataType> + inline void writeStridedFlagsProperty( XmlWriter& writer, MemoryBuffer& tempBuffer, const char* inPropName, PxStrideIterator<const TDataType>& inData, PxU32 inCount, PxU32 inItemsPerLine, const PxU32ToName* inTable ) + { + writeStrideFlags<TDataType>(writer, tempBuffer + , inItemsPerLine, inData, PtrAccess<TDataType> + , inCount, inPropName, inTable ); + } + +} +} +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSimpleXmlWriter.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSimpleXmlWriter.h new file mode 100644 index 00000000..7ee771b8 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlSimpleXmlWriter.h @@ -0,0 +1,215 @@ +// 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_SIMPLEXMLWRITER_H +#define PX_SIMPLEXMLWRITER_H + +#include "PsArray.h" +#include "SnXmlMemoryPoolStreams.h" +#include "CmPhysXCommon.h" + +namespace physx { namespace Sn { + class XmlWriter + { + public: + + struct STagWatcher + { + typedef XmlWriter TXmlWriterType; + TXmlWriterType& mWriter; + STagWatcher( const STagWatcher& inOther ); + STagWatcher& operator-( const STagWatcher& inOther ); + STagWatcher( TXmlWriterType& inWriter, const char* inTagName ) + : mWriter( inWriter ) + { + mWriter.beginTag( inTagName ); + } + ~STagWatcher() { mWriter.endTag(); } + }; + + virtual ~XmlWriter(){} + virtual void beginTag( const char* inTagname ) = 0; + virtual void endTag() = 0; + virtual void addAttribute( const char* inName, const char* inValue ) = 0; + virtual void writeContentTag( const char* inTag, const char* inContent ) = 0; + virtual void addContent( const char* inContent ) = 0; + virtual PxU32 tabCount() = 0; + }; + + template<typename TStreamType> + class XmlWriterImpl : public XmlWriter + { + PxProfileAllocatorWrapper mWrapper; + TStreamType& mStream; + XmlWriterImpl( const XmlWriterImpl& inOther ); + XmlWriterImpl& operator=( const XmlWriterImpl& inOther ); + PxProfileArray<const char*> mTags; + bool mTagOpen; + PxU32 mInitialTagDepth; + public: + + XmlWriterImpl( TStreamType& inStream, PxAllocatorCallback& inAllocator, PxU32 inInitialTagDepth = 0 ) + : mWrapper( inAllocator ) + , mStream( inStream ) + , mTags( mWrapper ) + , mTagOpen( false ) + , mInitialTagDepth( inInitialTagDepth ) + { + } + virtual ~XmlWriterImpl() + { + while( mTags.size() ) + endTag(); + } + PxU32 tabCount() { return mTags.size() + mInitialTagDepth; } + + void writeTabs( PxU32 inSize ) + { + inSize += mInitialTagDepth; + for ( PxU32 idx =0; idx < inSize; ++idx ) + mStream << "\t"; + } + void beginTag( const char* inTagname ) + { + closeTag(); + writeTabs(mTags.size()); + mTags.pushBack( inTagname ); + mStream << "<" << inTagname; + mTagOpen = true; + } + void addAttribute( const char* inName, const char* inValue ) + { + PX_ASSERT( mTagOpen ); + mStream << " " << inName << "=" << "\"" << inValue << "\""; + } + void closeTag(bool useNewline = true) + { + if ( mTagOpen ) + { + mStream << " " << ">"; + if (useNewline ) + mStream << "\n"; + } + mTagOpen = false; + } + void doEndOpenTag() + { + mStream << "</" << mTags.back() << ">" << "\n"; + } + void endTag() + { + PX_ASSERT( mTags.size() ); + if ( mTagOpen ) + mStream << " " << "/>" << "\n"; + else + { + writeTabs(mTags.size()-1); + doEndOpenTag(); + } + mTagOpen = false; + mTags.popBack(); + } + void addContent( const char* inContent ) + { + closeTag(false); + mStream << inContent; + } + void writeContentTag( const char* inTag, const char* inContent ) + { + beginTag( inTag ); + addContent( inContent ); + doEndOpenTag(); + mTags.popBack(); + } + void insertXml( const char* inXml ) + { + closeTag(); + mStream << inXml; + } + }; + + struct BeginTag + { + const char* mTagName; + BeginTag( const char* inTagName ) + : mTagName( inTagName ) { } + }; + + struct EndTag + { + EndTag() {} + }; + + struct Att + { + const char* mAttName; + const char* mAttValue; + Att( const char* inAttName, const char* inAttValue ) + : mAttName( inAttName ) + , mAttValue( inAttValue ) { } + }; + + struct Content + { + const char* mContent; + Content( const char* inContent ) + : mContent( inContent ) { } + }; + + + struct ContentTag + { + const char* mTagName; + const char* mContent; + ContentTag( const char* inTagName, const char* inContent ) + : mTagName( inTagName ) + , mContent( inContent ) { } + }; + + inline XmlWriter& operator<<( XmlWriter& inWriter, const BeginTag& inTag ) { inWriter.beginTag( inTag.mTagName ); return inWriter; } + inline XmlWriter& operator<<( XmlWriter& inWriter, const EndTag& inTag ) { inWriter.endTag(); return inWriter; } + inline XmlWriter& operator<<( XmlWriter& inWriter, const Att& inTag ) { inWriter.addAttribute(inTag.mAttName, inTag.mAttValue); return inWriter; } + inline XmlWriter& operator<<( XmlWriter& inWriter, const Content& inTag ) { inWriter.addContent(inTag.mContent); return inWriter; } + inline XmlWriter& operator<<( XmlWriter& inWriter, const ContentTag& inTag ) { inWriter.writeContentTag(inTag.mTagName, inTag.mContent); return inWriter; } + + inline void writeProperty( XmlWriter& inWriter, MemoryBuffer& tempBuffer, const char* inPropName ) + { + PxU8 data = 0; + tempBuffer.write( &data, sizeof(PxU8) ); + inWriter.writeContentTag( inPropName, reinterpret_cast<const char*>( tempBuffer.mBuffer ) ); + tempBuffer.clear(); + } + + template<typename TDataType> + inline void writeProperty( XmlWriter& inWriter, MemoryBuffer& tempBuffer, const char* inPropName, TDataType inValue ) + { + tempBuffer << inValue; + writeProperty( inWriter, tempBuffer, inPropName ); + } +} } +#endif
\ No newline at end of file diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlStringToType.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlStringToType.h new file mode 100644 index 00000000..0361a2bf --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlStringToType.h @@ -0,0 +1,275 @@ +// 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_XML_STRINGTOTYPE_H +#define PX_XML_STRINGTOTYPE_H + +#include <stdio.h> +#include <ctype.h> +#include "PsString.h" +#include "PxCoreUtilityTypes.h" +#include "PxFiltering.h" + +//Remapping function name for gcc-based systems. +#ifndef _MSC_VER +#define _strtoui64 strtoull +#endif + + +namespace physx { namespace Sn { + + template<typename TDataType> + struct StrToImpl + { + bool compile_error; + }; + + template<> struct StrToImpl<PxU64> { + //Id's (void ptrs) are written to file as unsigned + //64 bit integers, so this method gets called more + //often than one might think. + PX_INLINE void strto( PxU64& ioDatatype,const char*& ioData ) + { + ioDatatype = _strtoui64( ioData, const_cast<char **>(&ioData), 10 ); + } + }; + + PX_INLINE PxF32 strToFloat(const char *str,const char **nextScan) + { + PxF32 ret; + while ( *str && isspace(static_cast<unsigned char>(*str))) str++; // skip leading whitespace + char temp[256] = ""; + char *dest = temp; + char *end = &temp[255]; + const char *begin = str; + while ( *str && !isspace(static_cast<unsigned char>(*str)) && dest < end ) // copy the number up to the first whitespace or eos + { + *dest++ = *str++; + } + *dest = 0; + ret = PxF32(strtod(temp,&end)); + if ( nextScan ) + { + *nextScan = begin+(end-temp); + } + return ret; + } + + + template<> struct StrToImpl<PxU32> { + PX_INLINE void strto( PxU32& ioDatatype,const char*& ioData ) + { + ioDatatype = static_cast<PxU32>( strtoul( ioData,const_cast<char **>(&ioData), 10 ) ); + } + }; + + template<> struct StrToImpl<PxI32> { + PX_INLINE void strto( PxI32& ioDatatype,const char*& ioData ) + { + ioDatatype = static_cast<PxI32>( strtoul( ioData,const_cast<char **>(&ioData), 10 ) ); + } + }; + + + template<> struct StrToImpl<PxU16> { + PX_INLINE void strto( PxU16& ioDatatype,const char*& ioData ) + { + ioDatatype = static_cast<PxU16>( strtoul( ioData,const_cast<char **>(&ioData), 10 ) ); + } + }; + + PX_INLINE void eatwhite(const char*& ioData ) + { + if ( ioData ) + { + while( isspace( static_cast<unsigned char>(*ioData) ) ) + ++ioData; + } + } + + // copy the source data to the dest buffer until the first whitespace is encountered. + // Do not overflow the buffer based on the bufferLen provided. + // Advance the input 'ioData' pointer so that it sits just at the next whitespace + PX_INLINE void nullTerminateWhite(const char*& ioData,char *buffer,PxU32 bufferLen) + { + if ( ioData ) + { + char *eof = buffer+(bufferLen-1); + char *dest = buffer; + while( *ioData && !isspace(static_cast<unsigned char>(*ioData)) && dest < eof ) + { + *dest++ = *ioData++; + } + *dest = 0; + } + } + + inline void nonNullTerminateWhite(const char*& ioData ) + { + if ( ioData ) + { + while( *ioData && !isspace( static_cast<unsigned char>(*ioData) ) ) + ++ioData; + } + } + + template<> struct StrToImpl<PxF32> { + inline void strto( PxF32& ioDatatype,const char*& ioData ) + { + ioDatatype = strToFloat(ioData,&ioData); + } + + }; + + + template<> struct StrToImpl<void*> { + inline void strto( void*& ioDatatype,const char*& ioData ) + { + PxU64 theData; + StrToImpl<PxU64>().strto( theData, ioData ); + ioDatatype = reinterpret_cast<void*>( static_cast<size_t>( theData ) ); + } + }; + + + template<> struct StrToImpl<physx::PxVec3> { + inline void strto( physx::PxVec3& ioDatatype,const char*& ioData ) + { + StrToImpl<PxF32>().strto( ioDatatype[0], ioData ); + StrToImpl<PxF32>().strto( ioDatatype[1], ioData ); + StrToImpl<PxF32>().strto( ioDatatype[2], ioData ); + } + }; + + template<> struct StrToImpl<PxU8*> { + inline void strto( PxU8*& /*ioDatatype*/,const char*& /*ioData*/) + { + } + }; + + template<> struct StrToImpl<bool> { + inline void strto( bool& ioType,const char*& inValue ) + { + ioType = physx::shdfnd::stricmp( inValue, "true" ) == 0 ? true : false; + } + }; + + template<> struct StrToImpl<PxU8> { + PX_INLINE void strto( PxU8& ioType,const char* & inValue) + { + ioType = static_cast<PxU8>( strtoul( inValue,const_cast<char **>(&inValue), 10 ) ); + } + }; + + template<> struct StrToImpl<PxFilterData> { + PX_INLINE void strto( PxFilterData& ioType,const char*& inValue) + { + ioType.word0 = static_cast<PxU32>( strtoul( inValue,const_cast<char **>(&inValue), 10 ) ); + ioType.word1 = static_cast<PxU32>( strtoul( inValue,const_cast<char **>(&inValue), 10 ) ); + ioType.word2 = static_cast<PxU32>( strtoul( inValue,const_cast<char **>(&inValue), 10 ) ); + ioType.word3 = static_cast<PxU32>( strtoul( inValue, NULL, 10 ) ); + } + }; + + + template<> struct StrToImpl<PxQuat> { + PX_INLINE void strto( PxQuat& ioType,const char*& inValue ) + { + ioType.x = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.y = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.z = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.w = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + } + }; + + template<> struct StrToImpl<PxTransform> { + PX_INLINE void strto( PxTransform& ioType,const char*& inValue) + { + ioType.q.x = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.q.y = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.q.z = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.q.w = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + + ioType.p[0] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.p[1] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.p[2] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + } + }; + + template<> struct StrToImpl<PxBounds3> { + PX_INLINE void strto( PxBounds3& ioType,const char*& inValue) + { + ioType.minimum[0] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.minimum[1] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.minimum[2] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + + ioType.maximum[0] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.maximum[1] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.maximum[2] = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + } + }; + + template<> struct StrToImpl<PxMetaDataPlane> { + PX_INLINE void strto( PxMetaDataPlane& ioType,const char*& inValue) + { + ioType.normal.x = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.normal.y = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.normal.z = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + ioType.distance = static_cast<PxReal>( strToFloat( inValue, &inValue ) ); + } + }; + + + template<> struct StrToImpl<PxRigidDynamic*> { + PX_INLINE void strto( PxRigidDynamic*& /*ioDatatype*/,const char*& /*ioData*/) + { + } + }; + + template<typename TDataType> + inline void strto( TDataType& ioType,const char*& ioData ) + { + if ( ioData && *ioData ) StrToImpl<TDataType>().strto( ioType, ioData ); + } + + template<typename TDataType> + inline void strtoLong( TDataType& ioType,const char*& ioData ) + { + if ( ioData && *ioData ) StrToImpl<TDataType>().strto( ioType, ioData ); + } + + template<typename TDataType> + inline void stringToType( const char* inValue, TDataType& ioType ) + { + const char* theValue( inValue ); + return strto( ioType, theValue ); + } + +} } + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorReader.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorReader.h new file mode 100644 index 00000000..e003edf0 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorReader.h @@ -0,0 +1,889 @@ +// 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_XML_VISITOR_READER_H +#define PX_XML_VISITOR_READER_H + +#include "PsArray.h" +#include "PsUtilities.h" +#include "RepXMetaDataPropertyVisitor.h" +#include "SnPxStreamOperators.h" +#include "SnXmlMemoryPoolStreams.h" +#include "SnXmlReader.h" +#include "SnXmlImpl.h" +#include "SnXmlMemoryAllocator.h" +#include "SnXmlStringToType.h" + +namespace physx { namespace Sn { + + + inline PxU32 findEnumByName( const char* inName, const PxU32ToName* inTable ) + { + for ( PxU32 idx = 0; inTable[idx].mName != NULL; ++idx ) + { + if ( physx::shdfnd::stricmp( inTable[idx].mName, inName ) == 0 ) + return inTable[idx].mValue; + } + return 0; + } + + PX_INLINE void stringToFlagsType( const char* strData, XmlMemoryAllocator& alloc, PxU32& ioType, const PxU32ToName* inTable ) + { + if ( inTable == NULL ) + return; + ioType = 0; + if ( strData && *strData) + { + //Destructively parse the string to get out the different flags. + char* theValue = const_cast<char*>( copyStr( &alloc, strData ) ); + char* theMarker = theValue; + char* theNext = theValue; + while( theNext && *theNext ) + { + ++theNext; + if( *theNext == '|' ) + { + *theNext = 0; + ++theNext; + ioType |= static_cast< PxU32 > ( findEnumByName( theMarker, inTable ) ); + theMarker = theNext; + } + } + if ( theMarker && *theMarker ) + ioType |= static_cast< PxU32 > ( findEnumByName( theMarker, inTable ) ); + alloc.deallocate( reinterpret_cast<PxU8*>( theValue ) ); + } + } + + template<typename TDataType> + PX_INLINE void stringToEnumType( const char* strData, TDataType& ioType, const PxU32ToName* inTable ) + { + ioType = static_cast<TDataType>( findEnumByName( strData, inTable ) ); + } + + template<typename TDataType> + PX_INLINE bool readProperty( XmlReader& inReader, const char* pname, TDataType& ioType ) + { + const char* value; + if ( inReader.read( pname, value ) ) + { + stringToType( value, ioType ); + return true; + } + return false; + } + + template<typename TObjType> + inline TObjType* findReferencedObject( PxCollection& collection, PxSerialObjectId id) + { + PX_ASSERT(id > 0); + TObjType* outObject = static_cast<TObjType*>(const_cast<PxBase*>(collection.find(id))); + if (outObject == NULL) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxSerialization::createCollectionFromXml: " + "Reference to ID %d cannot be resolved. Make sure externalRefs collection is specified if required and " + "check Xml file for completeness.", + id); + } + return outObject; + } + + template<typename TObjType> + inline bool readReference( XmlReader& inReader, PxCollection& collection, TObjType*& outObject ) + { + PxSerialObjectId theId; + const char* theValue = inReader.getCurrentItemValue(); + strto( theId, theValue ); + if( theId == 0) + { + // the NULL pointer is a valid pointer if the input id is 0 + outObject = NULL; + return true; + } + else + { + outObject = findReferencedObject<TObjType>(collection, theId); + return outObject != NULL; + } + } + + template<typename TObjType> + inline bool readReference( XmlReader& inReader, PxCollection& inCollection, const char* pname, TObjType*& outObject ) + { + outObject = NULL; + PxSerialObjectId theId = 0; + if (readProperty ( inReader, pname, theId ) && theId ) + { + outObject = findReferencedObject<TObjType>(inCollection, theId); + } + // the NULL pointer is a valid pointer if the input id is 0 + return (outObject != NULL) || 0 == theId; + } + + template<typename TEnumType, typename TStorageType> + inline bool readFlagsProperty( XmlReader& reader, XmlMemoryAllocator& allocator, const char* pname, const PxU32ToName* inConversions, PxFlags<TEnumType,TStorageType>& outFlags ) + { + const char* value; + if ( reader.read( pname, value ) ) + { + PxU32 tempValue = 0; + stringToFlagsType( value, allocator, tempValue, inConversions ); + outFlags = PxFlags<TEnumType,TStorageType>(Ps::to16(tempValue) ); + return true; + } + return false; + } + + template<typename TObjType, typename TReaderType, typename TInfoType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, TInfoType& info); + template<typename TObjType, typename TReaderType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj); + + template<typename TReaderType, typename TGeomType> + inline PxGeometry* parseGeometry( TReaderType& reader, TGeomType& /*inGeom*/) + { + PxAllocatorCallback& inAllocator = reader.mAllocator.getAllocator(); + + TGeomType* shape = PX_PLACEMENT_NEW((inAllocator.allocate(sizeof(TGeomType), "parseGeometry", __FILE__, __LINE__ )), TGeomType); + PxClassInfoTraits<TGeomType> info; + readComplexObj( reader, shape); + return shape; + } + + + template<typename TReaderType> + inline void parseShape( TReaderType& visitor, PxGeometry*& outResult, Ps::Array<PxMaterial*>& outMaterials) + { + XmlReader& theReader( visitor.mReader ); + PxCollection& collection = visitor.mCollection; + visitor.pushCurrentContext(); + if ( visitor.gotoTopName() ) + { + visitor.pushCurrentContext(); + if ( visitor.gotoChild( "Materials" ) ) + { + for( bool matSuccess = visitor.gotoFirstChild(); matSuccess; + matSuccess = visitor.gotoNextSibling() ) + { + PxMaterial* material = NULL; + if(!readReference<PxMaterial>( theReader, collection, material )) + visitor.mHadError = true; + if ( material ) + outMaterials.pushBack( material ); + } + } + visitor.popCurrentContext(); + visitor.pushCurrentContext(); + + PxPlaneGeometry plane; + PxHeightFieldGeometry heightField; + PxSphereGeometry sphere; + PxTriangleMeshGeometry mesh; + PxConvexMeshGeometry convex; + PxBoxGeometry box; + PxCapsuleGeometry capsule; + if ( visitor.gotoChild( "Geometry" ) ) + { + if ( visitor.gotoFirstChild() ) + { + const char* geomTypeName = visitor.getCurrentItemName(); + + if ( physx::shdfnd::stricmp( geomTypeName, "PxSphereGeometry" ) == 0 ) outResult = parseGeometry(visitor, sphere); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxPlaneGeometry" ) == 0 ) outResult = parseGeometry(visitor, plane); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxCapsuleGeometry" ) == 0 ) outResult = parseGeometry(visitor, capsule); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxBoxGeometry" ) == 0 ) outResult = parseGeometry(visitor, box); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxConvexMeshGeometry" ) == 0 ) outResult = parseGeometry(visitor, convex); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxTriangleMeshGeometry" ) == 0 ) outResult = parseGeometry(visitor, mesh); + else if ( physx::shdfnd::stricmp( geomTypeName, "PxHeightFieldGeometry" ) == 0 ) outResult = parseGeometry(visitor, heightField); + else + PX_ASSERT( false ); + } + } + visitor.popCurrentContext(); + } + visitor.popCurrentContext(); + + return; + } + + template<typename TReaderType, typename TObjType> + inline void readShapesProperty( TReaderType& visitor, TObjType* inObj, const PxRigidActorShapeCollection* inProp = NULL, bool isSharedShape = false ) + { + PX_UNUSED(isSharedShape); + PX_UNUSED(inProp); + + XmlReader& theReader( visitor.mReader ); + PxCollection& collection( visitor.mCollection ); + + visitor.pushCurrentContext(); + if ( visitor.gotoTopName() ) + { + //uggh working around the shape collection api. + //read out materials and geometry + for ( bool success = visitor.gotoFirstChild(); success; + success = visitor.gotoNextSibling() ) + { + if( 0 == physx::shdfnd::stricmp( visitor.getCurrentItemName(), "PxShapeRef" ) ) + { + PxShape* shape = NULL; + if(!readReference<PxShape>( theReader, collection, shape )) + visitor.mHadError = true; + if(shape) + inObj->attachShape( *shape ); + } + else + { + Ps::Array<PxMaterial*> materials; + PxGeometry* geometry = NULL; + parseShape( visitor, geometry, materials); + PxShape* theShape = NULL; + if ( materials.size() ) + { + theShape = visitor.mArgs.physics.createShape( *geometry, materials.begin(), Ps::to16(materials.size()), true ); + if ( theShape ) + { + readComplexObj( visitor, theShape ); + + if(theShape) + { + inObj->attachShape(*theShape); + collection.add( *theShape ); + } + } + } + + switch(geometry->getType()) + { + case PxGeometryType::eSPHERE : + static_cast<PxSphereGeometry*>(geometry)->~PxSphereGeometry(); + break; + case PxGeometryType::ePLANE : + static_cast<PxPlaneGeometry*>(geometry)->~PxPlaneGeometry(); + break; + case PxGeometryType::eCAPSULE : + static_cast<PxCapsuleGeometry*>(geometry)->~PxCapsuleGeometry(); + break; + case PxGeometryType::eBOX : + static_cast<PxBoxGeometry*>(geometry)->~PxBoxGeometry(); + break; + case PxGeometryType::eCONVEXMESH : + static_cast<PxConvexMeshGeometry*>(geometry)->~PxConvexMeshGeometry(); + break; + case PxGeometryType::eTRIANGLEMESH : + static_cast<PxTriangleMeshGeometry*>(geometry)->~PxTriangleMeshGeometry(); + break; + case PxGeometryType::eHEIGHTFIELD : + static_cast<PxHeightFieldGeometry*>(geometry)->~PxHeightFieldGeometry(); + break; + + case PxGeometryType::eGEOMETRY_COUNT: + case PxGeometryType::eINVALID: + PX_ASSERT(0); + } + visitor.mAllocator.getAllocator().deallocate(geometry); + } + } + } + visitor.popCurrentContext(); + } + + struct ReaderNameStackEntry : NameStackEntry + { + bool mValid; + ReaderNameStackEntry( const char* nm, bool valid ) : NameStackEntry(nm), mValid(valid) {} + }; + + typedef PxProfileArray<ReaderNameStackEntry> TReaderNameStack; + + template<typename TObjType> + struct RepXVisitorReaderBase + { + + protected: + RepXVisitorReaderBase<TObjType>& operator=(const RepXVisitorReaderBase<TObjType>&); + public: + TReaderNameStack& mNames; + PxProfileArray<PxU32>& mContexts; + PxRepXInstantiationArgs mArgs; + XmlReader& mReader; + TObjType* mObj; + XmlMemoryAllocator& mAllocator; + PxCollection& mCollection; + bool mValid; + bool& mHadError; + + RepXVisitorReaderBase( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, TObjType* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& hadError ) + : mNames( names ) + , mContexts( contexts ) + , mArgs( args ) + , mReader( reader ) + , mObj( obj ) + , mAllocator( alloc ) + , mCollection( collection ) + , mValid( true ) + , mHadError(hadError) + { + } + RepXVisitorReaderBase( const RepXVisitorReaderBase& other ) + : mNames( other.mNames ) + , mContexts( other.mContexts ) + , mArgs( other.mArgs ) + , mReader( other.mReader ) + , mObj( other.mObj ) + , mAllocator( other.mAllocator ) + , mCollection( other.mCollection ) + , mValid( other.mValid ) + , mHadError( other.mHadError ) + { + } + + + void pushName( const char* name ) + { + gotoTopName(); + mNames.pushBack( ReaderNameStackEntry( name, mValid ) ); + } + void pushBracketedName( const char* name ) { pushName( name ); } + void popName() + { + if ( mNames.size() ) + { + if ( mNames.back().mOpen && mNames.back().mValid ) + mReader.leaveChild(); + mNames.popBack(); + } + mValid =true; + if ( mNames.size() && mNames.back().mValid == false ) + mValid = false; + } + + void pushCurrentContext() + { + mContexts.pushBack( static_cast<PxU32>( mNames.size() ) ); + } + void popCurrentContext() + { + if ( mContexts.size() ) + { + PxU32 depth = mContexts.back(); + PX_ASSERT( mNames.size() >= depth ); + while( mNames.size() > depth ) + popName(); + mContexts.popBack(); + } + } + + bool updateLastEntryAfterOpen() + { + mNames.back().mValid = mValid; + mNames.back().mOpen = mValid; + return mValid; + } + + bool gotoTopName() + { + if ( mNames.size() && mNames.back().mOpen == false ) + { + if ( mValid ) + mValid = mReader.gotoChild( mNames.back().mName ); + updateLastEntryAfterOpen(); + } + return mValid; + } + + bool isValid() const { return mValid; } + + bool gotoChild( const char* name ) + { + pushName( name ); + return gotoTopName(); + } + + bool gotoFirstChild() + { + pushName( "__child" ); + if ( mValid ) mValid = mReader.gotoFirstChild(); + return updateLastEntryAfterOpen(); + } + + bool gotoNextSibling() + { + bool retval = mValid; + if ( mValid ) retval = mReader.gotoNextSibling(); + return retval; + } + + const char* getCurrentItemName() { if (mValid ) return mReader.getCurrentItemName(); return ""; } + + const char* topName() const + { + if ( mNames.size() ) return mNames.back().mName; + PX_ASSERT( false ); + return "bad__repx__name"; + } + + const char* getCurrentValue() + { + const char* value = NULL; + if ( isValid() && mReader.read( topName(), value ) ) + return value; + return NULL; + } + + template<typename TDataType> + bool readProperty(TDataType& outType) + { + const char* value = getCurrentValue(); + if ( value && *value ) + { + stringToType( value, outType ); + return true; + } + return false; + } + + template<typename TDataType> + bool readExtendedIndexProperty(TDataType& outType) + { + const char* value = mReader.getCurrentItemValue(); + if ( value && *value ) + { + stringToType( value, outType ); + return true; + } + return false; + } + + + template<typename TRefType> + bool readReference(TRefType*& outRef) + { + return physx::Sn::readReference<TRefType>( mReader, mCollection, topName(), outRef ); + } + + inline bool readProperty(const char*& outProp ) + { + outProp = ""; + const char* value = getCurrentValue(); + if ( value && *value && mArgs.stringTable ) + { + outProp = mArgs.stringTable->allocateStr( value ); + return true; + } + return false; + } + + inline bool readProperty(PxConvexMesh*& outProp ) + { + return readReference<PxConvexMesh>( outProp ); + } + + inline bool readProperty(PxTriangleMesh*& outProp ) + { + return readReference<PxTriangleMesh>( outProp ); + } + inline bool readProperty(PxBVH33TriangleMesh*& outProp ) + { + return readReference<PxBVH33TriangleMesh>( outProp ); + } + inline bool readProperty(PxBVH34TriangleMesh*& outProp ) + { + return readReference<PxBVH34TriangleMesh>( outProp ); + } + + inline bool readProperty(PxHeightField*& outProp ) + { + return readReference<PxHeightField>( outProp ); + } + + inline bool readProperty( PxRigidActor *& outProp ) + { + return readReference<PxRigidActor>( outProp ); + } + + template<typename TAccessorType> + void simpleProperty( PxU32 /*key*/, TAccessorType& inProp ) + { + typedef typename TAccessorType::prop_type TPropertyType; + TPropertyType value; + if ( readProperty( value ) ) + inProp.set( mObj, value ); + } + + template<typename TAccessorType> + void enumProperty( PxU32 /*key*/, TAccessorType& inProp, const PxU32ToName* inConversions ) + { + typedef typename TAccessorType::prop_type TPropertyType; + const char* strVal = getCurrentValue(); + if ( strVal && *strVal ) + { + TPropertyType pval; + stringToEnumType( strVal, pval, inConversions ); + inProp.set( mObj, pval ); + } + } + + template<typename TAccessorType> + void flagsProperty( PxU32 /*key*/, const TAccessorType& inProp, const PxU32ToName* inConversions ) + { + typedef typename TAccessorType::prop_type TPropertyType; + typedef typename TPropertyType::InternalType TInternalType; + + const char* strVal = getCurrentValue(); + if ( strVal && *strVal ) + { + PxU32 tempValue = 0; + stringToFlagsType( strVal, mAllocator, tempValue, inConversions ); + inProp.set( mObj, TPropertyType(TInternalType( tempValue ))); + } + } + + template<typename TAccessorType, typename TInfoType> + void complexProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + if ( gotoTopName() ) + { + TPropertyType propVal = inProp.get( mObj ); + readComplexObj( *this, &propVal, inInfo ); + inProp.set( mObj, propVal ); + } + } + + template<typename TAccessorType, typename TInfoType> + void bufferCollectionProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + Ps::InlineArray<TPropertyType,5> theData; + + this->pushCurrentContext(); + if ( this->gotoTopName() ) + { + for ( bool success = this->gotoFirstChild(); success; + success = this->gotoNextSibling() ) + { + TPropertyType propVal; + readComplexObj( *this, &propVal, inInfo ); + theData.pushBack(propVal); + } + } + this->popCurrentContext(); + + inProp.set( mObj, theData.begin(), theData.size() ); + + } + + template<typename TAccessorType, typename TInfoType> + void extendedIndexedProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + + this->pushCurrentContext(); + if ( this->gotoTopName() ) + { + PxU32 index = 0; + for ( bool success = this->gotoFirstChild(); success; + success = this->gotoNextSibling() ) + { + TPropertyType propVal; + readComplexObj( *this, &propVal, inInfo ); + inProp.set(mObj, index, propVal); + ++index; + } + } + this->popCurrentContext(); + } + + template<typename TAccessorType, typename TInfoType> + void PxFixedSizeLookupTableProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + const_cast<TAccessorType&>(inProp).clear( mObj ); + + this->pushCurrentContext(); + if ( this->gotoTopName() ) + { + for ( bool success = this->gotoFirstChild(); success; + success = this->gotoNextSibling() ) + { + TPropertyType propXVal; + readComplexObj( *this, &propXVal, inInfo ); + + if(this->gotoNextSibling()) + { + TPropertyType propYVal; + readComplexObj( *this, &propYVal, inInfo ); + const_cast<TAccessorType&>(inProp).addPair(mObj, propXVal, propYVal); + } + } + } + this->popCurrentContext(); + } + + void handleShapes( const PxRigidActorShapeCollection& inProp ) + { + physx::Sn::readShapesProperty( *this, mObj, &inProp ); + } + }; + + template<typename TObjType> + struct RepXVisitorReader : public RepXVisitorReaderBase<TObjType> + { + RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, TObjType* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret) + : RepXVisitorReaderBase<TObjType>( names, contexts, args, reader, obj, alloc, collection, ret) + { + } + RepXVisitorReader( const RepXVisitorReader<TObjType>& other ) + : RepXVisitorReaderBase<TObjType>( other ) + { + } + }; + + // Specialized template to load dynamic rigid, to determine the kinematic state first + template<> + struct RepXVisitorReader<PxRigidDynamic> : public RepXVisitorReaderBase<PxRigidDynamic> + { + RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, PxRigidDynamic* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret) + : RepXVisitorReaderBase<PxRigidDynamic>( names, contexts, args, reader, obj, alloc, collection, ret) + { + } + RepXVisitorReader( const RepXVisitorReader<PxRigidDynamic>& other ) + : RepXVisitorReaderBase<PxRigidDynamic>( other ) + { + } + + void handleShapes( const PxRigidActorShapeCollection& inProp ) + { + // Need to read the parental actor to check if actor is kinematic + // in that case we need to apply the kinematic flag before a shape is set + XmlReaderWriter* parentReader = static_cast<XmlReaderWriter*>(mReader.getParentReader()); + if(mObj) + { + const char* value; + if (parentReader->read( "RigidBodyFlags", value )) + { + if(strstr(value, "eKINEMATIC")) + { + mObj->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); + } + } + } + physx::Sn::readShapesProperty( *this, mObj, &inProp ); + parentReader->release(); + } + + + template<typename TAccessorType> + void simpleProperty( PxU32 /*key*/, TAccessorType& inProp ) + { + typedef typename TAccessorType::prop_type TPropertyType; + TPropertyType value; + if (readProperty(value)) + { + // If the rigid body is kinematic, we cannot set the LinearVelocity or AngularVelocity + const bool kinematic = (mObj->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC); + if(kinematic && (inProp.mProperty.mKey == PxPropertyInfoName::PxRigidBody_LinearVelocity || inProp.mProperty.mKey == PxPropertyInfoName::PxRigidBody_AngularVelocity)) + return; + + inProp.set(mObj, value ); + } + } + private: + RepXVisitorReader<PxRigidDynamic>& operator=(const RepXVisitorReader<PxRigidDynamic>&); + }; + + template<> + struct RepXVisitorReader<PxShape> : public RepXVisitorReaderBase<PxShape> + { + RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, PxShape* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret ) + : RepXVisitorReaderBase<PxShape>( names, contexts, args, reader, obj, alloc, collection, ret ) + { + } + RepXVisitorReader( const RepXVisitorReader<PxShape>& other ) + : RepXVisitorReaderBase<PxShape>( other ) + { + } + void handleShapeMaterials( const PxShapeMaterialsProperty& ) //these were handled during construction. + { + } + void handleGeometryProperty( const PxShapeGeometryProperty& ) + { + } + private: + RepXVisitorReader<PxShape>& operator=(const RepXVisitorReader<PxShape>&); + }; + + template<> + struct RepXVisitorReader<PxArticulationLink> : public RepXVisitorReaderBase<PxArticulationLink> + { + RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, PxArticulationLink* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret ) + : RepXVisitorReaderBase<PxArticulationLink>( names, contexts, args, reader, obj, alloc, collection, ret ) + { + } + RepXVisitorReader( const RepXVisitorReader<PxArticulationLink>& other ) + : RepXVisitorReaderBase<PxArticulationLink>( other ) + { + } + void handleIncomingJoint( const TIncomingJointPropType& prop ) + { + pushName( "Joint" ); + if ( gotoTopName() ) + { + PxArticulationJoint* theJoint( prop.get( mObj ) ); + readComplexObj( *this, theJoint ); + + //Add joint to PxCollection, since PxArticulation requires PxArticulationLink and joint. + mCollection.add( *theJoint ); + } + popName(); + } + private: + RepXVisitorReader<PxArticulationLink>& operator=(const RepXVisitorReader<PxArticulationLink>&); + }; + + inline void readProperty( RepXVisitorReaderBase<PxArticulation>& inSerializer, PxArticulation* inObj, const PxArticulationLinkCollectionProp& /*inProp*/) + { + PxProfileAllocatorWrapper theWrapper( inSerializer.mAllocator.getAllocator() ); + PxCollection& collection( inSerializer.mCollection ); + + TArticulationLinkLinkMap linkRemapMap( theWrapper ); + inSerializer.pushCurrentContext(); + if( inSerializer.gotoTopName() ) + { + for ( bool links = inSerializer.gotoFirstChild(); + links != false; + links = inSerializer.gotoNextSibling() ) + { + //Need enough information to create the link... + PxSerialObjectId theParentPtr = 0; + const PxArticulationLink* theParentLink = NULL; + if ( inSerializer.mReader.read( "Parent", theParentPtr ) ) + { + const TArticulationLinkLinkMap::Entry* theRemappedParent( linkRemapMap.find( theParentPtr ) ); + //If we have a valid at write time, we had better have a valid parent at read time. + PX_ASSERT( theRemappedParent ); + theParentLink = theRemappedParent->second; + } + PxArticulationLink* newLink = inObj->createLink( const_cast<PxArticulationLink*>( theParentLink ), PxTransform(PxIdentity) ); + PxSerialObjectId theIdPtr = 0; + inSerializer.mReader.read( "Id", theIdPtr ); + + linkRemapMap.insert( theIdPtr, newLink ); + readComplexObj( inSerializer, newLink ); + + //Add link to PxCollection, since PxArticulation requires PxArticulationLink and joint. + collection.add( *newLink, theIdPtr ); + } + } + inSerializer.popCurrentContext(); + } + + template<> + struct RepXVisitorReader<PxArticulation> : public RepXVisitorReaderBase<PxArticulation> + { + RepXVisitorReader( TReaderNameStack& names, PxProfileArray<PxU32>& contexts, const PxRepXInstantiationArgs& args, XmlReader& reader, PxArticulation* obj + , XmlMemoryAllocator& alloc, PxCollection& collection, bool& ret) + : RepXVisitorReaderBase<PxArticulation>( names, contexts, args, reader, obj, alloc, collection, ret) + { + } + RepXVisitorReader( const RepXVisitorReader<PxArticulation>& other ) + : RepXVisitorReaderBase<PxArticulation>( other ) + { + } + + void handleArticulationLinks( const PxArticulationLinkCollectionProp& inProp ) + { + physx::Sn::readProperty( *this, mObj, inProp ); + } + }; + + template<typename TObjType, typename TInfoType> + inline bool readAllProperties( PxRepXInstantiationArgs args, TReaderNameStack& names, PxProfileArray<PxU32>& contexts, XmlReader& reader, TObjType* obj, XmlMemoryAllocator& alloc, PxCollection& collection, TInfoType& info ) + { + bool hadError = false; + RepXVisitorReader<TObjType> theReader( names, contexts, args, reader, obj, alloc, collection, hadError); + RepXPropertyFilter<RepXVisitorReader<TObjType> > theOp( theReader ); + info.visitBaseProperties( theOp ); + info.visitInstanceProperties( theOp ); + return !hadError; + } + + + template<typename TObjType> + inline bool readAllProperties( PxRepXInstantiationArgs args, XmlReader& reader, TObjType* obj, XmlMemoryAllocator& alloc, PxCollection& collection ) + { + PxProfileAllocatorWrapper wrapper( alloc.getAllocator() ); + TReaderNameStack names( wrapper ); + PxProfileArray<PxU32> contexts( wrapper ); + PxClassInfoTraits<TObjType> info; + return readAllProperties( args, names, contexts, reader, obj, alloc, collection, info.Info ); + } + + template<typename TObjType, typename TReaderType, typename TInfoType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, TInfoType& info) + { + if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info )) + oldVisitor.mHadError = true; + } + + template<typename TObjType, typename TReaderType, typename TInfoType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, const TInfoType& info) + { + if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info )) + oldVisitor.mHadError = true; + } + + template<typename TObjType, typename TReaderType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj, const PxUnknownClassInfo& /*info*/) + { + const char* value = oldVisitor.mReader.getCurrentItemValue(); + if ( value && *value ) + { + stringToType( value, *inObj ); + return; + } + oldVisitor.mHadError = true; + } + + template<typename TObjType, typename TReaderType> + inline void readComplexObj( TReaderType& oldVisitor, TObjType* inObj) + { + PxClassInfoTraits<TObjType> info; + if(!readAllProperties( oldVisitor.mArgs, oldVisitor.mNames, oldVisitor.mContexts, oldVisitor.mReader, inObj, oldVisitor.mAllocator, oldVisitor.mCollection, info.Info )) + oldVisitor.mHadError = true; + } + +} } + +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorWriter.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorWriter.h new file mode 100644 index 00000000..76bf66cd --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlVisitorWriter.h @@ -0,0 +1,765 @@ +// 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_XML_VISITOR_WRITER_H +#define PX_XML_VISITOR_WRITER_H + +#include "PsInlineArray.h" +#include "CmPhysXCommon.h" +#include "RepXMetaDataPropertyVisitor.h" +#include "SnPxStreamOperators.h" +#include "SnXmlMemoryPoolStreams.h" +#include "SnXmlWriter.h" +#include "SnXmlImpl.h" +#include "PsFoundation.h" + +namespace physx { namespace Sn { + + template<typename TDataType> + inline void writeReference( XmlWriter& writer, PxCollection& inCollection, const char* inPropName, const TDataType* inDatatype ) + { + const PxBase* s = static_cast<const PxBase*>( inDatatype ) ; + if( inDatatype && !inCollection.contains( *const_cast<PxBase*>(s) )) + { + Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, + "PxSerialization::serializeCollectionToXml: Reference \"%s\" could not be resolved.", inPropName); + } + + PxSerialObjectId theId = 0; + if( s ) + { + theId = inCollection.getId( *s ); + if( theId == 0 ) + theId = PX_PROFILE_POINTER_TO_U64( inDatatype ); + } + + writer.write( inPropName, PxCreateRepXObject( inDatatype, theId ) ); + } + + inline void writeProperty( XmlWriter& inWriter, MemoryBuffer& inBuffer, const char* inProp ) + { + PxU8 data = 0; + inBuffer.write( &data, sizeof(PxU8) ); + inWriter.write( inProp, reinterpret_cast<const char*>( inBuffer.mBuffer ) ); + inBuffer.clear(); + } + + template<typename TDataType> + inline void writeProperty( XmlWriter& inWriter, PxCollection&, MemoryBuffer& inBuffer, const char* inPropName, TDataType inValue ) + { + inBuffer << inValue; + writeProperty( inWriter, inBuffer, inPropName ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxConvexMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxConvexMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } +#ifdef REMOVED + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxTriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxTriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } +#endif + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxBVH33TriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxBVH33TriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxBVH34TriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxBVH34TriangleMesh* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxHeightField* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxHeightField* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, const PxRigidActor* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxArticulation* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeProperty( XmlWriter& writer, PxCollection& inCollection, MemoryBuffer& /*inBuffer*/, const char* inPropName, PxRigidActor* inDatatype ) + { + writeReference( writer, inCollection, inPropName, inDatatype ); + } + + inline void writeFlagsProperty( XmlWriter& inWriter, MemoryBuffer& tempBuf, const char* inPropName, PxU32 inFlags, const PxU32ToName* inTable ) + { + if ( inTable ) + { + PxU32 flagValue( inFlags ); + if ( flagValue ) + { + for ( PxU32 idx =0; inTable[idx].mName != NULL; ++idx ) + { + if ( (inTable[idx].mValue & flagValue) == inTable[idx].mValue ) + { + if ( tempBuf.mWriteOffset != 0 ) + tempBuf << "|"; + tempBuf << inTable[idx].mName; + } + } + writeProperty( inWriter, tempBuf, inPropName ); + } + } + } + + inline void writeFlagsBuffer( MemoryBuffer& tempBuf, PxU32 flagValue, const PxU32ToName* inTable ) + { + PX_ASSERT(inTable); + bool added = false; + + if ( flagValue ) + { + for ( PxU32 item =0; inTable[item].mName != NULL; ++item ) + { + if ( (inTable[item].mValue & flagValue) != 0 ) + { + if ( added ) + tempBuf << "|"; + tempBuf << inTable[item].mName; + added = true; + } + } + } + } + + inline void writePxVec3( PxOutputStream& inStream, const PxVec3& inVec ) { inStream << inVec; } + + + template<typename TDataType> + inline const TDataType& PtrAccess( const TDataType* inPtr, PxU32 inIndex ) + { + return inPtr[inIndex]; + } + + template<typename TDataType> + inline void BasicDatatypeWrite( PxOutputStream& inStream, const TDataType& item ) { inStream << item; } + + template<typename TObjType, typename TAccessOperator, typename TWriteOperator> + inline void writeBuffer( XmlWriter& inWriter, MemoryBuffer& inTempBuffer + , PxU32 inObjPerLine, const TObjType* inObjType, TAccessOperator inAccessOperator + , PxU32 inBufSize, const char* inPropName, TWriteOperator inOperator ) + { + if ( inBufSize && inObjType ) + { + for ( PxU32 idx = 0; idx < inBufSize; ++idx ) + { + if ( idx && ( idx % inObjPerLine == 0 ) ) + inTempBuffer << "\n\t\t\t"; + else + inTempBuffer << " "; + inOperator( inTempBuffer, inAccessOperator( inObjType, idx ) ); + } + writeProperty( inWriter, inTempBuffer, inPropName ); + } + } + + template<typename TDataType, typename TAccessOperator, typename TWriteOperator> + inline void writeStrideBuffer( XmlWriter& inWriter, MemoryBuffer& inTempBuffer + , PxU32 inObjPerLine, PxStrideIterator<const TDataType>& inData, TAccessOperator inAccessOperator + , PxU32 inBufSize, const char* inPropName, PxU32 /*inStride*/, TWriteOperator inOperator ) + { + if ( inBufSize && &inData[0]) + { + for ( PxU32 idx = 0; idx < inBufSize; ++idx ) + { + if ( idx && ( idx % inObjPerLine == 0 ) ) + inTempBuffer << "\n\t\t\t"; + else + inTempBuffer << " "; + + inOperator( inTempBuffer, inAccessOperator( &inData[idx], 0 ) ); + } + writeProperty( inWriter, inTempBuffer, inPropName ); + } + } + + + template<typename TDataType, typename TAccessOperator> + inline void writeStrideFlags( XmlWriter& inWriter, MemoryBuffer& inTempBuffer + , PxU32 inObjPerLine, PxStrideIterator<const TDataType>& inData, TAccessOperator /*inAccessOperator*/ + , PxU32 inBufSize, const char* inPropName, const PxU32ToName* inTable) + { + if ( inBufSize && &inData[0]) + { + for ( PxU32 idx = 0; idx < inBufSize; ++idx ) + { + writeFlagsBuffer(inTempBuffer, inData[idx], inTable); + + if ( idx && ( idx % inObjPerLine == 0 ) ) + inTempBuffer << "\n\t\t\t"; + else + inTempBuffer << " "; + } + writeProperty( inWriter, inTempBuffer, inPropName ); + } + } + + template<typename TDataType, typename TWriteOperator> + inline void writeBuffer( XmlWriter& inWriter, MemoryBuffer& inTempBuffer + , PxU32 inObjPerLine, const TDataType* inBuffer + , PxU32 inBufSize, const char* inPropName, TWriteOperator inOperator ) + { + writeBuffer( inWriter, inTempBuffer, inObjPerLine, inBuffer, PtrAccess<TDataType>, inBufSize, inPropName, inOperator ); + } + + template<typename TEnumType> + inline void writeEnumProperty( XmlWriter& inWriter, const char* inPropName, TEnumType inEnumValue, const PxU32ToName* inConversions ) + { + PxU32 theValue = static_cast<PxU32>( inEnumValue ); + for ( const PxU32ToName* conv = inConversions; conv->mName != NULL; ++conv ) + if ( conv->mValue == theValue ) inWriter.write( inPropName, conv->mName ); + } + + + + template<typename TObjType, typename TWriterType, typename TInfoType> + inline void handleComplexObj( TWriterType& oldVisitor, const TObjType* inObj, TInfoType& info); + + template<typename TCollectionType, typename TVisitor, typename TPropType, typename TInfoType > + void handleComplexCollection( TVisitor& visitor, const TPropType& inProp, const char* childName, TInfoType& inInfo ) + { + PxU32 count( inProp.size( visitor.mObj ) ); + if ( count ) + { + Ps::InlineArray<TCollectionType*,5> theData; + theData.resize( count ); + inProp.get( visitor.mObj, theData.begin(), count ); + for( PxU32 idx =0; idx < count; ++idx ) + { + visitor.pushName( childName ); + handleComplexObj( visitor, theData[idx], inInfo ); + visitor.popName(); + } + } + } + + template<typename TCollectionType, typename TVisitor, typename TPropType, typename TInfoType > + void handleBufferCollection( TVisitor& visitor, const TPropType& inProp, const char* childName, TInfoType& inInfo ) + { + PxU32 count( inProp.size( visitor.mObj ) ); + if ( count ) + { + Ps::InlineArray<TCollectionType*,5> theData; + theData.resize( count ); + inProp.get( visitor.mObj, theData.begin()); + + for( PxU32 idx =0; idx < count; ++idx ) + { + visitor.pushName( childName ); + handleComplexObj( visitor, theData[idx], inInfo ); + visitor.popName(); + } + } + } + + template<typename TVisitor> + void handleShapes( TVisitor& visitor, const PxRigidActorShapeCollection& inProp ) + { + PxShapeGeneratedInfo theInfo; + + PxU32 count( inProp.size( visitor.mObj ) ); + if ( count ) + { + Ps::InlineArray<PxShape*,5> theData; + theData.resize( count ); + inProp.get( visitor.mObj, theData.begin(), count ); + for( PxU32 idx = 0; idx < count; ++idx ) + { + const PxShape* shape = theData[idx]; + visitor.pushName( "PxShape" ); + + if( !shape->isExclusive() ) + { + writeReference( visitor.mWriter, visitor.mCollection, "PxShapeRef", shape ); + } + else + { + handleComplexObj( visitor, shape, theInfo ); + } + visitor.popName(); + } + } + } + + template<typename TVisitor> + void handleShapeMaterials( TVisitor& visitor, const PxShapeMaterialsProperty& inProp ) + { + PxU32 count( inProp.size( visitor.mObj ) ); + if ( count ) + { + Ps::InlineArray<PxMaterial*,5> theData; + theData.resize( count ); + inProp.get( visitor.mObj, theData.begin(), count ); + visitor.pushName( "PxMaterialRef" ); + + for( PxU32 idx =0; idx < count; ++idx ) + writeReference( visitor.mWriter, visitor.mCollection, "PxMaterialRef", theData[idx] ); + visitor.popName(); + } + } + + template<typename TObjType> + struct RepXVisitorWriterBase + { + TNameStack& mNameStack; + XmlWriter& mWriter; + const TObjType* mObj; + MemoryBuffer& mTempBuffer; + PxCollection& mCollection; + + RepXVisitorWriterBase( TNameStack& ns, XmlWriter& writer, const TObjType* obj, MemoryBuffer& buf, PxCollection& collection ) + : mNameStack( ns ) + , mWriter( writer ) + , mObj( obj ) + , mTempBuffer( buf ) + , mCollection( collection ) + { + } + + RepXVisitorWriterBase( const RepXVisitorWriterBase<TObjType>& other ) + : mNameStack( other.mNameStack ) + , mWriter( other.mWriter ) + , mObj( other.mObj ) + , mTempBuffer( other.mTempBuffer ) + , mCollection( other.mCollection ) + { + } + + RepXVisitorWriterBase& operator=( const RepXVisitorWriterBase& ){ PX_ASSERT( false ); return *this; } + + void gotoTopName() + { + if ( mNameStack.size() && mNameStack.back().mOpen == false ) + { + mWriter.addAndGotoChild( mNameStack.back().mName ); + mNameStack.back().mOpen = true; + } + } + + void pushName( const char* inName ) + { + gotoTopName(); + mNameStack.pushBack( inName ); + } + + void pushBracketedName( const char* inName ) { pushName( inName ); } + void popName() + { + if ( mNameStack.size() ) + { + if ( mNameStack.back().mOpen ) + mWriter.leaveChild(); + mNameStack.popBack(); + } + } + + const char* topName() const + { + if ( mNameStack.size() ) return mNameStack.back().mName; + PX_ASSERT( false ); + return "bad__repx__name"; + } + + template<typename TAccessorType> + void simpleProperty( PxU32 /*key*/, TAccessorType& inProp ) + { + typedef typename TAccessorType::prop_type TPropertyType; + TPropertyType propVal = inProp.get( mObj ); + writeProperty( mWriter, mCollection, mTempBuffer, topName(), propVal ); + } + + template<typename TAccessorType> + void enumProperty( PxU32 /*key*/, TAccessorType& inProp, const PxU32ToName* inConversions ) + { + writeEnumProperty( mWriter, topName(), inProp.get( mObj ), inConversions ); + } + + template<typename TAccessorType> + void flagsProperty( PxU32 /*key*/, const TAccessorType& inProp, const PxU32ToName* inConversions ) + { + writeFlagsProperty( mWriter, mTempBuffer, topName(), inProp.get( mObj ), inConversions ); + } + + template<typename TAccessorType, typename TInfoType> + void complexProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + TPropertyType propVal = inProp.get( mObj ); + handleComplexObj( *this, &propVal, inInfo ); + } + + template<typename TAccessorType, typename TInfoType> + void bufferCollectionProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + + PxU32 count( inProp.size( mObj ) ); + Ps::InlineArray<TPropertyType,5> theData; + theData.resize( count ); + + PxClassInfoTraits<TInfoType> theTraits; + PX_UNUSED(theTraits); + PxU32 numItems = inProp.get( mObj, theData.begin(), count ); + PX_ASSERT( numItems == count ); + for( PxU32 idx =0; idx < numItems; ++idx ) + { + pushName( inProp.name() ); + handleComplexObj( *this, &theData[idx], inInfo ); + popName(); + } + } + + template<typename TAccessorType, typename TInfoType> + void extendedIndexedProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& /*inInfo */) + { + typedef typename TAccessorType::prop_type TPropertyType; + + PxU32 count( inProp.size( mObj ) ); + Ps::InlineArray<TPropertyType,5> theData; + theData.resize( count ); + + for(PxU32 i = 0; i < count; ++i) + { + char buffer[32] = { 0 }; + sprintf( buffer, "id_%u", i ); + pushName( buffer ); + + TPropertyType propVal = inProp.get( mObj, i ); + TInfoType& infoType = PxClassInfoTraits<TPropertyType>().Info; + handleComplexObj(*this, &propVal, infoType); + popName(); + } + } + + template<typename TAccessorType, typename TInfoType> + void PxFixedSizeLookupTableProperty( PxU32* /*key*/, TAccessorType& inProp, TInfoType& /*inInfo */) + { + typedef typename TAccessorType::prop_type TPropertyType; + PxU32 count( inProp.size( mObj ) ); + + PxU32 index = 0; + for(PxU32 i = 0; i < count; ++i) + { + char buffer[32] = { 0 }; + sprintf( buffer, "id_%u", index++ ); + pushName( buffer ); + TPropertyType propVal = inProp.getX( mObj , i); + writeProperty( mWriter, mCollection, mTempBuffer, topName(), propVal ); + popName(); + + sprintf( buffer, "id_%u", index++ ); + pushName( buffer ); + propVal = inProp.getY( mObj , i); + writeProperty( mWriter, mCollection, mTempBuffer, topName(), propVal ); + popName(); + } + } + + + void handleShapes( const PxRigidActorShapeCollection& inProp ) + { + physx::Sn::handleShapes( *this, inProp ); + } + + void handleShapeMaterials( const PxShapeMaterialsProperty& inProp ) + { + physx::Sn::handleShapeMaterials( *this, inProp ); + } + }; + + template<typename TObjType> + struct RepXVisitorWriter : RepXVisitorWriterBase<TObjType> + { + RepXVisitorWriter( TNameStack& ns, XmlWriter& writer, const TObjType* obj, MemoryBuffer& buf, PxCollection& collection ) + : RepXVisitorWriterBase<TObjType>( ns, writer, obj, buf, collection ) + { + } + + RepXVisitorWriter( const RepXVisitorWriter<TObjType>& other ) + : RepXVisitorWriterBase<TObjType>( other ) + { + } + }; + + template<> + struct RepXVisitorWriter<PxArticulationLink> : RepXVisitorWriterBase<PxArticulationLink> + { + RepXVisitorWriter( TNameStack& ns, XmlWriter& writer, const PxArticulationLink* obj, MemoryBuffer& buf, PxCollection& collection ) + : RepXVisitorWriterBase<PxArticulationLink>( ns, writer, obj, buf, collection ) + { + } + + RepXVisitorWriter( const RepXVisitorWriter<PxArticulationLink>& other ) + : RepXVisitorWriterBase<PxArticulationLink>( other ) + { + } + + void handleIncomingJoint( const TIncomingJointPropType& prop ) + { + const PxArticulationJoint* theJoint( prop.get( mObj ) ); + if ( theJoint ) + { + PxArticulationJointGeneratedInfo info; + pushName( "Joint" ); + handleComplexObj( *this, theJoint, info ); + popName(); + } + } + }; + + typedef PxProfileHashMap< const PxSerialObjectId, const PxArticulationLink* > TArticulationLinkLinkMap; + + template<> + struct RepXVisitorWriter<PxArticulation> : RepXVisitorWriterBase<PxArticulation> + { + TArticulationLinkLinkMap& mArticulationLinkParents; + + RepXVisitorWriter( TNameStack& ns, XmlWriter& writer, const PxArticulation* inArticulation, MemoryBuffer& buf, PxCollection& collection, TArticulationLinkLinkMap* artMap = NULL ) + : RepXVisitorWriterBase<PxArticulation>( ns, writer, inArticulation, buf, collection ) + , mArticulationLinkParents( *artMap ) + { + Ps::InlineArray<PxArticulationLink*, 64, PxProfileWrapperReflectionAllocator<PxArticulationLink*> > linkList( PxProfileWrapperReflectionAllocator<PxArticulationLink*>( buf.mManager->getWrapper() ) ); + PxU32 numLinks = inArticulation->getNbLinks(); + linkList.resize( numLinks ); + inArticulation->getLinks( linkList.begin(), numLinks ); + for ( PxU32 idx = 0; idx < numLinks; ++idx ) + { + const PxArticulationLink* theLink( linkList[idx] ); + + Ps::InlineArray<PxArticulationLink*, 64> theChildList; + PxU32 numChildren = theLink->getNbChildren(); + theChildList.resize( numChildren ); + theLink->getChildren( theChildList.begin(), numChildren ); + for ( PxU32 childIdx = 0; childIdx < numChildren; ++childIdx ) + mArticulationLinkParents.insert( PX_PROFILE_POINTER_TO_U64(theChildList[childIdx]), theLink ); + } + } + + RepXVisitorWriter( const RepXVisitorWriter<PxArticulation>& other ) + : RepXVisitorWriterBase<PxArticulation>( other ) + , mArticulationLinkParents( other.mArticulationLinkParents ) + { + } + template<typename TAccessorType, typename TInfoType> + void complexProperty( PxU32* /*key*/, const TAccessorType& inProp, TInfoType& inInfo ) + { + typedef typename TAccessorType::prop_type TPropertyType; + TPropertyType propVal = inProp.get( mObj ); + handleComplexObj( *this, &propVal, inInfo ); + } + + void writeArticulationLink( const PxArticulationLink* inLink ) + { + pushName( "PxArticulationLink" ); + gotoTopName(); + + const TArticulationLinkLinkMap::Entry* theParentPtr = mArticulationLinkParents.find( PX_PROFILE_POINTER_TO_U64(inLink) ); + if ( theParentPtr != NULL ) + writeProperty( mWriter, mCollection, mTempBuffer, "Parent", theParentPtr->second ); + writeProperty( mWriter, mCollection, mTempBuffer, "Id", inLink ); + + PxArticulationLinkGeneratedInfo info; + handleComplexObj( *this, inLink, info ); + popName(); + } + + void recurseAddLinkAndChildren( const PxArticulationLink* inLink, Ps::InlineArray<const PxArticulationLink*, 64>& ioLinks ) + { + ioLinks.pushBack( inLink ); + Ps::InlineArray<PxArticulationLink*, 8> theChildren; + PxU32 childCount( inLink->getNbChildren() ); + theChildren.resize( childCount ); + inLink->getChildren( theChildren.begin(), childCount ); + for ( PxU32 idx = 0; idx < childCount; ++idx ) + recurseAddLinkAndChildren( theChildren[idx], ioLinks ); + } + + void handleArticulationLinks( const PxArticulationLinkCollectionProp& inProp ) + { + //topologically sort the links as per my discussion with Dilip because + //links aren't guaranteed to have the parents before the children in the + //overall link list and it is unlikely to be done by beta 1. + PxU32 count( inProp.size( mObj ) ); + if ( count ) + { + Ps::InlineArray<PxArticulationLink*, 64> theLinks; + theLinks.resize( count ); + inProp.get( mObj, theLinks.begin(), count ); + + Ps::InlineArray<const PxArticulationLink*, 64> theSortedLinks; + for ( PxU32 idx = 0; idx < count; ++idx ) + { + const PxArticulationLink* theLink( theLinks[idx] ); + if ( mArticulationLinkParents.find( PX_PROFILE_POINTER_TO_U64(theLink) ) == NULL ) + recurseAddLinkAndChildren( theLink, theSortedLinks ); + } + PX_ASSERT( theSortedLinks.size() == count ); + for ( PxU32 idx = 0; idx < count; ++idx ) + writeArticulationLink( theSortedLinks[idx] ); + popName(); + } + } + private: + RepXVisitorWriter<PxArticulation>& operator=(const RepXVisitorWriter<PxArticulation>&); + }; + + template<> + struct RepXVisitorWriter<PxShape> : RepXVisitorWriterBase<PxShape> + { + RepXVisitorWriter( TNameStack& ns, XmlWriter& writer, const PxShape* obj, MemoryBuffer& buf, PxCollection& collection ) + : RepXVisitorWriterBase<PxShape>( ns, writer, obj, buf, collection ) + { + } + + RepXVisitorWriter( const RepXVisitorWriter<PxShape>& other ) + : RepXVisitorWriterBase<PxShape>( other ) + { + } + + template<typename GeometryType> + inline void writeGeometryProperty( const PxShapeGeometryProperty& inProp, const char* inTypeName ) + { + pushName( "Geometry" ); + pushName( inTypeName ); + GeometryType theType; + inProp.getGeometry( mObj, theType ); + PxClassInfoTraits<GeometryType> theTraits; + PxU32 count = theTraits.Info.totalPropertyCount(); + if(count) + { + handleComplexObj( *this, &theType, theTraits.Info); + } + else + { + writeProperty(mWriter, mTempBuffer, inTypeName); + } + popName(); + popName(); + } + + void handleGeometryProperty( const PxShapeGeometryProperty& inProp ) + { + switch( mObj->getGeometryType() ) + { + case PxGeometryType::eSPHERE: writeGeometryProperty<PxSphereGeometry>( inProp, "PxSphereGeometry" ); break; + case PxGeometryType::ePLANE: writeGeometryProperty<PxPlaneGeometry>( inProp, "PxPlaneGeometry" ); break; + case PxGeometryType::eCAPSULE: writeGeometryProperty<PxCapsuleGeometry>( inProp, "PxCapsuleGeometry" ); break; + case PxGeometryType::eBOX: writeGeometryProperty<PxBoxGeometry>( inProp, "PxBoxGeometry" ); break; + case PxGeometryType::eCONVEXMESH: writeGeometryProperty<PxConvexMeshGeometry>( inProp, "PxConvexMeshGeometry" ); break; + case PxGeometryType::eTRIANGLEMESH: writeGeometryProperty<PxTriangleMeshGeometry>( inProp, "PxTriangleMeshGeometry" ); break; + case PxGeometryType::eHEIGHTFIELD: writeGeometryProperty<PxHeightFieldGeometry>( inProp, "PxHeightFieldGeometry" ); break; + case PxGeometryType::eINVALID: + case PxGeometryType::eGEOMETRY_COUNT: + PX_ASSERT( false ); + } + } + }; + + template<typename TObjType> + inline void writeAllProperties( TNameStack& inNameStack, const TObjType* inObj, XmlWriter& writer, MemoryBuffer& buffer, PxCollection& collection ) + { + RepXVisitorWriter<TObjType> newVisitor( inNameStack, writer, inObj, buffer, collection ); + RepXPropertyFilter<RepXVisitorWriter<TObjType> > theOp( newVisitor ); + PxClassInfoTraits<TObjType> info; + info.Info.visitBaseProperties( theOp ); + info.Info.visitInstanceProperties( theOp ); + } + + template<typename TObjType> + inline void writeAllProperties( TNameStack& inNameStack, TObjType* inObj, XmlWriter& writer, MemoryBuffer& buffer, PxCollection& collection ) + { + RepXVisitorWriter<TObjType> newVisitor( inNameStack, writer, inObj, buffer, collection ); + RepXPropertyFilter<RepXVisitorWriter<TObjType> > theOp( newVisitor ); + PxClassInfoTraits<TObjType> info; + info.Info.visitBaseProperties( theOp ); + info.Info.visitInstanceProperties( theOp ); + } + + template<typename TObjType> + inline void writeAllProperties( const TObjType* inObj, XmlWriter& writer, MemoryBuffer& buffer, PxCollection& collection ) + { + TNameStack theNames( buffer.mManager->getWrapper() ); + writeAllProperties( theNames, inObj, writer, buffer, collection ); + } + + template<typename TObjType, typename TWriterType, typename TInfoType> + inline void handleComplexObj( TWriterType& oldVisitor, const TObjType* inObj, const TInfoType& /*info*/) + { + writeAllProperties( oldVisitor.mNameStack, inObj, oldVisitor.mWriter, oldVisitor.mTempBuffer, oldVisitor.mCollection ); + } + + template<typename TObjType, typename TWriterType, typename TInfoType> + inline void handleComplexObj( TWriterType& oldVisitor, const TObjType* inObj, TInfoType& /*info*/) + { + writeAllProperties( oldVisitor.mNameStack, inObj, oldVisitor.mWriter, oldVisitor.mTempBuffer, oldVisitor.mCollection ); + } + + template<typename TObjType, typename TWriterType> + inline void handleComplexObj( TWriterType& oldVisitor, const TObjType* inObj, const PxUnknownClassInfo& /*info*/) + { + writeProperty( oldVisitor.mWriter, oldVisitor.mCollection, oldVisitor.mTempBuffer, oldVisitor.topName(), *inObj ); + } + +} } +#endif diff --git a/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlWriter.h b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlWriter.h new file mode 100644 index 00000000..afea8aa0 --- /dev/null +++ b/PhysX_3.4/Source/PhysXExtensions/src/serialization/Xml/SnXmlWriter.h @@ -0,0 +1,57 @@ +// 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_XML_WRITER_H +#define PX_XML_WRITER_H + +#include "foundation/PxSimpleTypes.h" + +namespace physx { + + struct PxRepXObject; + + /** + * Writer used by extensions to write elements to a file or database + */ + class XmlWriter + { + protected: + virtual ~XmlWriter(){} + public: + /** Write a key-value pair into the current item */ + virtual void write( const char* inName, const char* inData ) = 0; + /** Write an object id into the current item */ + virtual void write( const char* inName, const PxRepXObject& inLiveObject ) = 0; + /** Add a child that then becomes the current context */ + virtual void addAndGotoChild( const char* inName ) = 0; + /** Leave the current child */ + virtual void leaveChild() = 0; + }; +} + +#endif |