Beispiel #1
0
// function is similar to part of CSkelMeshInstance::SetMesh()
static void BuildSkeleton(TArray<CCoords> &Coords, const TArray<RJoint> &Bones, const TArray<AnalogTrack> &Anim)
{
	guard(BuildSkeleton);

	int numBones = Anim.Num();
	Coords.Empty(numBones);
	Coords.AddZeroed(numBones);

	for (int i = 0; i < numBones; i++)
	{
		const AnalogTrack &A = Anim[i];
		const RJoint &B = Bones[i];
		CCoords &BC = Coords[i];
		// compute reference bone coords
		CVec3 BP;
		CQuat BO;
		// get default pose
		BP = CVT(A.KeyPos[0]);
		BO = CVT(A.KeyQuat[0]);
		if (!i) BO.Conjugate();

		BC.origin = BP;
		BO.ToAxis(BC.axis);
		// move bone position to global coordinate space
		if (i)	// do not rotate root bone
		{
			assert(B.parent >= 0);
			Coords[B.parent].UnTransformCoords(BC, BC);
		}
	}

	unguard;
}
Beispiel #2
0
/**
 * Decodes a Base64 string into a FString
 *
 * @param Source the stringified data to convert
 * @param Dest the out buffer that will be filled with the decoded data
 */
bool FBase64::Decode(const FString& Source, FString& Dest)
{
	uint32 Length = Source.Len();
	// Size must be a multiple of 4
	if (Length % 4)
	{
		return false;
	}
	// Each 4 uint8 chunk of characters is 3 bytes of data
	uint32 ExpectedLength = Length / 4 * 3;
	TArray<ANSICHAR> TempDest;
	TempDest.AddZeroed(ExpectedLength);
	uint8* Buffer = (uint8*)TempDest.GetData();
	uint32 PadCount = 0;

	bool bWasSuccessful = Decode(TCHAR_TO_ANSI(*Source), Length, Buffer, PadCount);
	if (bWasSuccessful)
	{
		if (PadCount > 0)
		{
			Buffer[ExpectedLength - PadCount] = 0;
		}
		else
		{
			TempDest.Add('\0');
		}
		Dest = ANSI_TO_TCHAR(TempDest.GetData());
	}
	return bWasSuccessful;
}
bool FPaperAtlasTextureHelpers::ReadSpriteTexture(UTexture* SourceTexture, const FIntPoint& SourceXY, const FIntPoint& SourceSize, TArray<uint8>& TargetBuffer)
{
	{
		const int32 BytesPerPixel = 4;
		TargetBuffer.Empty();
		TargetBuffer.AddZeroed(SourceSize.X * SourceSize.Y * BytesPerPixel);
	}

	check(SourceTexture);
	FTextureSource& SourceData = SourceTexture->Source;
	if (SourceData.GetFormat() == TSF_BGRA8)
	{
		uint32 BytesPerPixel = SourceData.GetBytesPerPixel();
		uint8* OffsetSource = SourceData.LockMip(0) + (SourceXY.X + SourceXY.Y * SourceData.GetSizeX()) * BytesPerPixel;
		uint8* OffsetDest = TargetBuffer.GetData();
		CopyTextureData(OffsetSource, OffsetDest, SourceSize.X, SourceSize.Y, BytesPerPixel, SourceData.GetSizeX() * BytesPerPixel, SourceSize.X * BytesPerPixel);
		SourceData.UnlockMip(0);
	}
	else
	{
		UE_LOG(LogPaper2DEditor, Error, TEXT("Sprite texture %s is not BGRA8, which isn't supported in atlases yet"), *SourceTexture->GetName());
	}

	return true;
}
/**
 * Dump allocation information.
 */
