FPhysXFormatDataReader::FPhysXFormatDataReader( FByteBulkData& InBulkData ) : TriMesh( NULL ) , TriMeshNegX( NULL ) { // Read cooked physics data uint8* DataPtr = (uint8*)InBulkData.Lock( LOCK_READ_ONLY ); FBufferReader Ar( DataPtr, InBulkData.GetBulkDataSize(), false ); uint8 bLittleEndian = true; int32 NumConvexElementsCooked = 0; int32 NumMirroredElementsCooked = 0; uint8 bTriMeshCooked = false; uint8 bMirroredTriMeshCooked = false; Ar << bLittleEndian; Ar.SetByteSwapping( PLATFORM_LITTLE_ENDIAN ? !bLittleEndian : !!bLittleEndian ); Ar << NumConvexElementsCooked; Ar << NumMirroredElementsCooked; Ar << bTriMeshCooked; Ar << bMirroredTriMeshCooked; ConvexMeshes.Empty( NumConvexElementsCooked ); ConvexMeshesNegX.Empty( NumMirroredElementsCooked ); for( int32 ElementIndex = 0; ElementIndex < NumConvexElementsCooked; ElementIndex++ ) { PxConvexMesh* ConvexMesh = ReadConvexMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); ConvexMeshes.Add( ConvexMesh ); } for( int32 ElementIndex = 0; ElementIndex < NumMirroredElementsCooked; ElementIndex++ ) { PxConvexMesh* ConvexMeshNegX = ReadConvexMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); ConvexMeshesNegX.Add( ConvexMeshNegX ); } if( bTriMeshCooked ) { TriMesh = ReadTriMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); check(TriMesh); } if( bMirroredTriMeshCooked ) { TriMeshNegX = ReadTriMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); check(TriMeshNegX); } InBulkData.Unlock(); }
FByteBulkData* UNavCollision::GetCookedData(FName Format) { if (IsTemplate()) { return NULL; } bool bContainedData = CookedFormatData.Contains(Format); FByteBulkData* Result = &CookedFormatData.GetFormat(Format); if (!bContainedData) { if (FPlatformProperties::RequiresCookedData()) { UE_LOG(LogNavigation, Fatal, TEXT("Attempt to build nav collision data for %s when we are unable to. This platform requires cooked packages."), *GetPathName()); } TArray<uint8> OutData; FDerivedDataNavCollisionCooker* DerivedNavCollisionData = new FDerivedDataNavCollisionCooker(Format, this); if (DerivedNavCollisionData->CanBuild() && GetDerivedDataCacheRef().GetSynchronous(DerivedNavCollisionData, OutData)) { if (OutData.Num()) { Result->Lock(LOCK_READ_WRITE); FMemory::Memcpy(Result->Realloc(OutData.Num()), OutData.GetData(), OutData.Num()); Result->Unlock(); } } } check(Result); return Result->GetBulkDataSize() > 0 ? Result : NULL; // we don't return empty bulk data...but we save it to avoid thrashing the DDC }
FByteBulkData* USoundWave::GetCompressedData(FName Format) { if (IsTemplate() || IsRunningDedicatedServer()) { return NULL; } bool bContainedData = CompressedFormatData.Contains(Format); FByteBulkData* Result = &CompressedFormatData.GetFormat(Format); if (!bContainedData) { if (!FPlatformProperties::RequiresCookedData() && GetDerivedDataCache()) { TArray<uint8> OutData; FDerivedAudioDataCompressor* DeriveAudioData = new FDerivedAudioDataCompressor(this, Format); GetDerivedDataCacheRef().GetSynchronous(DeriveAudioData, OutData); if (OutData.Num()) { Result->Lock(LOCK_READ_WRITE); FMemory::Memcpy(Result->Realloc(OutData.Num()), OutData.GetData(), OutData.Num()); Result->Unlock(); } } else { UE_LOG(LogAudio, Error, TEXT("Attempt to access the DDC when there is none available on sound '%s', format = %s. Should have been cooked."), *GetFullName(), *Format.ToString()); } } check(Result); return Result->GetBulkDataSize() > 0 ? Result : NULL; // we don't return empty bulk data...but we save it to avoid thrashing the DDC }
FByteBulkData* UBodySetup::GetCookedData(FName Format) { if (IsTemplate()) { return NULL; } IInterface_CollisionDataProvider* CDP = Cast<IInterface_CollisionDataProvider>(GetOuter()); // If there is nothing to cook or if we are reading data from a cooked package for an asset with no collision, // we want to return here if ((AggGeom.ConvexElems.Num() == 0 && CDP == NULL) || !bHasCookedCollisionData) { return NULL; } FFormatContainer* UseCookedData = CookedFormatDataOverride ? CookedFormatDataOverride : &CookedFormatData; bool bContainedData = UseCookedData->Contains(Format); FByteBulkData* Result = &UseCookedData->GetFormat(Format); #if WITH_PHYSX if (!bContainedData) { if (FPlatformProperties::RequiresCookedData()) { UE_LOG(LogPhysics, Error, TEXT("Attempt to build physics data for %s when we are unable to. This platform requires cooked packages."), *GetPathName()); } if (AggGeom.ConvexElems.Num() == 0 && (CDP == NULL || CDP->ContainsPhysicsTriMeshData(bMeshCollideAll) == false)) { return NULL; } #if WITH_RUNTIME_PHYSICS_COOKING || WITH_EDITOR TArray<uint8> OutData; FDerivedDataPhysXCooker* DerivedPhysXData = new FDerivedDataPhysXCooker(Format, this); if (DerivedPhysXData->CanBuild()) { #if WITH_EDITOR GetDerivedDataCacheRef().GetSynchronous(DerivedPhysXData, OutData); #elif WITH_RUNTIME_PHYSICS_COOKING DerivedPhysXData->Build(OutData); #endif if (OutData.Num()) { Result->Lock(LOCK_READ_WRITE); FMemory::Memcpy(Result->Realloc(OutData.Num()), OutData.GetData(), OutData.Num()); Result->Unlock(); } } else #endif { UE_LOG(LogPhysics, Warning, TEXT("Attempt to build physics data for %s when we are unable to."), *GetPathName()); } } #endif // WITH_PHYSX check(Result); return Result->GetBulkDataSize() > 0 ? Result : NULL; // we don't return empty bulk data...but we save it to avoid thrashing the DDC }
FPhysXFormatDataReader::FPhysXFormatDataReader( FByteBulkData& InBulkData, FBodySetupUVInfo* UVInfo ) { // Read cooked physics data uint8* DataPtr = (uint8*)InBulkData.Lock( LOCK_READ_ONLY ); FBufferReader Ar( DataPtr, InBulkData.GetBulkDataSize(), false ); uint8 bLittleEndian = true; int32 NumConvexElementsCooked = 0; int32 NumMirroredElementsCooked = 0; int32 NumTriMeshesCooked = 0; Ar << bLittleEndian; Ar.SetByteSwapping( PLATFORM_LITTLE_ENDIAN ? !bLittleEndian : !!bLittleEndian ); Ar << NumConvexElementsCooked; Ar << NumMirroredElementsCooked; Ar << NumTriMeshesCooked; ConvexMeshes.Empty(NumConvexElementsCooked); for( int32 ElementIndex = 0; ElementIndex < NumConvexElementsCooked; ElementIndex++ ) { PxConvexMesh* ConvexMesh = ReadConvexMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); ConvexMeshes.Add( ConvexMesh ); } ConvexMeshesNegX.Empty(NumMirroredElementsCooked); for( int32 ElementIndex = 0; ElementIndex < NumMirroredElementsCooked; ElementIndex++ ) { PxConvexMesh* ConvexMeshNegX = ReadConvexMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); ConvexMeshesNegX.Add( ConvexMeshNegX ); } TriMeshes.Empty(NumTriMeshesCooked); for(int32 ElementIndex = 0; ElementIndex < NumTriMeshesCooked; ++ElementIndex) { PxTriangleMesh* TriMesh = ReadTriMesh( Ar, DataPtr, InBulkData.GetBulkDataSize() ); TriMeshes.Add(TriMesh); } // Init UVInfo pointer check(UVInfo); Ar << *UVInfo; InBulkData.Unlock(); }
void USoundWave::InitAudioResource( FByteBulkData& CompressedData ) { if( !ResourceSize ) { // Grab the compressed vorbis data from the bulk data ResourceSize = CompressedData.GetBulkDataSize(); if( ResourceSize > 0 ) { check(!ResourceData); CompressedData.GetCopy( ( void** )&ResourceData, true ); } } }
bool USoundWave::InitAudioResource(FName Format) { if( !ResourceSize && (!FPlatformProperties::SupportsAudioStreaming() || !IsStreaming()) ) { FByteBulkData* Bulk = GetCompressedData(Format); if (Bulk) { ResourceSize = Bulk->GetBulkDataSize(); check(ResourceSize > 0); check(!ResourceData); Bulk->GetCopy((void**)&ResourceData, true); } } return ResourceSize > 0; }
FByteBulkData* UPhysicsSerializer::GetBinaryData(FName Format, const TArray<FBodyInstance*>& Bodies, const TArray<class UBodySetup*>& BodySetups, const TArray<class UPhysicalMaterial*>& PhysicalMaterials) { if (!FParse::Param(FCommandLine::Get(), TEXT("PhysxSerialization"))) { return nullptr; } #if PLATFORM_MAC return nullptr; //This is not supported right now #endif QUICK_SCOPE_CYCLE_COUNTER(STAT_GetBinaryData); const bool bContainedData = BinaryFormatData.Contains(Format); FByteBulkData* Result = &BinaryFormatData.GetFormat(Format); if (!FParse::Param(FCommandLine::Get(), TEXT("NoPhysxAlignment"))) { Result->SetBulkDataAlignment(PHYSX_SERIALIZATION_ALIGNMENT); } if (!bContainedData) { #if WITH_EDITOR #if WITH_PHYSX TArray<uint8> OutData; FDerivedDataPhysXBinarySerializer* DerivedPhysXSerializer = new FDerivedDataPhysXBinarySerializer(Format, Bodies, BodySetups, PhysicalMaterials, FGuid::NewGuid()); //TODO: Maybe it's worth adding this to the DDC. For now there's a lot of complexity with the guid invalidation so I've left it out. if (DerivedPhysXSerializer->CanBuild()) { DerivedPhysXSerializer->Build(OutData); #endif if (OutData.Num()) { Result->Lock(LOCK_READ_WRITE); FMemory::Memcpy(Result->Realloc(OutData.Num()), OutData.GetData(), OutData.Num()); Result->Unlock(); } } else #endif { UE_LOG(LogPhysics, Warning, TEXT("Attempt to use binary physics data but we are unable to.")); } } return Result->GetBulkDataSize() > 0 ? Result : nullptr; }
FNavCollisionDataReader(FByteBulkData& InBulkData, FNavCollisionConvex& InTriMeshCollision, FNavCollisionConvex& InConvexCollision, TNavStatArray<int32>& InShapeIndices) : TriMeshCollision(InTriMeshCollision) , ConvexCollision(InConvexCollision) , ConvexShapeIndices(InShapeIndices) { // Read cooked data uint8* DataPtr = (uint8*)InBulkData.Lock( LOCK_READ_ONLY ); FBufferReader Ar( DataPtr, InBulkData.GetBulkDataSize(), false ); uint8 bLittleEndian = true; Ar << bLittleEndian; Ar.SetByteSwapping( PLATFORM_LITTLE_ENDIAN ? !bLittleEndian : !!bLittleEndian ); Ar << TriMeshCollision.VertexBuffer; Ar << TriMeshCollision.IndexBuffer; Ar << ConvexCollision.VertexBuffer; Ar << ConvexCollision.IndexBuffer; Ar << ConvexShapeIndices; InBulkData.Unlock(); }
/** Build the streamed audio. This function is safe to call from any thread. */ void BuildStreamedAudio() { GetStreamedAudioDerivedDataKeySuffix(SoundWave, AudioFormatName, KeySuffix); DerivedData->Chunks.Empty(); ITargetPlatformManagerModule* TPM = GetTargetPlatformManager(); const IAudioFormat* AudioFormat = NULL; if (TPM) { AudioFormat = TPM->FindAudioFormat(AudioFormatName); } if (AudioFormat) { DerivedData->AudioFormat = AudioFormatName; FByteBulkData* CompressedData = SoundWave.GetCompressedData(AudioFormatName); TArray<uint8> CompressedBuffer; CompressedBuffer.Empty(CompressedData->GetBulkDataSize()); CompressedBuffer.AddUninitialized(CompressedData->GetBulkDataSize()); void* BufferData = CompressedBuffer.GetData(); CompressedData->GetCopy(&BufferData, false); TArray<TArray<uint8>> ChunkBuffers; if (AudioFormat->SplitDataForStreaming(CompressedBuffer, ChunkBuffers)) { for (int32 ChunkIndex = 0; ChunkIndex < ChunkBuffers.Num(); ++ChunkIndex) { FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk(); NewChunk->DataSize = ChunkBuffers[ChunkIndex].Num(); NewChunk->BulkData.Lock(LOCK_READ_WRITE); void* NewChunkData = NewChunk->BulkData.Realloc(ChunkBuffers[ChunkIndex].Num()); FMemory::Memcpy(NewChunkData, ChunkBuffers[ChunkIndex].GetData(), ChunkBuffers[ChunkIndex].Num()); NewChunk->BulkData.Unlock(); } } else { // Could not split so copy compressed data into a single chunk FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk(); NewChunk->DataSize = CompressedBuffer.Num(); NewChunk->BulkData.Lock(LOCK_READ_WRITE); void* NewChunkData = NewChunk->BulkData.Realloc(CompressedBuffer.Num()); FMemory::Memcpy(NewChunkData, CompressedBuffer.GetData(), CompressedBuffer.Num()); NewChunk->BulkData.Unlock(); } DerivedData->NumChunks = DerivedData->Chunks.Num(); // Store it in the cache. PutDerivedDataInCache(DerivedData, KeySuffix); } if (DerivedData->Chunks.Num()) { bool bInlineChunks = (CacheFlags & EStreamedAudioCacheFlags::InlineChunks) != 0; bSucceeded = !bInlineChunks || DerivedData->TryInlineChunkData(); } else { UE_LOG(LogAudio, Warning, TEXT("Failed to build %s derived data for %s"), *AudioFormatName.GetPlainNameString(), *SoundWave.GetPathName() ); } }