Example #1
0
PxRigidActor* CPhysicManager::createFromFile(const std::string &file, int group, const IPhysic *component)
{
    assert(m_scene);

    PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*m_physics);
    PxDefaultFileInputData data(file.c_str());
    PxCollection* collection;

    collection = PxSerialization::createCollectionFromXml(data, *m_cooking, *registry);

    m_scene->addCollection(*collection);

    PxRigidActor *actor = nullptr;
    for (unsigned int i=0; (i<collection->getNbObjects()) && !actor; i++) {
        actor = collection->getObject(i).is<PxRigidActor>();
    }
    assert(actor);

    actor->userData = (void*)component;

    PxSetGroup(*actor,group);

    collection->release();
    registry->release();

    return actor;
}
Example #2
0
PxRigidActor* CServer::createFromFile(const std::string &file, int group, const IPhysics *component)
{
	assert(_scene);

	// Preparar parámetros para deserializar
	PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*_physics); 
	PxDefaultFileInputData data(file.c_str());
	PxCollection* collection;

	// Deserializar a partir del fichero RepX
	collection = PxSerialization::createCollectionFromXml(data, *_cooking, *registry);
	
	// Añadir entidades físicas a la escena
	_scene->addCollection(*collection); 
	
	// Buscar una entidad de tipo PxRigidActor. Asumimos que hay exactamente 1 en el fichero.
	PxRigidActor *actor = NULL;
	for (unsigned int i=0; (i<collection->getNbObjects()) && !actor; i++) {
		actor = collection->getObject(i).is<PxRigidActor>();		
	}
	assert(actor);
	
	// Anotar el componente lógico asociado a la entidad física
	actor->userData = (void *) component;

	// Establecer el grupo de colisión
	PxSetGroup(*actor, group);

	// Liberar recursos
	collection->release();
	registry->release();

	return actor;
}
SIZE_T GetPhysxObjectSize(PxBase* Obj, const PxCollection* SharedCollection)
{
	PxSerializationRegistry* Sr = PxSerialization::createSerializationRegistry(*GPhysXSDK);
	PxCollection* Collection = PxCreateCollection();

	Collection->add(*Obj);
	PxSerialization::complete(*Collection, *Sr, SharedCollection);	// chase all other stuff (shared shaps, materials, etc) needed to serialize this collection

	FPhysXCountMemoryStream Out;
	PxSerialization::serializeCollectionToBinary(Out, *Collection, *Sr, SharedCollection);

	Collection->release();
	Sr->release();

	return Out.UsedMemory;
}
void PxUnregisterPhysicsSerializers(PxSerializationRegistry& sr)
{
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eCONVEX_MESH));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eTRIANGLE_MESH_BVH33));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eTRIANGLE_MESH_BVH34));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eHEIGHTFIELD));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eRIGID_DYNAMIC));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eRIGID_STATIC));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eSHAPE));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eMATERIAL));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eCONSTRAINT));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eAGGREGATE));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eARTICULATION));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eARTICULATION_LINK));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eARTICULATION_JOINT));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::ePRUNING_STRUCTURE));
	
#if PX_USE_CLOTH_API
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eCLOTH));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::eCLOTH_FABRIC));
#endif