void FBestFitAllocator::DumpAllocs( FOutputDevice& Ar/*=*GLog*/ )
{		
	// Memory usage stats.
	INT				UsedSize		= 0;
	INT				FreeSize		= 0;
	INT				NumUsedChunks	= 0;
	INT				NumFreeChunks	= 0;
	
	// Fragmentation and allocation size visualization.
	INT				NumBlocks		= MemorySize / AllocationAlignment;
	INT				Dimension		= 1 + NumBlocks / appTrunc(appSqrt(NumBlocks));			
	TArray<FColor>	AllocationVisualization;
	AllocationVisualization.AddZeroed( Dimension * Dimension );
	INT				VisIndex		= 0;

	// Traverse linked list and gather allocation information.
	FMemoryChunk*	CurrentChunk	= FirstChunk;	
	while( CurrentChunk )
	{
		FColor VisColor;
		// Free chunk.
		if( CurrentChunk->bIsAvailable )
		{
			NumFreeChunks++;
			FreeSize += CurrentChunk->Size;
			VisColor = FColor(0,255,0);
		}
		// Allocated chunk.
		else
		{
			NumUsedChunks++;
			UsedSize += CurrentChunk->Size;
			
			// Slightly alternate coloration to also visualize allocation sizes.
			if( NumUsedChunks % 2 == 0 )
			{
				VisColor = FColor(255,0,0);
			}
			else
			{
				VisColor = FColor(192,0,0);
			}
		}

		for( INT i=0; i<(CurrentChunk->Size/AllocationAlignment); i++ )
		{
			AllocationVisualization(VisIndex++) = VisColor;
		}

		CurrentChunk = CurrentChunk->NextChunk;
	}

	check(UsedSize == AllocatedMemorySize);
	check(FreeSize == AvailableMemorySize);

	// Write out bitmap for visualization of fragmentation and allocation patterns.
	appCreateBitmap( TEXT("..\\..\\Binaries\\TextureMemory"), Dimension, Dimension, AllocationVisualization.GetTypedData() );
	Ar.Logf( TEXT("BestFitAllocator: Allocated %i KByte in %i chunks, leaving %i KByte in %i chunks."), UsedSize / 1024, NumUsedChunks, FreeSize / 1024, NumFreeChunks );
	Ar.Logf( TEXT("BestFitAllocator: %5.2f ms in allocator"), TimeSpentInAllocator * 1000 );
}
TArray<uint8> UGTCaptureComponent::CapturePng(FString Mode)
{
	// Flush location and rotation
	check(CaptureComponents.Num() != 0);
	USceneCaptureComponent2D* CaptureComponent = CaptureComponents.FindRef(Mode);

	TArray<uint8> ImgData;
	if (CaptureComponent == nullptr)
		return ImgData;

	// Attach this to something, for example, a real camera
	const FRotator PawnViewRotation = Pawn->GetViewRotation();
	if (!PawnViewRotation.Equals(CaptureComponent->GetComponentRotation()))
	{
		CaptureComponent->SetWorldRotation(PawnViewRotation);
	}

	UTextureRenderTarget2D* RenderTarget = CaptureComponent->TextureTarget;
	static IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	static TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
	int32 Width = RenderTarget->SizeX, Height = RenderTarget->SizeY;
	TArray<FColor> Image;
	FTextureRenderTargetResource* RenderTargetResource;
	Image.AddZeroed(Width * Height);
	RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource();

	FReadSurfaceDataFlags ReadSurfaceDataFlags;
	ReadSurfaceDataFlags.SetLinearToGamma(false); // This is super important to disable this!
												  // Instead of using this flag, we will set the gamma to the correct value directly
	RenderTargetResource->ReadPixels(Image, ReadSurfaceDataFlags);
	ImageWrapper->SetRaw(Image.GetData(), Image.GetAllocatedSize(), Width, Height, ERGBFormat::BGRA, 8);
	ImgData = ImageWrapper->GetCompressed();

	return ImgData;
}
int32 UAnimPreviewInstance::MontagePreview_FindLastSection(int32 StartSectionIdx)
{
	int32 ResultIdx = StartSectionIdx;
	if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset))
	{
		if (FAnimMontageInstance* CurMontageInstance = GetActiveMontageInstance())
		{
			int32 TotalSection = Montage->CompositeSections.Num();
			if (TotalSection > 0)
			{
				TArray<bool> AlreadyVisited;
				AlreadyVisited.AddZeroed(TotalSection);
				int32 CurrentSectionIdx = StartSectionIdx;
				while (CurrentSectionIdx != INDEX_NONE && ! AlreadyVisited[CurrentSectionIdx])
				{
					AlreadyVisited[CurrentSectionIdx] = true;
					ResultIdx = CurrentSectionIdx;
					if (CurMontageInstance->NextSections.IsValidIndex(CurrentSectionIdx))
					{
						CurrentSectionIdx = CurMontageInstance->NextSections[CurrentSectionIdx];
					}
				}
			}
		}
	}
	return ResultIdx;
}
	const FAtlasedTextureSlot* AddSprite(UPaperSprite* Sprite)
	{
		const FVector2D SpriteSizeFloat = Sprite->GetSourceSize();
		const FIntPoint SpriteSize(FMath::TruncToInt(SpriteSizeFloat.X), FMath::TruncToInt(SpriteSizeFloat.Y));

		TArray<uint8> DummyBuffer;
		DummyBuffer.AddZeroed(SpriteSize.X * SpriteSize.Y * Stride);
		
		check(Sprite->GetSourceTexture());
		FTextureSource& SourceData = Sprite->GetSourceTexture()->Source;

		//@TODO: Handle different texture formats!
		if (SourceData.GetFormat() == TSF_BGRA8)
		{
			uint32 BytesPerPixel = SourceData.GetBytesPerPixel();
			uint8* OffsetSource = SourceData.LockMip(0) + (FMath::TruncToInt(Sprite->GetSourceUV().X) + FMath::TruncToInt(Sprite->GetSourceUV().Y) * SourceData.GetSizeX()) * BytesPerPixel;
			uint8* OffsetDest = DummyBuffer.GetData();

			CopyTextureData(OffsetSource, OffsetDest, SpriteSize.X, SpriteSize.Y, BytesPerPixel, SourceData.GetSizeX() * BytesPerPixel, SpriteSize.X * BytesPerPixel);

			SourceData.UnlockMip(0);
		}
		else
		{
			UE_LOG(LogPaper2DEditor, Error, TEXT("Sprite %s is not BGRA8, which isn't supported in atlases yet"), *(Sprite->GetPathName()));
		}

		const FAtlasedTextureSlot* Slot = AddTexture(SpriteSize.X, SpriteSize.Y, DummyBuffer);
		if (Slot != nullptr)
		{
			SpriteToSlotMap.Add(Sprite, Slot);
		}

		return Slot;
	}
	virtual int32 Recompress(FName Format, const TArray<uint8>& SrcBuffer, FSoundQualityInfo& QualityInfo, TArray<uint8>& OutBuffer) const override
	{
		check(Format == NAME_OPUS);
		FOpusAudioInfo	AudioInfo;

		// Cannot quality preview multichannel sounds
		if( QualityInfo.NumChannels > 2 )
		{
			return 0;
		}

		TArray<uint8> CompressedDataStore;
		if( !Cook( Format, SrcBuffer, QualityInfo, CompressedDataStore ) )
		{
			return 0;
		}

		// Parse the opus header for the relevant information
		if( !AudioInfo.ReadCompressedInfo( CompressedDataStore.GetData(), CompressedDataStore.Num(), &QualityInfo ) )
		{
			return 0;
		}

		// Decompress all the sample data
		OutBuffer.Empty(QualityInfo.SampleDataSize);
		OutBuffer.AddZeroed(QualityInfo.SampleDataSize);
		AudioInfo.ExpandFile( OutBuffer.GetData(), &QualityInfo );

		return CompressedDataStore.Num();
	}
