FIndirectLightingCacheAllocation* FIndirectLightingCache::CreateAllocation(int32 BlockSize, const FBoxSphereBounds& Bounds, bool bPointSample, bool bUnbuiltPreview) { check(BlockSize > 1 || bPointSample); FIndirectLightingCacheAllocation* NewAllocation = new FIndirectLightingCacheAllocation(); FIndirectLightingCacheBlock NewBlock; //@todo - don't allocate point samples from the layout, they don't go through the volume texture if (AllocateBlock(BlockSize, NewBlock.MinTexel)) { NewBlock.TexelSize = BlockSize; CalculateBlockPositionAndSize(Bounds, BlockSize, NewBlock.Min, NewBlock.Size); FVector Scale; FVector Add; FVector MinUV; FVector MaxUV; CalculateBlockScaleAndAdd(NewBlock.MinTexel, NewBlock.TexelSize, NewBlock.Min, NewBlock.Size, Scale, Add, MinUV, MaxUV); VolumeBlocks.Add(NewBlock.MinTexel, NewBlock); NewAllocation->SetParameters(NewBlock.MinTexel, NewBlock.TexelSize, Scale, Add, MinUV, MaxUV, bPointSample, bUnbuiltPreview); } return NewAllocation; }
void FIndirectLightingCache::ReleasePrimitive(FPrimitiveComponentId PrimitiveId) { FIndirectLightingCacheAllocation* PrimitiveAllocation; if (PrimitiveAllocations.RemoveAndCopyValue(PrimitiveId, PrimitiveAllocation)) { check(PrimitiveAllocation); if (PrimitiveAllocation->IsValid()) { DeallocateBlock(PrimitiveAllocation->MinTexel, PrimitiveAllocation->AllocationTexelSize); } delete PrimitiveAllocation; } }
FIndirectLightingCacheAllocation* FIndirectLightingCache::CreateAllocation(int32 BlockSize, const FBoxSphereBounds& Bounds, bool bOpaqueRelevance) { FIndirectLightingCacheAllocation* NewAllocation = new FIndirectLightingCacheAllocation(); FIndirectLightingCacheBlock NewBlock; if (AllocateBlock(BlockSize, NewBlock.MinTexel)) { NewBlock.TexelSize = BlockSize; CalculateBlockPositionAndSize(Bounds, BlockSize, NewBlock.Min, NewBlock.Size); FVector Scale; FVector Add; FVector MinUV; FVector MaxUV; CalculateBlockScaleAndAdd(NewBlock.MinTexel, NewBlock.TexelSize, NewBlock.Min, NewBlock.Size, Scale, Add, MinUV, MaxUV); VolumeBlocks.Add(NewBlock.MinTexel, NewBlock); NewAllocation->SetParameters(NewBlock.MinTexel, NewBlock.TexelSize, Scale, Add, MinUV, MaxUV, bOpaqueRelevance); } return NewAllocation; }
void FPrimitiveSceneInfo::AddToScene(bool bUpdateStaticDrawLists) { check(IsInRenderingThread()); // If we are attaching a primitive that should be statically lit but has unbuilt lighting, // Allocate space in the indirect lighting cache so that it can be used for previewing indirect lighting if (Proxy->HasStaticLighting() && Proxy->NeedsUnbuiltPreviewLighting() && IsIndirectLightingCacheAllowed()) { FIndirectLightingCacheAllocation* PrimitiveAllocation = Scene->IndirectLightingCache.FindPrimitiveAllocation(PrimitiveComponentId); if (PrimitiveAllocation) { IndirectLightingCacheAllocation = PrimitiveAllocation; PrimitiveAllocation->SetDirty(); } else { PrimitiveAllocation = Scene->IndirectLightingCache.AllocatePrimitive(this, true); PrimitiveAllocation->SetDirty(); IndirectLightingCacheAllocation = PrimitiveAllocation; } } if (bUpdateStaticDrawLists) { AddStaticMeshes(); } // create potential storage for our compact info FPrimitiveSceneInfoCompact LocalCompactPrimitiveSceneInfo; FPrimitiveSceneInfoCompact* CompactPrimitiveSceneInfo = &LocalCompactPrimitiveSceneInfo; // if we are being added directly to the Octree, initialize the temp compact scene info, // and let the Octree make a copy of it LocalCompactPrimitiveSceneInfo.Init(this); // Add the primitive to the octree. check(!OctreeId.IsValidId()); Scene->PrimitiveOctree.AddElement(LocalCompactPrimitiveSceneInfo); check(OctreeId.IsValidId()); // Set bounds. FPrimitiveBounds& PrimitiveBounds = Scene->PrimitiveBounds[PackedIndex]; FBoxSphereBounds BoxSphereBounds = Proxy->GetBounds(); PrimitiveBounds.Origin = BoxSphereBounds.Origin; PrimitiveBounds.SphereRadius = BoxSphereBounds.SphereRadius; PrimitiveBounds.BoxExtent = BoxSphereBounds.BoxExtent; PrimitiveBounds.MinDrawDistanceSq = FMath::Square(Proxy->GetMinDrawDistance()); PrimitiveBounds.MaxDrawDistance = Proxy->GetMaxDrawDistance(); // Store precomputed visibility ID. int32 VisibilityBitIndex = Proxy->GetVisibilityId(); FPrimitiveVisibilityId& VisibilityId = Scene->PrimitiveVisibilityIds[PackedIndex]; VisibilityId.ByteIndex = VisibilityBitIndex / 8; VisibilityId.BitMask = (1 << (VisibilityBitIndex & 0x7)); // Store occlusion flags. uint8 OcclusionFlags = EOcclusionFlags::None; if (Proxy->CanBeOccluded()) { OcclusionFlags |= EOcclusionFlags::CanBeOccluded; } if (Proxy->AllowApproximateOcclusion() // Allow approximate occlusion if attached, even if the parent does not have bLightAttachmentsAsGroup enabled || LightingAttachmentRoot.IsValid()) { OcclusionFlags |= EOcclusionFlags::AllowApproximateOcclusion; } if (VisibilityBitIndex >= 0) { OcclusionFlags |= EOcclusionFlags::HasPrecomputedVisibility; } Scene->PrimitiveOcclusionFlags[PackedIndex] = OcclusionFlags; // Store occlusion bounds. FBoxSphereBounds OcclusionBounds = BoxSphereBounds; if (Proxy->HasCustomOcclusionBounds()) { OcclusionBounds = Proxy->GetCustomOcclusionBounds(); } OcclusionBounds.BoxExtent.X = OcclusionBounds.BoxExtent.X + OCCLUSION_SLOP; OcclusionBounds.BoxExtent.Y = OcclusionBounds.BoxExtent.Y + OCCLUSION_SLOP; OcclusionBounds.BoxExtent.Z = OcclusionBounds.BoxExtent.Z + OCCLUSION_SLOP; OcclusionBounds.SphereRadius = OcclusionBounds.SphereRadius + OCCLUSION_SLOP; Scene->PrimitiveOcclusionBounds[PackedIndex] = OcclusionBounds; // Store the component. Scene->PrimitiveComponentIds[PackedIndex] = PrimitiveComponentId; bNeedsCachedReflectionCaptureUpdate = true; { FMemMark MemStackMark(FMemStack::Get()); // Find lights that affect the primitive in the light octree. for (FSceneLightOctree::TConstElementBoxIterator<SceneRenderingAllocator> LightIt(Scene->LightOctree, Proxy->GetBounds().GetBox()); LightIt.HasPendingElements(); LightIt.Advance()) { const FLightSceneInfoCompact& LightSceneInfoCompact = LightIt.GetCurrentElement(); if (LightSceneInfoCompact.AffectsPrimitive(*CompactPrimitiveSceneInfo)) { FLightPrimitiveInteraction::Create(LightSceneInfoCompact.LightSceneInfo,this); } } } INC_MEMORY_STAT_BY(STAT_PrimitiveInfoMemory, sizeof(*this) + StaticMeshes.GetAllocatedSize() + Proxy->GetMemoryFootprint()); }