void FIndirectLightingCache::UpdateCacheAllocation(
	const FBoxSphereBounds& Bounds, 
	int32 BlockSize,
	bool bOpaqueRelevance,
	FIndirectLightingCacheAllocation*& Allocation, 
	TMap<FIntVector, FBlockUpdateInfo>& BlocksToUpdate,
	TArray<FIndirectLightingCacheAllocation*>& TransitionsOverTimeToUpdate)
{
	if (Allocation && Allocation->IsValid())
	{
		FIndirectLightingCacheBlock& Block = FindBlock(Allocation->MinTexel);

		// Calculate a potentially new min and size based on the current bounds
		FVector NewMin;
		FVector NewSize;
		CalculateBlockPositionAndSize(Bounds, Block.TexelSize, NewMin, NewSize);

		// If the primitive has moved enough to change its block min and size, we need to interpolate it again
		if (Allocation->bIsDirty || GCacheUpdateEveryFrame || !Block.Min.Equals(NewMin) || !Block.Size.Equals(NewSize))
		{
			// Update the block and primitive allocation with the new bounds
			Block.Min = NewMin;
			Block.Size = NewSize;

			FVector NewScale;
			FVector NewAdd;
			FVector MinUV;
			FVector MaxUV;
			CalculateBlockScaleAndAdd(Allocation->MinTexel, Allocation->AllocationTexelSize, NewMin, NewSize, NewScale, NewAdd, MinUV, MaxUV);

			Allocation->SetParameters(Allocation->MinTexel, Allocation->AllocationTexelSize, NewScale, NewAdd, MinUV, MaxUV, bOpaqueRelevance);
			BlocksToUpdate.Add(Block.MinTexel, FBlockUpdateInfo(Block, Allocation));
		}

		if ((Allocation->SingleSamplePosition - Allocation->TargetPosition).SizeSquared() > DELTA)
		{
			TransitionsOverTimeToUpdate.AddUnique(Allocation);
		}
	}
	else
	{
		delete Allocation;
		Allocation = CreateAllocation(BlockSize, Bounds, bOpaqueRelevance);

		if (Allocation->IsValid())
		{
			// Must interpolate lighting for this new block
			BlocksToUpdate.Add(Allocation->MinTexel, FBlockUpdateInfo(VolumeBlocks.FindChecked(Allocation->MinTexel), Allocation));
		}
	}
}
FIndirectLightingCacheAllocation* FIndirectLightingCache::AllocatePrimitive(const FPrimitiveSceneInfo* PrimitiveSceneInfo, bool bUnbuiltPreview)
{
	const bool bPointSample = PrimitiveSceneInfo->Proxy->GetIndirectLightingCacheQuality() == ILCQ_Point || bUnbuiltPreview;
	const int32 BlockSize = bPointSample ? 1 : GLightingCacheMovableObjectAllocationSize;
	return PrimitiveAllocations.Add(PrimitiveSceneInfo->PrimitiveComponentId, CreateAllocation(BlockSize, PrimitiveSceneInfo->Proxy->GetBounds(), bPointSample, bUnbuiltPreview));
}
FIndirectLightingCacheAllocation* FIndirectLightingCache::AllocatePrimitive(const FPrimitiveSceneInfo* PrimitiveSceneInfo, bool bUnbuiltPreview)
{
	const int32 BlockSize = bUnbuiltPreview ? GLightingCacheUnbuiltPreviewAllocationSize : GLightingCacheMovableObjectAllocationSize;
	return PrimitiveAllocations.Add(PrimitiveSceneInfo->PrimitiveComponentId, CreateAllocation(BlockSize, PrimitiveSceneInfo->Proxy->GetBounds(), true));
}