bool SAnimMontageSectionsPanel::IsLoop(int32 SectionIdx)
{
	if(Montage && Montage->CompositeSections.IsValidIndex(SectionIdx))
	{
		TArray<bool>	Used;
		Used.AddZeroed(Montage->CompositeSections.Num());
		int32 CurrentIdx = SectionIdx;
		while(true)
		{
			CurrentIdx = Montage->GetSectionIndex(Montage->CompositeSections[CurrentIdx].NextSectionName);
			if(CurrentIdx == INDEX_NONE)
			{
				// End of the chain
				return false;
			}
			if(CurrentIdx == SectionIdx)
			{
				// Hit the starting position, return true
				return true;
			}
			if(Used[CurrentIdx])
			{
				// Hit a loop but the starting section was part of it, so return false
				return false;
			}
			Used[CurrentIdx]=true;
		}
	}
	return false;
}
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;
}
Beispiel #11
0
void BuildResourceTableTokenStream(const TArray<uint32>& InResourceMap, int32 MaxBoundResourceTable, TArray<uint32>& OutTokenStream)
{
	// First we sort the resource map.
	TArray<uint32> SortedResourceMap = InResourceMap;
	SortedResourceMap.Sort();

	// The token stream begins with a table that contains offsets per bound uniform buffer.
	// This offset provides the start of the token stream.
	OutTokenStream.AddZeroed(MaxBoundResourceTable+1);
	auto LastBufferIndex = FRHIResourceTableEntry::GetEndOfStreamToken();
	for (int32 i = 0; i < SortedResourceMap.Num(); ++i)
	{
		auto BufferIndex = FRHIResourceTableEntry::GetUniformBufferIndex(SortedResourceMap[i]);
		if (BufferIndex != LastBufferIndex)
		{
			// Store the offset for resources from this buffer.
			OutTokenStream[BufferIndex] = OutTokenStream.Num();
			LastBufferIndex = BufferIndex;
		}
		OutTokenStream.Add(SortedResourceMap[i]);
	}

	// Add a token to mark the end of the stream. Not needed if there are no bound resources.
	if (OutTokenStream.Num())
	{
		OutTokenStream.Add(FRHIResourceTableEntry::GetEndOfStreamToken());
	}
}
void UGameplayDebuggingComponent::OnRep_UpdateEQS()
{
#if  USE_EQS_DEBUGGER
    // decode scoring data
    if (World && World->GetNetMode() == NM_Client)
    {
        TArray<uint8> UncompressedBuffer;
        int32 UncompressedSize = 0;
        const int32 HeaderSize = sizeof(int32);
        uint8* SrcBuffer = (uint8*)EQSRepData.GetData();
        FMemory::Memcpy(&UncompressedSize, SrcBuffer, HeaderSize);
        SrcBuffer += HeaderSize;
        const int32 CompressedSize = EQSRepData.Num() - HeaderSize;

        UncompressedBuffer.AddZeroed(UncompressedSize);

        FCompression::UncompressMemory((ECompressionFlags)(COMPRESS_ZLIB), (void*)UncompressedBuffer.GetData(), UncompressedSize, SrcBuffer, CompressedSize);
        FMemoryReader ArReader(UncompressedBuffer);

        ArReader << EQSLocalData;
    }

    UpdateBounds();
    MarkRenderStateDirty();
#endif //USE_EQS_DEBUGGER
}
void USkeletalMeshComponent::FillSpaceBases()
{
	SCOPE_CYCLE_COUNTER(STAT_SkelComposeTime);

	if( !SkeletalMesh )
	{
		return;
	}

	// right now all this does is to convert to SpaceBases
	check( SkeletalMesh->RefSkeleton.GetNum() == LocalAtoms.Num() );
	check( SkeletalMesh->RefSkeleton.GetNum() == SpaceBases.Num() );
	check( SkeletalMesh->RefSkeleton.GetNum() == BoneVisibilityStates.Num() );

	const int32 NumBones = LocalAtoms.Num();

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
	/** Keep track of which bones have been processed for fast look up */
	TArray<uint8> BoneProcessed;
	BoneProcessed.AddZeroed(NumBones);
#endif

	FTransform * LocalTransformsData = LocalAtoms.GetTypedData(); 
	FTransform * SpaceBasesData = SpaceBases.GetTypedData();

	// First bone is always root bone, and it doesn't have a parent.
	{
		check( RequiredBones[0] == 0 );
		SpaceBases[0] = LocalAtoms[0];

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
		// Mark bone as processed
		BoneProcessed[0] = 1;
#endif
	}

	for(int32 i=1; i<RequiredBones.Num(); i++)
	{
		const int32 BoneIndex = RequiredBones[i];
		FPlatformMisc::Prefetch(SpaceBasesData + BoneIndex);

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
		// Mark bone as processed
		BoneProcessed[BoneIndex] = 1;
#endif
		// For all bones below the root, final component-space transform is relative transform * component-space transform of parent.
		const int32 ParentIndex = SkeletalMesh->RefSkeleton.GetParentIndex(BoneIndex);
		FPlatformMisc::Prefetch(SpaceBasesData + ParentIndex);

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
		// Check the precondition that Parents occur before Children in the RequiredBones array.
		checkSlow(BoneProcessed[ParentIndex] == 1);
#endif
		FTransform::Multiply(SpaceBasesData + BoneIndex, LocalTransformsData + BoneIndex, SpaceBasesData + ParentIndex);

		checkSlow( SpaceBases[BoneIndex].IsRotationNormalized() );
		checkSlow( !SpaceBases[BoneIndex].ContainsNaN() );
	}
}
void FVulkanPipelineStateCache::CreateDiskEntryRuntimeObjects(FDiskEntry* DiskEntry)
{
	{
		// Descriptor Set Layouts
		DiskEntry->DescriptorSetLayouts.AddZeroed(DiskEntry->DescriptorSetLayoutBindings.Num());
		for (int32 SetIndex = 0; SetIndex < DiskEntry->DescriptorSetLayoutBindings.Num(); ++SetIndex)
		{
			TArray<VkDescriptorSetLayoutBinding> DescriptorBindings;
			DescriptorBindings.AddZeroed(DiskEntry->DescriptorSetLayoutBindings[SetIndex].Num());
			for (int32 Index = 0; Index < DiskEntry->DescriptorSetLayoutBindings[SetIndex].Num(); ++Index)
			{
				DiskEntry->DescriptorSetLayoutBindings[SetIndex][Index].WriteInto(DescriptorBindings[Index]);
			}

			VkDescriptorSetLayoutCreateInfo DescriptorLayoutInfo;
			FMemory::Memzero(DescriptorLayoutInfo);
			DescriptorLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
			DescriptorLayoutInfo.pNext = nullptr;
			DescriptorLayoutInfo.bindingCount = DescriptorBindings.Num();
			DescriptorLayoutInfo.pBindings = DescriptorBindings.GetData();

			VERIFYVULKANRESULT(VulkanRHI::vkCreateDescriptorSetLayout(Device->GetInstanceHandle(), &DescriptorLayoutInfo, nullptr, &DiskEntry->DescriptorSetLayouts[SetIndex]));
		}

		// Pipeline layout
		VkPipelineLayoutCreateInfo PipelineLayoutInfo;
		FMemory::Memzero(PipelineLayoutInfo);
		PipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
		//PipelineLayoutInfo.pNext = nullptr;
		PipelineLayoutInfo.setLayoutCount = DiskEntry->DescriptorSetLayouts.Num();
		PipelineLayoutInfo.pSetLayouts = DiskEntry->DescriptorSetLayouts.GetData();
		//PipelineLayoutInfo.pushConstantRangeCount = 0;
		//PipelineLayoutInfo.pPushConstantRanges = nullptr;

		VERIFYVULKANRESULT(VulkanRHI::vkCreatePipelineLayout(Device->GetInstanceHandle(), &PipelineLayoutInfo, nullptr, &DiskEntry->PipelineLayout));
	}

	{
		// Shaders
		for (int32 Index = 0; Index < ARRAY_COUNT(DiskEntry->ShaderMicrocodes); ++Index)
		{
			if (DiskEntry->ShaderMicrocodes[Index].Num() != 0)
			{
				VkShaderModuleCreateInfo ModuleCreateInfo;
				FMemory::Memzero(ModuleCreateInfo);
				ModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
				ModuleCreateInfo.codeSize = DiskEntry->ShaderMicrocodes[Index].Num();
				ModuleCreateInfo.pCode = (uint32*)DiskEntry->ShaderMicrocodes[Index].GetData();
				VERIFYVULKANRESULT(VulkanRHI::vkCreateShaderModule(Device->GetInstanceHandle(), &ModuleCreateInfo, nullptr, &DiskEntry->ShaderModules[Index]));
			}
		}
	}

	{
		FVulkanRenderTargetLayout RTLayout;
		DiskEntry->RenderTargets.WriteInto(RTLayout);
		DiskEntry->RenderPass = new FVulkanRenderPass(*Device, RTLayout);
	}
}
Beispiel #15
0
	void RegisterResource(const FAIResourceID& Resource)
	{
		if (FAIResourceID::GetSize() > static_cast<uint32>(FAIResources::ResourceIDs.Num()))
		{
			ResourceIDs.AddZeroed(FAIResourceID::GetSize() - FAIResources::ResourceIDs.Num());
		}
		ResourceIDs[Resource.Index] = Resource;
	}
