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