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());
}
Example #2
0
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;
}
Example #3
0
	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;
    }
}
Example #6
0
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;
	}
}
Example #7
0
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;
}
Example #8
0
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;
}