void FLODUtilities::RemoveLOD(FSkeletalMeshUpdateContext& UpdateContext, int32 DesiredLOD )
{
	USkeletalMesh* SkeletalMesh = UpdateContext.SkeletalMesh;
	FSkeletalMeshResource* SkelMeshResource = SkeletalMesh->GetImportedResource();

	if( SkelMeshResource->LODModels.Num() == 1 )
	{
		FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "NoLODToRemove", "No LODs to remove!") );
		return;
	}

	// Now display combo to choose which LOD to remove.
	TArray<FString> LODStrings;
	LODStrings.AddZeroed( SkelMeshResource->LODModels.Num()-1 );
	for(int32 i=0; i<SkelMeshResource->LODModels.Num()-1; i++)
	{
		LODStrings[i] = FString::Printf( TEXT("%d"), i+1 );
	}

	check( SkeletalMesh->LODInfo.Num() == SkelMeshResource->LODModels.Num() );

	// If its a valid LOD, kill it.
	if( DesiredLOD > 0 && DesiredLOD < SkelMeshResource->LODModels.Num() )
	{
		//We'll be modifying the skel mesh data so reregister

		//TODO - do we need to reregister something else instead?
		FMultiComponentReregisterContext ReregisterContext(UpdateContext.AssociatedComponents);

		// Release rendering resources before deleting LOD
		SkelMeshResource->ReleaseResources();

		// Block until this is done
		FlushRenderingCommands();

		SkelMeshResource->LODModels.RemoveAt(DesiredLOD);
		SkeletalMesh->LODInfo.RemoveAt(DesiredLOD);
		SkeletalMesh->InitResources();

		RefreshLODChange(SkeletalMesh);

		// Set the forced LOD to Auto.
		for(auto Iter = UpdateContext.AssociatedComponents.CreateIterator(); Iter; ++Iter)
		{
			USkinnedMeshComponent* SkinnedComponent = Cast<USkinnedMeshComponent>(*Iter);
			if(SkinnedComponent)
			{
				SkinnedComponent->ForcedLodModel = 0;
			}
		}
		
		//Notify calling system of change
		UpdateContext.OnLODChanged.ExecuteIfBound();

		// Mark things for saving.
		SkeletalMesh->MarkPackageDirty();
	}
}
Beispiel #17
0
bool FNFSMessageHeader::ReceivePayload(FArrayReader& OutPayload, const FSimpleAbstractSocket& Socket)
{
    // make room to receive a header
    TArray<uint8> HeaderBytes;
    int32 Size = sizeof(FNFSMessageHeader);
    HeaderBytes.AddZeroed(Size);

    if (!Socket.Receive(HeaderBytes.GetData(), Size))
    {
        UE_LOG(LogSockets, Error, TEXT("Unable to read full header"));
        return false;
    }

    // parse it as a header (doing any byte swapping as needed)
    FMemoryReader Reader(HeaderBytes);
    FNFSMessageHeader Header(Socket);
    Reader << Header;

    // make sure it's valid
    if (Header.Magic != Socket.GetMagic())
    {
        UE_LOG(LogSockets, Error, TEXT("Bad network header magic"));
        return false;
    }
    if (!Header.PayloadSize)
    {
        UE_LOG(LogSockets, Error, TEXT("Empty payload"));
        return false;
    }

    // was the header byteswapped? If so, make the archive byteswapped
    OutPayload.SetByteSwapping(Reader.ForceByteSwapping());

    // we are going to append to the payload, so note how much data is in it now
    int32 PayloadOffset = OutPayload.AddUninitialized(Header.PayloadSize);

    // put the read head at the start of the new data
    OutPayload.Seek(PayloadOffset);

    // receive the payload
    if (!Socket.Receive(OutPayload.GetData() + PayloadOffset, Header.PayloadSize))
    {
        UE_LOG(LogSockets, Error, TEXT("Unable to read full payload"));
        return false;
    }

    // make sure it's valid
    uint32 ActualPayloadCrc = FCrc::MemCrc_DEPRECATED(OutPayload.GetData() + PayloadOffset, Header.PayloadSize);
    if (Header.PayloadCrc != ActualPayloadCrc)
    {
        UE_LOG(LogSockets, Error, TEXT("Payload Crc failure."));
        return false;
    }

    // success!
    return true;
}
Beispiel #18
0
	void FDataStructure::CompleteCurrentChunk()
	{
		DataStructure.AddZeroed();
		FChunkPart& PreviousPart = DataStructure[DataStructure.Num() - 2];

		// Create next chunk
		NewChunkGuid = FGuid::NewGuid();
		DataStructure.Top().DataOffset = PreviousPart.DataOffset + PreviousPart.PartSize;
		DataStructure.Top().ChunkGuid = NewChunkGuid;
	}