#if PX_USE_PARTICLE_SYSTEM_API
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::ePARTICLE_SYSTEM));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxConcreteType::ePARTICLE_FLUID));
#endif
}
void PxRegisterPhysicsSerializers(PxSerializationRegistry& sr)
{
	sr.registerSerializer(PxConcreteType::eCONVEX_MESH,			PX_NEW_SERIALIZER_ADAPTER(ConvexMesh));
	sr.registerSerializer(PxConcreteType::eTRIANGLE_MESH_BVH33,	PX_NEW_SERIALIZER_ADAPTER(RTreeTriangleMesh));
	sr.registerSerializer(PxConcreteType::eTRIANGLE_MESH_BVH34,	PX_NEW_SERIALIZER_ADAPTER(BV4TriangleMesh));
	sr.registerSerializer(PxConcreteType::eHEIGHTFIELD,			PX_NEW_SERIALIZER_ADAPTER(HeightField));
	sr.registerSerializer(PxConcreteType::eRIGID_DYNAMIC,		PX_NEW_SERIALIZER_ADAPTER(NpRigidDynamic));
	sr.registerSerializer(PxConcreteType::eRIGID_STATIC,		PX_NEW_SERIALIZER_ADAPTER(NpRigidStatic));
	sr.registerSerializer(PxConcreteType::eSHAPE,				PX_NEW_SERIALIZER_ADAPTER(NpShape));
	sr.registerSerializer(PxConcreteType::eMATERIAL,			PX_NEW_SERIALIZER_ADAPTER(NpMaterial));
	sr.registerSerializer(PxConcreteType::eCONSTRAINT,			PX_NEW_SERIALIZER_ADAPTER(NpConstraint));
	sr.registerSerializer(PxConcreteType::eAGGREGATE,			PX_NEW_SERIALIZER_ADAPTER(NpAggregate));
	sr.registerSerializer(PxConcreteType::eARTICULATION,		PX_NEW_SERIALIZER_ADAPTER(NpArticulation));
	sr.registerSerializer(PxConcreteType::eARTICULATION_LINK,	PX_NEW_SERIALIZER_ADAPTER(NpArticulationLink));
	sr.registerSerializer(PxConcreteType::eARTICULATION_JOINT,	PX_NEW_SERIALIZER_ADAPTER(NpArticulationJoint));
	sr.registerSerializer(PxConcreteType::ePRUNING_STRUCTURE,	PX_NEW_SERIALIZER_ADAPTER(Sq::PruningStructure));
	
#if PX_USE_CLOTH_API
	sr.registerSerializer(PxConcreteType::eCLOTH,				PX_NEW_SERIALIZER_ADAPTER(NpCloth));
	sr.registerSerializer(PxConcreteType::eCLOTH_FABRIC,		PX_NEW_SERIALIZER_ADAPTER(NpClothFabric));
#endif

#if PX_USE_PARTICLE_SYSTEM_API
	sr.registerSerializer(PxConcreteType::ePARTICLE_SYSTEM,		PX_NEW_SERIALIZER_ADAPTER(NpParticleSystem));
	sr.registerSerializer(PxConcreteType::ePARTICLE_FLUID,		PX_NEW_SERIALIZER_ADAPTER(NpParticleFluid));
#endif

}
void FPhysxSharedData::DumpSharedMemoryUsage(FOutputDevice* Ar)
{
	struct FSharedResourceEntry
	{
		uint64 MemorySize;
		uint64 Count;
	};

	struct FSortBySize
	{
		FORCEINLINE bool operator()( const FSharedResourceEntry& A, const FSharedResourceEntry& B ) const 
		{ 
			// Sort descending
			return B.MemorySize < A.MemorySize;
		}
	};

	TMap<FString, FSharedResourceEntry> AllocationsByType;

	uint64 OverallSize = 0;
	int32 OverallCount = 0;

	TMap<FString, TArray<PxBase*> > ObjectsByType;

	for (int32 i=0; i < (int32)SharedObjects->getNbObjects(); ++i)
	{
		PxBase& Obj = SharedObjects->getObject(i);
		FString TypeName = ANSI_TO_TCHAR(Obj.getConcreteTypeName());

		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		if (ObjectsArray == NULL)
		{
			ObjectsByType.Add(TypeName, TArray<PxBase*>());
			ObjectsArray = ObjectsByType.Find(TypeName);
		}

		check(ObjectsArray);
		ObjectsArray->Add(&Obj);
	}

	TArray<FString> TypeNames;
	ObjectsByType.GetKeys(TypeNames);

	for (int32 TypeIdx=0; TypeIdx < TypeNames.Num(); ++TypeIdx)
	{
		const FString& TypeName = TypeNames[TypeIdx];
		
		TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName);
		check(ObjectsArray);

		PxSerializationRegistry* Sr = PxSerialization::createSerializationRegistry(*GPhysXSDK);
		PxCollection* Collection = PxCreateCollection();
		
		for (int32 i=0; i < ObjectsArray->Num(); ++i)
		{
			Collection->add(*((*ObjectsArray)[i]));;
		}

		PxSerialization::complete(*Collection, *Sr);	// chase all other stuff (shared shaps, materials, etc) needed to serialize this collection

		FPhysXCountMemoryStream Out;
		PxSerialization::serializeCollectionToBinary(Out, *Collection, *Sr);

		Collection->release();
		Sr->release();

		OverallSize += Out.UsedMemory;
		OverallCount += ObjectsArray->Num();

		FSharedResourceEntry NewEntry;
		NewEntry.Count = ObjectsArray->Num();
		NewEntry.MemorySize = Out.UsedMemory;

		AllocationsByType.Add(TypeName, NewEntry);
	}

	Ar->Logf(TEXT(""));
	Ar->Logf(TEXT("Shared Resources:"));
	Ar->Logf(TEXT(""));

	AllocationsByType.ValueSort(FSortBySize());
	
	Ar->Logf(TEXT("%-10d %s (%d)"), OverallSize, TEXT("Overall"), OverallCount );
	
	for( auto It=AllocationsByType.CreateConstIterator(); It; ++It )
	{
		Ar->Logf(TEXT("%-10d %s (%d)"), It.Value().MemorySize, *It.Key(), It.Value().Count );
	}
}
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 %llu 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;
}
bool PxSerialization::isSerializable(PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalReferences) 
{		
	bool bRet = true;	

	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__, 
						"NpCollection::isSerializable: object shares reference name with other object in externalReferences (reference clash).");
					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);
	}
	
	for(PxU32 j = 0; j < subordinateCollection->getNbObjects(); ++j)
	{
		PxBase& subordinate = subordinateCollection->getObject(j);
		bRet = requiresCollection->contains(subordinate);
		if(!bRet)
		{
			requiresCollection->release();
			subordinateCollection->release();
			Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
				"NpCollection::isSerializable: object is a subordinate and not required by other objects in the collection (orphan).");
			return false;		
		}
	}
	subordinateCollection->release();

	for(PxU32 j = 0; j < requiresCollection->getNbObjects(); ++j)
	{
		PxBase& s0 = requiresCollection->getObject(j);
		bRet = collection.contains(s0);
		if(!bRet && externalReferences)
		{
			bRet = externalReferences->contains(s0) &&  externalReferences->getId(s0) != PX_SERIAL_OBJECT_ID_INVALID;
		}
		if(!bRet)
		{
			requiresCollection->release();
			Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
				"NpCollection::isSerializable: cannot find a required serial object (collection is not complete).");
			return false;
		}
	}
	requiresCollection->release();

	if(externalReferences)
	{
		PxCollection* oppsiteRequiresCollection = PxCreateCollection();
		PX_ASSERT(oppsiteRequiresCollection);

		RequiresCallback requiresCallback(*oppsiteRequiresCollection);

		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);
		}

		for(PxU32 j = 0; j < oppsiteRequiresCollection->getNbObjects(); ++j)
		{
			PxBase& s0 = oppsiteRequiresCollection->getObject(j);

			if(collection.contains(s0))
			{
				oppsiteRequiresCollection->release();
				Ps::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
					"NpCollection::isSerializable: object in externalReferences requires an object in collection (circular dependency).");
				return false;
			}
		}
		oppsiteRequiresCollection->release();
	}

	return true;
}
void Ext::UnregisterExtensionsSerializers(PxSerializationRegistry& sr)
{
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::eFIXED));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::eDISTANCE));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::eD6 ));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::ePRISMATIC));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::eREVOLUTE));
	PX_DELETE_SERIALIZER_ADAPTER(sr.unregisterSerializer(PxJointConcreteType::eSPHERICAL));

	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eMATERIAL));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eSHAPE));	
