void FReflectionCaptureFullHDRDerivedData::InitializeFromUncompressedData(const TArray<uint8>& UncompressedData) { DEC_MEMORY_STAT_BY(STAT_ReflectionCaptureMemory, CompressedCapturedData.GetAllocatedSize()); int32 UncompressedSize = UncompressedData.Num() * UncompressedData.GetTypeSize(); TArray<uint8> TempCompressedMemory; // Compressed can be slightly larger than uncompressed TempCompressedMemory.Empty(UncompressedSize * 4 / 3); TempCompressedMemory.AddUninitialized(UncompressedSize * 4 / 3); int32 CompressedSize = TempCompressedMemory.Num() * TempCompressedMemory.GetTypeSize(); verify(FCompression::CompressMemory( (ECompressionFlags)(COMPRESS_ZLIB | COMPRESS_BiasMemory), TempCompressedMemory.GetData(), CompressedSize, UncompressedData.GetData(), UncompressedSize)); // Note: change REFLECTIONCAPTURE_FULL_DERIVEDDATA_VER when modifying the serialization layout FMemoryWriter FinalArchive(CompressedCapturedData, true); FinalArchive << UncompressedSize; FinalArchive << CompressedSize; FinalArchive.Serialize(TempCompressedMemory.GetData(), CompressedSize); INC_MEMORY_STAT_BY(STAT_ReflectionCaptureMemory, CompressedCapturedData.GetAllocatedSize()); }
bool UMP3Decoder::Decode(TArray<uint8> &OutBuffer) { check(OutBuffer.Num() == 0); check(OutBuffer.GetAllocatedSize() >= WAV_HEADER_SIZE); OutBuffer.AddZeroed(WAV_HEADER_SIZE / OutBuffer.GetTypeSize()); FDateTime tStart = FDateTime::Now(); unsigned char* BlockBuffer = (unsigned char*)FMemory::Malloc(BlockBufferSize); size_t bytesRead = 0; size_t done = 0; int result; do { result = mpg123_read(Handle, BlockBuffer, BlockBufferSize, &done); bytesRead += done; OutBuffer.Append(BlockBuffer, done); } while (result == MPG123_OK); uint8 header[WAV_HEADER_SIZE]; WriteWaveHeader(header, bytesRead, Samplerate, Channels); FMemory::Memcpy(OutBuffer.GetData(), header, WAV_HEADER_SIZE); FMemory::Free(BlockBuffer); SizeInBytes = bytesRead; bool bSuccess = result == MPG123_OK || result == MPG123_DONE; UE_LOG(MP3ImporterLog, Display, TEXT("Decoding finished. %s bytes in %d ms. Success: %s"), *FString::FormatAsNumber((int32)bytesRead), (int32)(FDateTime::Now() - tStart).GetTotalMilliseconds(), bSuccess ? TEXT("True") : TEXT("False")); return bSuccess; }
void FLightmassSolverExporter::WriteArray(const TArray<T>& Array) const { const int32 ArrayNum = Array.Num(); Swarm->Write((void*)&ArrayNum, sizeof(ArrayNum)); if (ArrayNum > 0) { Swarm->Write(Array.GetData(), Array.GetTypeSize() * ArrayNum); } }
void FPositionVertexBuffer::Init(const TArray<FVector>& InPositions) { NumVertices = InPositions.Num(); if ( NumVertices ) { AllocateData(); check( Stride == InPositions.GetTypeSize() ); VertexData->ResizeBuffer(NumVertices); Data = VertexData->GetDataPointer(); FMemory::Memcpy( Data, InPositions.GetData(), Stride * NumVertices ); } }
void AStereoCapturePawn::CopyAtlasDataToTextures(const TArray<FColor>& InLeftEyeAtlasData, const TArray<FColor>& InRightEyeAtlasData) { if (LeftEyeAtlas && LeftEyeAtlas->IsValidLowLevel() && RightEyeAtlas && RightEyeAtlas->IsValidLowLevel()) { { const int32 TextureDataSize = InLeftEyeAtlasData.Num() * InLeftEyeAtlasData.GetTypeSize(); check(TextureDataSize == LeftEyeAtlas->GetSizeX() * LeftEyeAtlas->GetSizeY() * sizeof(FColor) ); FTexture2DMipMap& Mip = LeftEyeAtlas->PlatformData->Mips[0]; void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(Data, InLeftEyeAtlasData.GetData(), TextureDataSize); Mip.BulkData.Unlock(); LeftEyeAtlas->UpdateResource(); } { const int32 TextureDataSize = InRightEyeAtlasData.Num() * InRightEyeAtlasData.GetTypeSize(); check(TextureDataSize == RightEyeAtlas->GetSizeX() * RightEyeAtlas->GetSizeY() * sizeof(FColor) ); FTexture2DMipMap& Mip = RightEyeAtlas->PlatformData->Mips[0]; void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(Data, InRightEyeAtlasData.GetData(), TextureDataSize); Mip.BulkData.Unlock(); RightEyeAtlas->UpdateResource(); } } if (StereoCaptureDoneAction) { StereoCaptureDoneAction->IsStereoCaptureDone = true; } }
void FRawStaticIndexBuffer::SetIndices(const TArray<uint32>& InIndices, EIndexBufferStride::Type DesiredStride) { int32 NumIndices = InIndices.Num(); bool bShouldUse32Bit = false; // Figure out if we should store the indices as 16 or 32 bit. if (DesiredStride == EIndexBufferStride::Force32Bit) { bShouldUse32Bit = true; } else if (DesiredStride == EIndexBufferStride::AutoDetect) { int32 i = 0; while (!bShouldUse32Bit && i < NumIndices) { bShouldUse32Bit = InIndices[i] > MAX_uint16; i++; } } // Allocate storage for the indices. int32 IndexStride = bShouldUse32Bit ? sizeof(uint32) : sizeof(uint16); IndexStorage.Empty(IndexStride * NumIndices); IndexStorage.AddUninitialized(IndexStride * NumIndices); // Store them! if (bShouldUse32Bit) { // If the indices are 32 bit we can just do a memcpy. check(IndexStorage.Num() == InIndices.Num() * InIndices.GetTypeSize()); FMemory::Memcpy(IndexStorage.GetData(),InIndices.GetData(),IndexStorage.Num()); b32Bit = true; } else { // Copy element by element demoting 32-bit integers to 16-bit. check(IndexStorage.Num() == InIndices.Num() * sizeof(uint16)); uint16* DestIndices16Bit = (uint16*)IndexStorage.GetData(); for (int32 i = 0; i < NumIndices; ++i) { DestIndices16Bit[i] = InIndices[i]; } b32Bit = false; } }
void FRawMeshBulkData::UseHashAsGuid(UObject* Owner) { // Build the hash from the path name + the contents of the bulk data. FSHA1 Sha; TArray<TCHAR> OwnerName = Owner->GetPathName().GetCharArray(); Sha.Update((uint8*)OwnerName.GetData(), OwnerName.Num() * OwnerName.GetTypeSize()); if (BulkData.GetBulkDataSize() > 0) { uint8* Buffer = (uint8*)BulkData.Lock(LOCK_READ_ONLY); Sha.Update(Buffer, BulkData.GetBulkDataSize()); BulkData.Unlock(); } Sha.Final(); // Retrieve the hash and use it to construct a pseudo-GUID. Use bGuidIsHash to distinguish from real guids. uint32 Hash[5]; Sha.GetHash((uint8*)Hash); Guid = FGuid(Hash[0] ^ Hash[4], Hash[1], Hash[2], Hash[3]); bGuidIsHash = true; }
void FRawStaticIndexBuffer::GetCopy(TArray<uint32>& OutIndices) const { int32 NumIndices = b32Bit ? (IndexStorage.Num() / 4) : (IndexStorage.Num() / 2); OutIndices.Empty(NumIndices); OutIndices.AddUninitialized(NumIndices); if (b32Bit) { // If the indices are 32 bit we can just do a memcpy. check(IndexStorage.Num() == OutIndices.Num() * OutIndices.GetTypeSize()); FMemory::Memcpy(OutIndices.GetData(),IndexStorage.GetData(),IndexStorage.Num()); } else { // Copy element by element promoting 16-bit integers to 32-bit. check(IndexStorage.Num() == OutIndices.Num() * sizeof(uint16)); const uint16* SrcIndices16Bit = (const uint16*)IndexStorage.GetData(); for (int32 i = 0; i < NumIndices; ++i) { OutIndices[i] = SrcIndices16Bit[i]; } } }
void UnchunkSkeletalModel(TArray<FSkinnedMeshChunk*>& Chunks, TArray<int32>& PointToOriginalMap, const FSkinnedModelData& SrcModel) { #if WITH_EDITORONLY_DATA const TArray<FSoftSkinVertex>& SrcVertices = SrcModel.Vertices; const TArray<uint32>& SrcIndices = SrcModel.Indices; TArray<uint32> IndexMap; check(Chunks.Num() == 0); check(PointToOriginalMap.Num() == 0); IndexMap.Empty(SrcVertices.Num()); IndexMap.AddUninitialized(SrcVertices.Num()); for (int32 SectionIndex = 0; SectionIndex < SrcModel.Sections.Num(); ++SectionIndex) { const FSkelMeshSection& Section = SrcModel.Sections[SectionIndex]; const TArray<FBoneIndexType>& BoneMap = SrcModel.BoneMaps[SectionIndex]; FSkinnedMeshChunk* DestChunk = Chunks.Num() ? Chunks.Last() : NULL; if (DestChunk == NULL || DestChunk->MaterialIndex != Section.MaterialIndex) { DestChunk = new FSkinnedMeshChunk(); Chunks.Add(DestChunk); DestChunk->MaterialIndex = Section.MaterialIndex; DestChunk->OriginalSectionIndex = SectionIndex; // When starting a new chunk reset the index map. FMemory::Memset(IndexMap.GetData(),0xff,IndexMap.Num()*IndexMap.GetTypeSize()); } int32 NumIndicesThisSection = Section.NumTriangles * 3; for (uint32 SrcIndex = Section.BaseIndex; SrcIndex < Section.BaseIndex + NumIndicesThisSection; ++SrcIndex) { uint32 VertexIndex = SrcIndices[SrcIndex]; uint32 DestVertexIndex = IndexMap[VertexIndex]; if (DestVertexIndex == INDEX_NONE) { FSoftSkinBuildVertex NewVertex; const FSoftSkinVertex& SrcVertex = SrcVertices[VertexIndex]; NewVertex.Position = SrcVertex.Position; NewVertex.TangentX = SrcVertex.TangentX; NewVertex.TangentY = SrcVertex.TangentY; NewVertex.TangentZ = SrcVertex.TangentZ; FMemory::Memcpy(NewVertex.UVs, SrcVertex.UVs, sizeof(FVector2D)*MAX_TEXCOORDS); NewVertex.Color = SrcVertex.Color; for (int32 i = 0; i < MAX_TOTAL_INFLUENCES; ++i) { uint8 BoneIndex = SrcVertex.InfluenceBones[i]; check(BoneMap.IsValidIndex(BoneIndex)); NewVertex.InfluenceBones[i] = BoneMap[BoneIndex]; NewVertex.InfluenceWeights[i] = SrcVertex.InfluenceWeights[i]; } NewVertex.PointWedgeIdx = SrcModel.RawPointIndices.Num() ? SrcModel.RawPointIndices[VertexIndex] : 0; int32 RawVertIndex = SrcModel.MeshToImportVertexMap.Num() ? SrcModel.MeshToImportVertexMap[VertexIndex] : INDEX_NONE; if ((int32)NewVertex.PointWedgeIdx >= PointToOriginalMap.Num()) { PointToOriginalMap.AddZeroed(NewVertex.PointWedgeIdx + 1 - PointToOriginalMap.Num()); } PointToOriginalMap[NewVertex.PointWedgeIdx] = RawVertIndex; DestVertexIndex = AddSkinVertex(DestChunk->Vertices,NewVertex,/*bKeepOverlappingVertices=*/ false); IndexMap[VertexIndex] = DestVertexIndex; } DestChunk->Indices.Add(DestVertexIndex); } } #endif // #if WITH_EDITORONLY_DATA }
UObject* UMP3SoundFactory::FactoryCreateBinary(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* BufferEnd, FFeedbackContext* Warn) { FEditorDelegates::OnAssetPreImport.Broadcast(this, Class, InParent, Name, Type); if (mpg123_init == nullptr) { Warn->Logf(ELogVerbosity::Error, TEXT("Function pointer was null. Was %s found?"), DLL_NAME); FEditorDelegates::OnAssetPostImport.Broadcast(this, nullptr); return nullptr; } // if the sound already exists, remember the user settings USoundWave* ExistingSound = FindObject<USoundWave>(InParent, *Name.ToString()); // stop playing the file, if it already exists (e.g. reimport) TArray<UAudioComponent*> ComponentsToRestart; FAudioDeviceManager* AudioDeviceManager = GEngine->GetAudioDeviceManager(); if (AudioDeviceManager && ExistingSound) { AudioDeviceManager->StopSoundsUsingResource(ExistingSound, ComponentsToRestart); } // Read the mp3 header and make sure we have valid data UMP3Decoder Decoder(Warn); Decoder.Init(Buffer, BufferEnd); if (Decoder.BitsPerSample != 16) { Warn->Logf(ELogVerbosity::Error, TEXT("Unreal only supports 16bit WAVE data (%s)."), *Name.ToString()); FEditorDelegates::OnAssetPostImport.Broadcast(this, nullptr); return nullptr; } if (Decoder.Channels != 1 && Decoder.Channels != 2) { Warn->Logf(ELogVerbosity::Error, TEXT("Unreal only supports 1-2 channel WAVE data (Mono/Stereo). (%s)."), *Name.ToString()); FEditorDelegates::OnAssetPostImport.Broadcast(this, nullptr); return nullptr; } //on reimport, reuse settings, wipe data. otherwise create new. (UE4 WAVE import has some more checks, maybe implement, too?) USoundWave* Sound; if (ExistingSound && bMP3SoundFactoryIsReimport) { Sound = ExistingSound; Sound->FreeResources(); Sound->InvalidateCompressedData(); } else { Sound = NewObject<USoundWave>(InParent, Name, Flags); } Sound->AssetImportData->Update(GetCurrentFilename()); TArray<uint8> RawWavBuffer; RawWavBuffer.Reserve((BufferEnd - Buffer) * 16); //actual decoding Decoder.Decode(RawWavBuffer); Sound->RawData.Lock(LOCK_READ_WRITE); void* LockedData = Sound->RawData.Realloc(RawWavBuffer.Num() * RawWavBuffer.GetTypeSize()); FMemory::Memcpy(LockedData, RawWavBuffer.GetData(), RawWavBuffer.Num() * RawWavBuffer.GetTypeSize()); Sound->RawData.Unlock(); RawWavBuffer.Empty(); // Calculate duration. Sound->Duration = (float)Decoder.SizeInBytes / Decoder.Samplerate / Decoder.Channels / (BITS_PER_SAMPLE / 8); Sound->SampleRate = Decoder.Samplerate; Sound->NumChannels = Decoder.Channels; Sound->RawPCMDataSize = Decoder.SizeInBytes; FEditorDelegates::OnAssetPostImport.Broadcast(this, Sound); if (ExistingSound) { Sound->PostEditChange(); } for (int32 ComponentIndex = 0; ComponentIndex < ComponentsToRestart.Num(); ++ComponentIndex) { ComponentsToRestart[ComponentIndex]->Play(); } return Sound; }