void USoundCue::CompileSoundNodesFromGraphNodes()
{
	// Use GraphNodes to make SoundNode Connections
	TArray<USoundNode*> ChildNodes;
	TArray<UEdGraphPin*> InputPins;

	for (int32 NodeIndex = 0; NodeIndex < SoundCueGraph->Nodes.Num(); ++NodeIndex)
	{
		USoundCueGraphNode* GraphNode = Cast<USoundCueGraphNode>(SoundCueGraph->Nodes[NodeIndex]);
		if (GraphNode && GraphNode->SoundNode)
		{
			// Set ChildNodes of each SoundNode
			
			GraphNode->GetInputPins(InputPins);
			ChildNodes.Empty();
			for (int32 PinIndex = 0; PinIndex < InputPins.Num(); ++PinIndex)
			{
				UEdGraphPin* ChildPin = InputPins[PinIndex];

				if (ChildPin->LinkedTo.Num() > 0)
				{
					USoundCueGraphNode* GraphChildNode = CastChecked<USoundCueGraphNode>(ChildPin->LinkedTo[0]->GetOwningNode());
					ChildNodes.Add(GraphChildNode->SoundNode);
				}
				else
				{
					ChildNodes.AddZeroed();
				}
			}

			GraphNode->SoundNode->SetFlags(RF_Transactional);
			GraphNode->SoundNode->Modify();
			GraphNode->SoundNode->SetChildNodes(ChildNodes);
			GraphNode->SoundNode->PostEditChange();
		}
		else
		{
			// Set FirstNode based on RootNode connection
			USoundCueGraphNode_Root* RootNode = Cast<USoundCueGraphNode_Root>(SoundCueGraph->Nodes[NodeIndex]);
			if (RootNode)
			{
				Modify();
				if (RootNode->Pins[0]->LinkedTo.Num() > 0)
				{
					FirstNode = CastChecked<USoundCueGraphNode>(RootNode->Pins[0]->LinkedTo[0]->GetOwningNode())->SoundNode;
				}
				else
				{
					FirstNode = NULL;
				}
				PostEditChange();
			}
		}
	}
}
/**
 * Converts the UObject accessible array into the native only analytics array type
 */
