public void Op(ref Vector3I position, MyStorageDataTypeEnum dataType, ref byte inOutContent) { if (inOutContent != MyVoxelConstants.VOXEL_CONTENT_EMPTY) { inOutContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } }
public void Op(ref Vector3I pos, MyStorageDataTypeEnum dataType, ref byte content) { if (content != MyVoxelConstants.VOXEL_CONTENT_EMPTY) { HasHit = true; } }
public MyProviderLeaf(IMyStorageDataProvider provider, MyStorageDataTypeEnum dataType, ref Vector3I leafMin, ref Vector3I leafMax) { m_provider = provider; m_dataType = dataType; m_leafMin = leafMin; m_leafMax = leafMax; }
public void BlockFill(MyStorageDataTypeEnum type, Vector3I min, Vector3I max, byte content) { AssertPosition(ref min); AssertPosition(ref max); min.Z *= m_sZ; max.Z *= m_sZ; min.Y *= m_sY; max.Y *= m_sY; min.X *= m_sX; max.X *= m_sX; unsafe { fixed(byte *c = &this[type][0]) { Vector3I p; for (p.Z = min.Z; p.Z <= max.Z; p.Z += m_sZ) { int z = p.Z; for (p.Y = min.Y; p.Y <= max.Y; p.Y += m_sY) { for (p.X = min.X; p.X <= max.X; p.X += m_sX) { c[p.X + p.Y + z] = content; } } } } } }
public byte[] this[MyStorageDataTypeEnum type] { get { Debug.Assert(((int)m_storedTypes & (1 << (int)type)) != 0); return(m_dataByType[(int)type]); } }
public void Clear(MyStorageDataTypeEnum type, byte p) { var data = this[type]; for (int i = 0; i < m_sizeLinear; i += StepLinear) { data[i] = p; } }
public void ClearMaterials(byte p) { const MyStorageDataTypeEnum type = MyStorageDataTypeEnum.Material; for (int i = (int)type; i < m_sizeLinear; i += StepLinear) { m_data[i] = p; } }
public void ClearContent(byte p) { const MyStorageDataTypeEnum type = MyStorageDataTypeEnum.Content; for (int i = (int)type; i < m_sizeLinear; i += StepLinear) { m_data[i] = p; } }
void IMyStorageDataProvider.ReadRange(MyStorageDataCache target, MyStorageDataTypeEnum dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod) { if (dataType == MyStorageDataTypeEnum.Content) { ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod); } else { ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod); } }
public MyMicroOctreeLeaf(MyStorageDataTypeEnum dataType, int height, Vector3I voxelRangeMin) { Debug.Assert(dataType == MyStorageDataTypeEnum.Content || dataType == MyStorageDataTypeEnum.Material); m_octree = new MySparseOctree(height, dataType == MyStorageDataTypeEnum.Content ? MyOctreeNode.ContentFilter : MyOctreeNode.MaterialFilter); m_dataType = dataType; m_voxelRangeMin = voxelRangeMin; }
internal void ExecuteOperation <TOperator>(ref TOperator source, MyStorageDataTypeEnum type, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max) where TOperator : struct, IVoxelOperator { if (source.Flags == VoxelOperatorFlags.Read) { this.ReadRange <TOperator>(ref source, type, ref readOffset, 0, ref min, ref max); } else { this.WriteRange <TOperator>(new MyCellCoord(this.m_treeHeight - 1, Vector3I.Zero), this.m_defaultContent, ref source, type, ref readOffset, ref min, ref max); } }
public MortonEnumerator(MyStorageData source, MyStorageDataTypeEnum type) { Debug.Assert(source.Size3D.X == source.Size3D.Y && source.Size3D.Y == source.Size3D.Z); Debug.Assert(source.Size3D.IsPowerOfTwo); m_type = type; m_source = source; m_maxMortonCode = source.Size3D.Size; m_mortonCode = -1; m_pos = default(Vector3I); m_current = 0; }
public void Op(ref Vector3I pos, MyStorageDataTypeEnum dataType, ref byte content) { if (content != 0) { Vector3D vectord = (Vector3D)pos; if (Vector3D.DistanceSquared(this.Center, vectord) < this.RadSq) { this.Changed = true; content = 0; } } }
public int ValueWhenAllEqual(MyStorageDataTypeEnum dataType) { var data = this[dataType]; byte first = data[0]; for (int i = 1; i < m_sizeLinear; i += StepLinear) { if (first != data[i]) { return(-1); } } return(first); }
private unsafe void ReadLod(MyStorageData target, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, int lod, Vector3I min, Vector3I max) { int offset = 0; for (int i = 0; i < lod; ++i) { offset += Volume >> (i + i + i); } var sy = Size >> lod; var sz = sy * sy; min.Y *= sy; min.Z *= sz; max.Y *= sy; max.Z *= sz; int tsx = target.StepX, tsy = target.StepY, tsz = target.StepZ; tofft.Y *= tsy; tofft.Z *= tsz; fixed(byte *fixedDataArray = dataArray) fixed(byte *targetData = target[dataType]) { byte *voxel = fixedDataArray + offset; int x, y, z; int tx, ty, tz; for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz) { for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy) { for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx) { targetData[tz + ty + tx] = voxel[z + y + x]; } } } } }
public byte[] this[MyStorageDataTypeEnum type] { get { Debug.Assert(((int)m_storedTypes & (1 << (int)type)) != 0); return(m_dataByType[(int)type]); } set { Debug.Assert(value.Length >= m_sizeLinear && (m_dataSizeLinear == -1 || value.Length == m_dataSizeLinear)); if (m_dataSizeLinear == -1) { m_dataSizeLinear = value.Length; } m_dataByType[(int)type] = value; } }
// Token: 0x06008150 RID: 33104 RVA: 0x00348D5C File Offset: 0x00346F5C public void Op(ref Vector3I pos, MyStorageDataTypeEnum dataType, ref byte content) { VoxelsProcessed++; if (content == 0) { return; } Vector3D value = pos; double dist = Vector3D.DistanceSquared(LocalCenter, value); if (dist < Radius * Radius) { VoxelsRemoved++; content = MyVoxelConstants.VOXEL_CONTENT_EMPTY; } else { Log.WriteToLog("CutOutSphereCustom.Op", $"Dist: {Math.Round(dist, 2)}"); } }
private unsafe void Write(MyStorageData source, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, Vector3I min, Vector3I max) { Debug.Assert(Cached.Requests(dataType) || (min == Vector3I.Zero && max == MaxVector)); var sy = Size; var sz = sy * sy; min.Y *= sy; min.Z *= sz; max.Y *= sy; max.Z *= sz; int tsx = source.StepX, tsy = source.StepY, tsz = source.StepZ; tofft.Y *= tsy; tofft.Z *= tsz; fixed(byte *voxel = dataArray) fixed(byte *sourceData = source[dataType]) { int x, y, z; int tx, ty, tz; for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz) { for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy) { for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx) { voxel[z + y + x] = sourceData[tz + ty + tx]; } } } } }
public byte Get(MyStorageDataTypeEnum type, ref Vector3I p) { AssertPosition(ref p); return(this[type][p.X * m_sX + p.Y * m_sY + p.Z * m_sZ]); }
private unsafe void Write(MyStorageData source, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, Vector3I min, Vector3I max) { Debug.Assert(Cached.Requests(dataType) || (min == Vector3I.Zero && max == MaxVector)); var sy = Size; var sz = sy * sy; min.Y *= sy; min.Z *= sz; max.Y *= sy; max.Z *= sz; int tsx = source.StepX, tsy = source.StepY, tsz = source.StepZ; tofft.Y *= tsy; tofft.Z *= tsz; fixed (byte* voxel = dataArray) fixed (byte* sourceData = source[dataType]) { int x, y, z; int tx, ty, tz; for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz) for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy) for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx) { voxel[z + y + x] = sourceData[tz + ty + tx]; } } }
private unsafe void ReadLod(MyStorageData target, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, int lod, Vector3I min, Vector3I max) { int offset = 0; for (int i = 0; i < lod; ++i) { offset += Volume >> (i + i + i); } var sy = Size >> lod; var sz = sy * sy; min.Y *= sy; min.Z *= sz; max.Y *= sy; max.Z *= sz; int tsx = target.StepX, tsy = target.StepY, tsz = target.StepZ; tofft.Y *= tsy; tofft.Z *= tsz; fixed (byte* fixedDataArray = dataArray) fixed (byte* targetData = target[dataType]) { byte* voxel = fixedDataArray + offset; int x, y, z; int tx, ty, tz; for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz) for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy) for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx) { targetData[tz + ty + tx] = voxel[z + y + x]; } } }
public void Set(MyStorageDataTypeEnum type, ref Vector3I p, byte value) { AssertPosition(ref p); m_data[p.X * m_sX + p.Y * m_sY + p.Z * m_sZ + (int)type] = value; }
public byte Get(MyStorageDataTypeEnum type, int x, int y, int z) { AssertPosition(x, y, z); return(m_data[x * m_sX + y * m_sY + z * m_sZ + (int)type]); }
public void Set(MyStorageDataTypeEnum type, ref Vector3I p, byte value) { AssertPosition(ref p); this[type][p.X * m_sX + p.Y * m_sY + p.Z * m_sZ] = value; }
public MyProviderLeaf(IMyStorageDataProvider provider, MyStorageDataTypeEnum dataType, ref MyCellCoord cell) { m_provider = provider; m_dataType = dataType; m_cell = cell; }
// Convert enum to flags public static MyStorageDataTypeFlags ToFlags(this MyStorageDataTypeEnum self) { return((MyStorageDataTypeFlags)(1 << (int)self)); }
// get the same flags except the provided type. public static MyStorageDataTypeFlags Without(this MyStorageDataTypeFlags self, MyStorageDataTypeEnum value) { return(self & ~(MyStorageDataTypeFlags)(1 << (int)value)); }
// Weather this flags request a given type of data public static bool Requests(this MyStorageDataTypeFlags self, MyStorageDataTypeEnum value) { return ((int)self & (1 << (int)value)) != 0; }
public static byte DefaultValue(MyStorageDataTypeEnum type) { return Defaults[(int) type]; }
public byte Get(MyStorageDataTypeEnum type, int linearIdx) { Debug.Assert(linearIdx < m_sizeLinear); return(this[type][linearIdx]); }
public byte Get(MyStorageDataTypeEnum type, int x, int y, int z) { AssertPosition(x, y, z); return(this[type][x * m_sX + y * m_sY + z * m_sZ]); }
public static byte DefaultValue(MyStorageDataTypeEnum type) { return(Defaults[(int)type]); }
void IMyStorageDataProvider.ReadRange(MyStorageDataCache target, MyStorageDataTypeEnum dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod) { if (dataType == MyStorageDataTypeEnum.Content) ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod); else ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod); }
public void Op(ref Vector3I position, MyStorageDataTypeEnum dataType, ref byte outData) { outData = this.m_data.Get(dataType, ref position); }
private static bool ResetOutsideBorders( IMyStorageDataProvider provider, MyStorageDataTypeEnum dataType, int lodIdx, Dictionary<UInt64, MyOctreeNode> nodes, Dictionary<UInt64, IMyOctreeLeafNode> leaves, Vector3I lodCoord, Vector3I minVoxel, Vector3I maxVoxel, out bool canCollapse, Dictionary<UInt64, IMyOctreeLeafNode> outResetLeaves = null) { canCollapse = false; bool changed = false; var currentCell = new MyCellCoord(lodIdx, lodCoord); var key = currentCell.PackId64(); var leafCell = currentCell; var leafKey = leafCell.PackId64(); IMyOctreeLeafNode leaf; if (leaves.TryGetValue(leafKey, out leaf)) { canCollapse = leaf.ReadOnly; if (leafCell.Lod != 0) { Debug.Assert(leaf.ReadOnly); return false; } else if (!leaf.ReadOnly) { var minCell = minVoxel >> (LeafLodCount + leafCell.Lod); var maxCell = maxVoxel >> (LeafLodCount + leafCell.Lod); if (!leafCell.CoordInLod.IsInsideInclusive(ref minCell, ref maxCell)) { canCollapse = true; leaves.Remove(leafKey); var leafCellCopy = leafCell; leafCellCopy.Lod += LeafLodCount; var leafNew = new MyProviderLeaf(provider, dataType, ref leafCellCopy); leaves.Add(leafKey, leafNew); changed = true; if (outResetLeaves != null) outResetLeaves.Add(leafKey, leafNew); } } } else { currentCell.Lod -= 1; key = currentCell.PackId64(); var nodeCell = currentCell; var nodeKey = currentCell.PackId64(); var node = nodes[nodeKey]; var childBase = lodCoord << 1; Vector3I childOffset; var minInChild = (minVoxel >> (LeafLodCount + currentCell.Lod)) - childBase; var maxInChild = (maxVoxel >> (LeafLodCount + currentCell.Lod)) - childBase; var leafSize = LeafSizeInVoxels << currentCell.Lod; unsafe { canCollapse = true; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; i++) { ComputeChildCoord(i, out childOffset); if (childOffset.IsInsideExclusive(ref minInChild, ref maxInChild)) { canCollapse = false; continue; } currentCell.CoordInLod = childBase + childOffset; if (node.HasChild(i)) { bool localCanCollapse; bool resetChanged = ResetOutsideBorders(provider, dataType, currentCell.Lod, nodes, leaves, currentCell.CoordInLod, minVoxel, maxVoxel, out localCanCollapse, outResetLeaves: outResetLeaves); changed = changed || resetChanged; canCollapse = localCanCollapse && canCollapse; } else { var currentCellCopy = currentCell; currentCellCopy.Lod += LeafLodCount; IMyOctreeLeafNode octreeLeaf = new MyProviderLeaf(provider, dataType, ref currentCellCopy); leaves.Add(currentCell.PackId64(), octreeLeaf); node.SetChild(i, true); node.SetData(i, octreeLeaf.GetFilteredValue()); changed = true; } } nodes[nodeKey] = node; if (canCollapse) { // Remove leaves for (int i = 0; i < MyOctreeNode.CHILD_COUNT; i++) { if (node.HasChild(i)) { ComputeChildCoord(i, out childOffset); currentCell.CoordInLod = childBase + childOffset; var childKey = currentCell.PackId64(); leaves.Remove(childKey); node.SetChild(i, false); } } // Remove node nodes.Remove(nodeKey); // Add leaf var leafCellCopy = leafCell; leafCellCopy.Lod += LeafLodCount; var leafNew = new MyProviderLeaf(provider, dataType, ref leafCellCopy); leaves.Add(leafKey, leafNew); } } } return changed; }
private void ReadOctreeLeaf(Stream stream, ChunkHeader header, ref bool isOldFormat, MyStorageDataTypeEnum dataType, out UInt64 key, out MyMicroOctreeLeaf contentLeaf) { Debug.Assert( header.ChunkType == ChunkTypeEnum.ContentLeafOctree || header.ChunkType == ChunkTypeEnum.MaterialLeafOctree); MyCellCoord cellCoord = new MyCellCoord(); if (header.Version <= VERSION_OCTREE_LEAVES_32BIT_KEY) { UInt32 oldKey = stream.ReadUInt32(); cellCoord.SetUnpack(oldKey); key = cellCoord.PackId64(); header.Size -= sizeof(UInt32); isOldFormat = true; } else { Debug.Assert(header.Version == CURRENT_VERSION_OCTREE_LEAVES); key = stream.ReadUInt64(); cellCoord.SetUnpack(key); header.Size -= sizeof(UInt64); } contentLeaf = new MyMicroOctreeLeaf(dataType, LeafLodCount, cellCoord.CoordInLod << (cellCoord.Lod + LeafLodCount)); contentLeaf.ReadFrom(header, stream); }
private static unsafe void ReadRange( MyStorageDataCache target, ref Vector3I targetWriteOffset, MyStorageDataTypeEnum type, int treeHeight, Dictionary<UInt64, MyOctreeNode> nodes, Dictionary<UInt64, IMyOctreeLeafNode> leaves, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod) { int stackIdx = 0; int stackSize = MySparseOctree.EstimateStackSize(treeHeight); MyCellCoord* stack = stackalloc MyCellCoord[stackSize]; MyCellCoord data = new MyCellCoord(treeHeight + LeafLodCount, ref Vector3I.Zero); stack[stackIdx++] = data; MyCellCoord cell = new MyCellCoord(); while (stackIdx > 0) { Debug.Assert(stackIdx <= stackSize); data = stack[--stackIdx]; cell.Lod = data.Lod - LeafLodCount; cell.CoordInLod = data.CoordInLod; int lodDiff; IMyOctreeLeafNode leaf; if (leaves.TryGetValue(cell.PackId64(), out leaf)) { lodDiff = data.Lod - lodIndex; var rangeMinInDataLod = minInLod >> lodDiff; var rangeMaxInDataLod = maxInLod >> lodDiff; if (data.CoordInLod.IsInsideInclusive(ref rangeMinInDataLod, ref rangeMaxInDataLod)) { var nodePosInLod = data.CoordInLod << lodDiff; var writeOffset = nodePosInLod - minInLod; Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset); writeOffset += targetWriteOffset; var lodSizeMinusOne = new Vector3I((1 << lodDiff) - 1); var minInLeaf = Vector3I.Clamp(minInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne); var maxInLeaf = Vector3I.Clamp(maxInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne); leaf.ReadRange(target, ref writeOffset, lodIndex, ref minInLeaf, ref maxInLeaf); } continue; } cell.Lod -= 1; lodDiff = data.Lod - 1 - lodIndex; var node = nodes[cell.PackId64()]; var min = minInLod >> lodDiff; var max = maxInLod >> lodDiff; var nodePositionInChild = data.CoordInLod << 1; min -= nodePositionInChild; max -= nodePositionInChild; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { Vector3I childPosRelative; ComputeChildCoord(i, out childPosRelative); if (!childPosRelative.IsInsideInclusive(ref min, ref max)) continue; if (lodIndex < data.Lod && node.HasChild(i)) { Debug.Assert(stackIdx < stackSize); stack[stackIdx++] = new MyCellCoord(data.Lod - 1, nodePositionInChild + childPosRelative); } else { var childMin = nodePositionInChild + childPosRelative; childMin <<= lodDiff; var writeOffset = childMin - minInLod; Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset); writeOffset += targetWriteOffset; var nodeData = node.GetData(i); if (lodDiff == 0) { target.Set(type, ref writeOffset, nodeData); } else { var childMax = childMin + ((1 << lodDiff) - 1); Vector3I.Max(ref childMin, ref minInLod, out childMin); Vector3I.Min(ref childMax, ref maxInLod, out childMax); for (int z = childMin.Z; z <= childMax.Z; ++z) for (int y = childMin.Y; y <= childMax.Y; ++y) for (int x = childMin.X; x <= childMax.X; ++x) { Vector3I write = writeOffset; write.X += x - childMin.X; write.Y += y - childMin.Y; write.Z += z - childMin.Z; target.Set(type, ref write, nodeData); } } } } } }
// Weather this flags request a given type of data public static bool Requests(this MyStorageDataTypeFlags self, MyStorageDataTypeEnum value) { return(((int)self & (1 << (int)value)) != 0); }
// get the same flags except the provided type. public static MyStorageDataTypeFlags Without(this MyStorageDataTypeFlags self, MyStorageDataTypeEnum value) { return self & ~(MyStorageDataTypeFlags) (1 << (int) value); }
private void FillOutOfBounds(MyStorageData target, MyStorageDataTypeEnum type, ref Vector3I woffset, int lodIndex, Vector3I minInLod, Vector3I maxInLod) { var value = MyVoxelConstants.DefaultValue(type); var size = new Vector3I((1 << (m_treeHeight + LeafLodCount - lodIndex)) - 1); var offset = woffset - minInLod; var req = new BoundingBoxI(minInLod, maxInLod); var tree = new BoundingBoxI(Vector3I.Zero, size); if (req.Intersects(ref tree) != true) { target.BlockFill(type, offset + minInLod, offset + maxInLod, value); return; } // Left if (minInLod.X < 0) { var min = minInLod; var max = maxInLod; max.X = -1; minInLod.X = 0; target.BlockFill(type, min + offset, max + offset, value); } // Right if (maxInLod.X > size.X) { var min = minInLod; var max = maxInLod; min.X = size.X+1; minInLod.X = size.X; target.BlockFill(type, min + offset, max + offset, value); } // Top if (minInLod.Y < 0) { var min = minInLod; var max = maxInLod; max.Y = -1; minInLod.Y = 0; target.BlockFill(type, min + offset, max + offset, value); } // Bottom if (maxInLod.Y > size.Y) { var min = minInLod; var max = maxInLod; min.Y = size.Y + 1; minInLod.Y = size.Y; target.BlockFill(type, min + offset, max + offset, value); } // Back if (minInLod.Y < 0) { var min = minInLod; var max = maxInLod; max.Y = -1; minInLod.Y = 0; target.BlockFill(type, min + offset, max + offset, value); } // Front if (maxInLod.Y > size.Y) { var min = minInLod; var max = maxInLod; min.Y = size.Y + 1; minInLod.Y = size.Y; target.BlockFill(type, min + offset, max + offset, value); } }