// 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; }
/** * 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; }
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); } }
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(); } }
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; }
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; }
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); }
/** * 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]; } } } } } }
// 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; }