static inline TArray<FAnalyticsEventAttribute> ConvertAttrs(const TArray<FAnalyticsEventAttr>& Attributes)
{
	TArray<FAnalyticsEventAttribute> Converted;
	Converted.AddZeroed(Attributes.Num());
	for (int32 Index = 0; Index < Attributes.Num(); Index++)
	{
		Converted[Index].AttrName = Attributes[Index].Name;
		Converted[Index].AttrValue = Attributes[Index].Value;
	}
	return Converted;
}
	FBoundaryImage(const FIntPoint& Pos, const FIntPoint& Size)
	{
		OutOfBoundsValue = 0;

		X0 = Pos.X - 1;
		Y0 = Pos.Y - 1;
		Width = Size.X + 2;
		Height = Size.Y + 2;

		Pixels.AddZeroed(Width * Height);
	}
/** Invert mapping - find final verts that  */
void CreateImportToFinalMap(const TArray<int32>& FinalToImportMap, int32 NumImportVerts, TArray< TArray<int32> >& OutImportToFinal)
{
	OutImportToFinal.Empty();
	OutImportToFinal.AddZeroed(NumImportVerts);

	for(int32 FinalVertIdx=0; FinalVertIdx<FinalToImportMap.Num(); FinalVertIdx++)
	{
		int32 ImportVert = FinalToImportMap[FinalVertIdx];
		OutImportToFinal[ImportVert].Add(FinalVertIdx);
	}
}
void UAnimPreviewInstance::MontagePreview_SetLoopAllSetupSections(bool bIsLooping)
{
	if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset))
	{
		MontagePreview_ResetSectionsOrder();

		int32 TotalSection = Montage->CompositeSections.Num();
		if (TotalSection > 0)
		{
			FName FirstSection = Montage->CompositeSections[0].SectionName;
			FName PreviousSection = FirstSection;
			TArray<bool> AlreadyUsed;
			AlreadyUsed.AddZeroed(TotalSection);
			while (true)
			{
				// find first not already used section
				int32 NotUsedIdx = 0;
				while (NotUsedIdx < TotalSection)
				{
					if (! AlreadyUsed[NotUsedIdx])
					{
						break;
					}
					++ NotUsedIdx;
				}
				if (NotUsedIdx >= TotalSection)
				{
					break;
				}
				// go through all connected to join them into one big chain
				int CurSectionIdx = NotUsedIdx;
				while (true)
				{
					AlreadyUsed[CurSectionIdx] = true;
					FName CurrentSection = Montage->CompositeSections[CurSectionIdx].SectionName;
					Montage_SetNextSection(PreviousSection, CurrentSection);
					PreviousSection = CurrentSection;

					FName NextSection = Montage->CompositeSections[CurSectionIdx].NextSectionName;
					CurSectionIdx = Montage->GetSectionIndex(NextSection);
					if (CurSectionIdx == INDEX_NONE || AlreadyUsed[CurSectionIdx]) // break loops
					{
						break;
					}
				}
			}
			if (bIsLooping)
			{
				// and loop all
				Montage_SetNextSection(PreviousSection, FirstSection);
			}
		}
	}
}
FSlateUpdatableTexture* FSlateOpenGLRenderer::CreateUpdatableTexture(uint32 Width, uint32 Height)
{
	TArray<uint8> RawData;
	RawData.AddZeroed(4);
	FSlateOpenGLTexture* NewTexture = new FSlateOpenGLTexture(Width, Height);
#if !PLATFORM_USES_ES2
	NewTexture->Init(GL_SRGB8_ALPHA8, RawData);
#else
	NewTexture->Init(GL_SRGB8_ALPHA8_EXT, RawData);
#endif
	return NewTexture;
}
void UPoseableMeshComponent::FillSpaceBases()
{
	SCOPE_CYCLE_COUNTER(STAT_SkelComposeTime);

	if( !SkeletalMesh )
	{
		return;
	}

	// right now all this does is to convert to SpaceBases
	check( SkeletalMesh->RefSkeleton.GetNum() == LocalAtoms.Num() );
	check( SkeletalMesh->RefSkeleton.GetNum() == GetNumSpaceBases());
	check( SkeletalMesh->RefSkeleton.GetNum() == BoneVisibilityStates.Num() );

	const int32 NumBones = LocalAtoms.Num();

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
	/** Keep track of which bones have been processed for fast look up */
	TArray<uint8> BoneProcessed;
	BoneProcessed.AddZeroed(NumBones);
#endif
	// Build in 3 passes.
	FTransform* LocalTransformsData = LocalAtoms.GetData(); 
	FTransform* SpaceBasesData = GetEditableSpaceBases().GetData();
	
	GetEditableSpaceBases()[0] = LocalAtoms[0];
#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
	BoneProcessed[0] = 1;
#endif

	for(int32 BoneIndex=1; BoneIndex<LocalAtoms.Num(); BoneIndex++)
	{
		FPlatformMisc::Prefetch(SpaceBasesData + BoneIndex);

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
		// Mark bone as processed
		BoneProcessed[BoneIndex] = 1;
#endif
		// For all bones below the root, final component-space transform is relative transform * component-space transform of parent.
		const int32 ParentIndex = SkeletalMesh->RefSkeleton.GetParentIndex(BoneIndex);
		FPlatformMisc::Prefetch(SpaceBasesData + ParentIndex);

#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
		// Check the precondition that Parents occur before Children in the RequiredBones array.
		checkSlow(BoneProcessed[ParentIndex] == 1);
#endif
		FTransform::Multiply(SpaceBasesData + BoneIndex, LocalTransformsData + BoneIndex, SpaceBasesData + ParentIndex);

		checkSlow(GetEditableSpaceBases()[BoneIndex].IsRotationNormalized());
		checkSlow(!GetEditableSpaceBases()[BoneIndex].ContainsNaN());
	}
	bNeedToFlipSpaceBaseBuffers = true;
}
Beispiel #26
0
void SaveExr(UTextureRenderTarget2D* RenderTarget, FString Filename)
{
	SCOPE_CYCLE_COUNTER(STAT_SaveExr)
	int32 Width = RenderTarget->SizeX, Height = RenderTarget->SizeY;
	TArray<FFloat16Color> FloatImage;
	FloatImage.AddZeroed(Width * Height);
	FTextureRenderTargetResource* RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource();
	RenderTargetResource->ReadFloat16Pixels(FloatImage);

	TArray<uint8> ExrData = SerializationUtils::Image2Exr(FloatImage, Width, Height);
	FFileHelper::SaveArrayToFile(ExrData, *Filename);
}
Beispiel #27
0
/**
 * Executes async DDC gets for chunks stored in the derived data cache.
 * @param Chunks - Chunks to retrieve.
 * @param FirstChunkToLoad - Index of the first chunk to retrieve.
 * @param OutHandles - Handles to the asynchronous DDC gets.
 */