//	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eTRIANGLE_MESH));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eTRIANGLE_MESH_BVH33));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eTRIANGLE_MESH_BVH34));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eHEIGHTFIELD));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eCONVEX_MESH));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eRIGID_STATIC));	
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eRIGID_DYNAMIC));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eARTICULATION));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eAGGREGATE));
	
#if PX_USE_CLOTH_API
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eCLOTH_FABRIC));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::eCLOTH));
#endif
#if PX_USE_PARTICLE_SYSTEM_API
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::ePARTICLE_SYSTEM));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxConcreteType::ePARTICLE_FLUID));
#endif
	
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::eFIXED));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::eDISTANCE));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::eD6));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::ePRISMATIC));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::eREVOLUTE));
	PX_DELETE_REPX_SERIALIZER(sr.unregisterRepXSerializer(PxJointConcreteType::eSPHERICAL));
}
void Ext::RegisterExtensionsSerializers(PxSerializationRegistry& sr)
{
	//for repx serialization
	sr.registerRepXSerializer(PxConcreteType::eMATERIAL,			PX_NEW_REPX_SERIALIZER( PxMaterialRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eSHAPE,				PX_NEW_REPX_SERIALIZER( PxShapeRepXSerializer ));	
//	sr.registerRepXSerializer(PxConcreteType::eTRIANGLE_MESH,		PX_NEW_REPX_SERIALIZER( PxTriangleMeshRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eTRIANGLE_MESH_BVH33,	PX_NEW_REPX_SERIALIZER( PxBVH33TriangleMeshRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eTRIANGLE_MESH_BVH34,	PX_NEW_REPX_SERIALIZER( PxBVH34TriangleMeshRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eHEIGHTFIELD,			PX_NEW_REPX_SERIALIZER( PxHeightFieldRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eCONVEX_MESH,			PX_NEW_REPX_SERIALIZER( PxConvexMeshRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eRIGID_STATIC,		PX_NEW_REPX_SERIALIZER( PxRigidStaticRepXSerializer ));	
	sr.registerRepXSerializer(PxConcreteType::eRIGID_DYNAMIC,		PX_NEW_REPX_SERIALIZER( PxRigidDynamicRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eARTICULATION,		PX_NEW_REPX_SERIALIZER( PxArticulationRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eAGGREGATE,			PX_NEW_REPX_SERIALIZER( PxAggregateRepXSerializer ));
	
#if PX_USE_CLOTH_API
	sr.registerRepXSerializer(PxConcreteType::eCLOTH_FABRIC,		PX_NEW_REPX_SERIALIZER( PxClothFabricRepXSerializer ));
	sr.registerRepXSerializer(PxConcreteType::eCLOTH,				PX_NEW_REPX_SERIALIZER( PxClothRepXSerializer ));
#endif
#if PX_USE_PARTICLE_SYSTEM_API
	sr.registerRepXSerializer(PxConcreteType::ePARTICLE_SYSTEM,		PX_NEW_REPX_SERIALIZER( PxParticleRepXSerializer<PxParticleSystem> ));
	sr.registerRepXSerializer(PxConcreteType::ePARTICLE_FLUID,		PX_NEW_REPX_SERIALIZER( PxParticleRepXSerializer<PxParticleFluid> ));
#endif
	
	sr.registerRepXSerializer(PxJointConcreteType::eFIXED,			PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxFixedJoint> ));
	sr.registerRepXSerializer(PxJointConcreteType::eDISTANCE,		PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxDistanceJoint> ));
	sr.registerRepXSerializer(PxJointConcreteType::eD6,				PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxD6Joint> ));
	sr.registerRepXSerializer(PxJointConcreteType::ePRISMATIC,		PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxPrismaticJoint> ));
	sr.registerRepXSerializer(PxJointConcreteType::eREVOLUTE,		PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxRevoluteJoint> ));
	sr.registerRepXSerializer(PxJointConcreteType::eSPHERICAL,		PX_NEW_REPX_SERIALIZER( PxJointRepXSerializer<PxSphericalJoint> ));

	//for binary serialization
	sr.registerSerializer(PxJointConcreteType::eFIXED,				PX_NEW_SERIALIZER_ADAPTER( FixedJoint ));
	sr.registerSerializer(PxJointConcreteType::eDISTANCE,			PX_NEW_SERIALIZER_ADAPTER( DistanceJoint ));
	sr.registerSerializer(PxJointConcreteType::eD6,					PX_NEW_SERIALIZER_ADAPTER( D6Joint) );
	sr.registerSerializer(PxJointConcreteType::ePRISMATIC,			PX_NEW_SERIALIZER_ADAPTER( PrismaticJoint ));
	sr.registerSerializer(PxJointConcreteType::eREVOLUTE,			PX_NEW_SERIALIZER_ADAPTER( RevoluteJoint ));
	sr.registerSerializer(PxJointConcreteType::eSPHERICAL,			PX_NEW_SERIALIZER_ADAPTER( SphericalJoint ));
}
	virtual bool SerializeActors(FName Format, const TArray<FBodyInstance*>& Bodies, const TArray<UBodySetup*>& BodySetups, const TArray<UPhysicalMaterial*>& PhysicalMaterials, TArray<uint8>& OutBuffer) const override
	{
#if WITH_PHYSX
		PxSerializationRegistry* PRegistry = PxSerialization::createSerializationRegistry(*GPhysXSDK);
		PxCollection* PCollection = PxCreateCollection();

		PxBase* PLastObject = nullptr;

		for(FBodyInstance* BodyInstance : Bodies)
		{
			if(BodyInstance->RigidActorSync)
			{
				PCollection->add(*BodyInstance->RigidActorSync, BodyInstance->RigidActorSyncId);
				PLastObject = BodyInstance->RigidActorSync;
			}

			if(BodyInstance->RigidActorAsync)
			{
				PCollection->add(*BodyInstance->RigidActorAsync,  BodyInstance->RigidActorAsyncId);
				PLastObject = BodyInstance->RigidActorAsync;
			}
		}

		PxSerialization::createSerialObjectIds(*PCollection, PxSerialObjectId(1));	//we get physx to assign an id for each actor

		//Note that rigid bodies may have assigned ids. It's important to let them go first because we rely on that id for deserialization.
		//One this is done we must find out the next available ID, and use that for naming the shared resources. We have to save this for deserialization
		uint64 BaseId = PLastObject ? (PCollection->getId(*PLastObject) + 1) : 1;

		PxCollection* PExceptFor = MakePhysXCollection(PhysicalMaterials, BodySetups, BaseId);
		
		for (FBodyInstance* BodyInstance : Bodies)	//and then we mark that id back into the bodyinstance so we can pair the two later
		{
			if (BodyInstance->RigidActorSync)
			{
				BodyInstance->RigidActorSyncId = PCollection->getId(*BodyInstance->RigidActorSync);
			}

			if (BodyInstance->RigidActorAsync)
			{
				BodyInstance->RigidActorAsyncId = PCollection->getId(*BodyInstance->RigidActorAsync);
			}
		}

		//We must store the BaseId for shared resources.
		FMemoryWriter Ar(OutBuffer);
		uint8 bIsLittleEndian = PLATFORM_LITTLE_ENDIAN; //TODO: We should pass the target platform into this function and write it. Then swap the endian on the writer so the reader doesn't have to do it at runtime
		Ar << bIsLittleEndian;
		Ar << BaseId;
		//Note that PhysX expects the binary data to be 128-byte aligned. Because of this we must pad
		int32 BytesToPad = PHYSX_SERIALIZATION_ALIGNMENT - (Ar.Tell() % PHYSX_SERIALIZATION_ALIGNMENT);
		OutBuffer.AddZeroed(BytesToPad);

		FPhysXOutputStream Buffer(&OutBuffer);
		PxSerialization::complete(*PCollection, *PRegistry, PExceptFor);
		PxSerialization::serializeCollectionToBinary(Buffer, *PCollection, *PRegistry, PExceptFor);

#if PHYSX_MEMORY_VALIDATION
		GPhysXAllocator->ValidateHeaders();
#endif
		PCollection->release();
		PExceptFor->release();
		PRegistry->release();

#if PHYSX_MEMORY_VALIDATION
		GPhysXAllocator->ValidateHeaders();
#endif
		return true;
#endif
		return false;
	}