public static void PerformOctreesEdit(this LargeWorldStreamer largeWorldStreamer, Int3.Bounds blockBounds, LargeWorldStreamer.DistanceField df, bool isAdd = false, byte type = 1) { VoxelandData.OctNode.BlendArgs args = new VoxelandData.OctNode.BlendArgs(isAdd ? VoxelandData.OctNode.BlendOp.Union : VoxelandData.OctNode.BlendOp.Subtraction, false, isAdd ? type : (byte)0); var streamerV2 = largeWorldStreamer.streamerV2; materialTypeOfLastOctreesEditAdd = 0; blockBounds = blockBounds.Expanded(1); foreach (Int3 @int in blockBounds / largeWorldStreamer.blocksPerTree) { if (largeWorldStreamer.CheckRoot(@int)) { Octree octree = streamerV2.octreesStreamer.GetOctree(@int); if (octree != null) { Int3.Bounds bounds = @int.Refined(largeWorldStreamer.blocksPerTree); VoxelandData.OctNode root = octree.ToVLOctree(); foreach (Int3 int2 in bounds.Intersect(blockBounds)) { Vector3 wsPos = largeWorldStreamer.land.transform.TransformPoint(int2 + UWE.Utils.half3); float num = df(wsPos); if (num >= 0f) { VoxelandData.OctNode i = new VoxelandData.OctNode(type, VoxelandData.OctNode.EncodeDensity(num)); int blocksPerTree = largeWorldStreamer.blocksPerTree; int x = int2.x % blocksPerTree; int y = int2.y % blocksPerTree; int z = int2.z % blocksPerTree; var node = root.GetNode(x, y, z, blocksPerTree / 2); if (!isAdd && materialTypeOfLastOctreesEditAdd <= node.type) { materialTypeOfLastOctreesEditAdd = node.type; } VoxelandData.OctNode octNode = VoxelandData.OctNode.Blend(node, i, args); root.SetNode(x, y, z, blocksPerTree / 2, octNode.type, octNode.density); } } root.Collapse(); streamerV2.octreesStreamer.SetBatchOctree(@int, root); root.Clear(); } } } streamerV2.clipmapStreamer.AddToRangesEdited(blockBounds); }
static public void SetOctree(this BatchOctrees batchOctrees, Int3 octreeId, VoxelandData.OctNode root) { var allocator = batchOctrees.allocator; var octree = batchOctrees.GetOctree(octreeId); octree.Set(root, allocator); if (!dirtyBatches.Contains(batchOctrees)) { dirtyBatches.Add(batchOctrees); } }
private static VoxelandData.OctNode ToVLOctNodeRecursive(this Octree octree, int nid) { CompactOctree.Node node = octree.GetNode(nid); VoxelandData.OctNode octNode = node.ToVLNode(); if (!octree.IsLeaf(nid)) { octNode.childNodes = VoxelandData.OctNode.childNodesPool.Get(); for (int i = 0; i < 8; i++) { octNode.childNodes[i] = octree.ToVLOctNodeRecursive(node.firstChildId + i); } } return(octNode); }
public static void Set(this Octree octree, VoxelandData.OctNode root, LinearArrayHeap <byte> allocator) #endif { int num = root.CountNodes() * 4; octree.Clear(allocator); #if BelowZero var octreeData = allocator.Get(num); #else var octreeData = allocator.Allocate(num); #endif octree.data = octreeData; ushort num2 = 1; octree.SetInternal(root, 0, ref num2); }
private static void SetInternal(this Octree octree, VoxelandData.OctNode node, int nodeId, ref ushort nextFreeId) { if (node.IsLeaf()) { octree.SetNode(nodeId, node.type, node.density, 0); } else { ushort num = nextFreeId; octree.SetNode(nodeId, node.type, node.density, num); nextFreeId += 8; for (int i = 0; i < 8; i++) { octree.SetInternal(node.childNodes[i], num + i, ref nextFreeId); } } }
public static void Set(this Octree octree, VoxelandData.OctNode root, SplitNativeArrayPool <byte> allocator)
public static void SetBatchOctree(this BatchOctreesStreamer batchOctreesStreamer, Int3 absoluteOctreeId, VoxelandData.OctNode root) { var numOctreesPerBatch = batchOctreesStreamer.numOctreesPerBatch; var batchId = Int3.FloorDiv(absoluteOctreeId, numOctreesPerBatch); var batch = batchOctreesStreamer.GetBatch(batchId); var octreeId = absoluteOctreeId - (batchId * numOctreesPerBatch); Logger.Debug($"numOctreesPerBatch = {numOctreesPerBatch}, batchId = {batchId}, octreeId = {octreeId}, absoluteOctreeId = {absoluteOctreeId}"); batch.SetOctree(octreeId, root); }