static void BeginLoadDerivedChunks(TIndirectArray<FStreamedAudioChunk>& Chunks, int32 FirstChunkToLoad, TArray<uint32>& OutHandles)
{
	FDerivedDataCacheInterface& DDC = GetDerivedDataCacheRef();
	OutHandles.AddZeroed(Chunks.Num());
	for (int32 ChunkIndex = FirstChunkToLoad; ChunkIndex < Chunks.Num(); ++ChunkIndex)
	{
		const FStreamedAudioChunk& Chunk = Chunks[ChunkIndex];
		if (!Chunk.DerivedDataKey.IsEmpty())
		{
			OutHandles[ChunkIndex] = DDC.GetAsynchronous(*Chunk.DerivedDataKey);
		}
	}
}
void UBlendSpaceBase::NormalizeSampleDataWeight(TArray<FBlendSampleData> & SampleDataList) const
{
	float TotalSum=0.f;

	TArray<float> PerBoneTotalSums;
	PerBoneTotalSums.AddZeroed(PerBoneBlend.Num());

	for (int32 I=0; I<SampleDataList.Num(); ++I)
	{
		const int32 SampleDataIndex = SampleDataList[I].SampleDataIndex;
		// need to verify if valid sample index
		if ( SampleData.IsValidIndex(SampleDataIndex) )
		{
			TotalSum += SampleDataList[I].GetWeight();

			if ( SampleDataList[I].PerBoneBlendData.Num() > 0 )
			{
				// now interpolate the per bone weights
				for (int32 Iter = 0; Iter<SampleDataList[I].PerBoneBlendData.Num(); ++Iter)
				{
					PerBoneTotalSums[Iter] += SampleDataList[I].PerBoneBlendData[Iter];
				}
			}
		}
	}

	if ( ensure (TotalSum > ZERO_ANIMWEIGHT_THRESH) )
	{
		for (int32 I=0; I<SampleDataList.Num(); ++I)
		{
			const int32 SampleDataIndex = SampleDataList[I].SampleDataIndex;
			if ( SampleData.IsValidIndex(SampleDataIndex) )
			{
				if (FMath::Abs<float>(TotalSum - 1.f) > ZERO_ANIMWEIGHT_THRESH)
				{
					SampleDataList[I].TotalWeight /= TotalSum;
				}

				// now interpolate the per bone weights
				for (int32 Iter = 0; Iter<SampleDataList[I].PerBoneBlendData.Num(); ++Iter)
				{
					if (FMath::Abs<float>(PerBoneTotalSums[Iter] - 1.f) > ZERO_ANIMWEIGHT_THRESH)
					{
						SampleDataList[I].PerBoneBlendData[Iter] /= PerBoneTotalSums[Iter];
					}
				}
			}
		}
	}
}
Beispiel #29
0
// function is similar to part of CSkelMeshInstance::SetMesh() and Rune mesh loader
static void BuildSkeleton(TArray<CCoords> &Coords, const TArray<CSkelMeshBone> &Bones)
{
	guard(BuildSkeleton);

	int numBones = Bones.Num();
	Coords.Empty(numBones);
	Coords.AddZeroed(numBones);

	for (int i = 0; i < numBones; i++)
	{
		const CSkelMeshBone &B = Bones[i];
		CCoords &BC = Coords[i];
		// compute reference bone coords
		CVec3 BP;
		CQuat BO;
		// get default pose
		BP = B.Position;
		BO = B.Orientation;
#if MIRROR_MESH
		BP[1] *= -1;							// y
		BO.y  *= -1;
		BO.w  *= -1;
#endif
		if (!i) BO.Conjugate();					// root bone

		BC.origin = BP;
		BO.ToAxis(BC.axis);
		// move bone position to global coordinate space
		if (i)	// do not rotate root bone
		{
			assert(B.ParentIndex < i);
			Coords[B.ParentIndex].UnTransformCoords(BC, BC);
		}
#if 0
	//!!
if (i == 32)
{
	appNotify("Bone %d (%8.3f %8.3f %8.3f) - (%8.3f %8.3f %8.3f %8.3f)", i, VECTOR_ARG(BP), QUAT_ARG(BO));
#define C BC
	appNotify("REF   : o=%8.3f %8.3f %8.3f",    VECTOR_ARG(C.origin ));
	appNotify("        0=%8.3f %8.3f %8.3f",    VECTOR_ARG(C.axis[0]));
	appNotify("        1=%8.3f %8.3f %8.3f",    VECTOR_ARG(C.axis[1]));
	appNotify("        2=%8.3f %8.3f %8.3f",    VECTOR_ARG(C.axis[2]));
#undef C
}
#endif
	}

	unguard;
}
/**
* Process and fill in the mesh ref skeleton bone hierarchy using the raw binary import data
* 
* @param RefSkeleton - [out] reference skeleton hierarchy to update
* @param SkeletalDepth - [out] depth of the reference skeleton hierarchy
* @param ImportData - raw binary import data to process
* @return true if the operation completed successfully
*/
bool ProcessImportMeshSkeleton(FReferenceSkeleton& RefSkeleton, int32& SkeletalDepth, FSkeletalMeshImportData& ImportData)
{
	TArray <VBone>&	RefBonesBinary = ImportData.RefBonesBinary;

	// Setup skeletal hierarchy + names structure.
	RefSkeleton.Empty();

	// Digest bones to the serializable format.
	for( int32 b=0; b<RefBonesBinary.Num(); b++ )
	{
		const VBone & BinaryBone = RefBonesBinary[ b ];
		const FString BoneName = FSkeletalMeshImportData::FixupBoneName( BinaryBone.Name );
		const FMeshBoneInfo BoneInfo(FName(*BoneName, FNAME_Add, true), BinaryBone.ParentIndex);
		const FTransform BoneTransform(BinaryBone.BonePos.Orientation, BinaryBone.BonePos.Position, FVector(1.f));

		if(RefSkeleton.FindBoneIndex(BoneInfo.Name) != INDEX_NONE)
		{
			UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
			FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("SkeletonHasDuplicateBones", "Skeleton has non-unique bone names.\nBone named '{0}' encountered more than once."), FText::FromName(BoneInfo.Name))));
			return false;
		}

		RefSkeleton.Add(BoneInfo, BoneTransform);
	}

	// Add hierarchy index to each bone and detect max depth.
	SkeletalDepth = 0;

	TArray<int32> SkeletalDepths;
	SkeletalDepths.Empty( RefBonesBinary.Num() );
	SkeletalDepths.AddZeroed( RefBonesBinary.Num() );
	for( int32 b=0; b < RefSkeleton.GetNum(); b++ )
	{
		int32 Parent	= RefSkeleton.GetParentIndex(b);
		int32 Depth	= 1.0f;

		SkeletalDepths[b]	= 1.0f;
		if( Parent != INDEX_NONE )
		{
			Depth += SkeletalDepths[Parent];
		}
		if( SkeletalDepth < Depth )
		{
			SkeletalDepth = Depth;
		}
		SkeletalDepths[b] = Depth;
	}

	return true;
}