private unsafe void WriteRange <TOperator>(MyCellCoord cell, byte defaultData, ref TOperator source, MyStorageDataTypeEnum type, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max) where TOperator : struct, IVoxelOperator { MyOctreeNode node; uint key = cell.PackId32(); if (!this.m_nodes.TryGetValue(key, out node)) { for (int i = 0; i < 8; i++) { &node.Data.FixedElementField[i] = defaultData; } } if (cell.Lod == 0) { Vector3I vectori = cell.CoordInLod << 1; for (int i = 0; i < 8; i++) { Vector3I vectori2; this.ComputeChildCoord(i, out vectori2); Vector3I position = (Vector3I)(vectori + vectori2); if (position.IsInsideInclusiveEnd(ref min, ref max)) { position = (Vector3I)((position - min) + readOffset); source.Op(ref position, type, ref (byte)ref (&node.Data.FixedElementField + i)); } } this.m_nodes[key] = node; } else { Vector3I vectori4 = cell.CoordInLod << 1; Vector3I vectori6 = (min >> cell.Lod) - vectori4; Vector3I vectori7 = (max >> cell.Lod) - vectori4; for (int i = 0; i < 8; i++) { Vector3I vectori5; this.ComputeChildCoord(i, out vectori5); if (vectori5.IsInsideInclusiveEnd(ref vectori6, ref vectori7)) { MyCellCoord coord = new MyCellCoord(cell.Lod - 1, (Vector3I)(vectori4 + vectori5)); this.WriteRange <TOperator>(coord, &node.Data.FixedElementField[i], ref source, type, ref readOffset, ref min, ref max); uint num5 = coord.PackId32(); MyOctreeNode node2 = this.m_nodes[num5]; if (node2.HasChildren || !MyOctreeNode.AllDataSame(&node2.Data.FixedElementField)) { node.SetChild(i, true); &node.Data.FixedElementField[i] = this.m_nodeFilter(&node2.Data.FixedElementField, cell.Lod); } else { node.SetChild(i, false); &node.Data.FixedElementField[i] = node2.Data.FixedElementField; this.m_nodes.Remove(num5); } } } this.m_nodes[key] = node; } }
private unsafe void BuildNode <TDataEnum>(ref StackData <TDataEnum> stack, out MyOctreeNode builtNode) where TDataEnum : struct, IEnumerator <byte> { MyOctreeNode defaultNode = stack.DefaultNode; if (stack.Cell.Lod == 0) { for (int i = 0; i < 8; i++) { stack.Data.MoveNext(); &defaultNode.Data.FixedElementField[i] = stack.Data.Current; } } else { int *numPtr1 = (int *)ref stack.Cell.Lod; numPtr1[0]--; Vector3I coordInLod = stack.Cell.CoordInLod; Vector3I vectori2 = coordInLod << 1; int childIdx = 0; while (true) { Vector3I vectori3; MyOctreeNode node2; if (childIdx >= 8) { int *numPtr2 = (int *)ref stack.Cell.Lod; numPtr2[0]++; stack.Cell.CoordInLod = coordInLod; break; } this.ComputeChildCoord(childIdx, out vectori3); stack.Cell.CoordInLod = (Vector3I)(vectori2 + vectori3); this.BuildNode <TDataEnum>(ref stack, out node2); if (!node2.HasChildren && MyOctreeNode.AllDataSame(&node2.Data.FixedElementField)) { defaultNode.SetChild(childIdx, false); &defaultNode.Data.FixedElementField[childIdx] = node2.Data.FixedElementField; } else { defaultNode.SetChild(childIdx, true); &defaultNode.Data.FixedElementField[childIdx] = this.m_nodeFilter(&node2.Data.FixedElementField, stack.Cell.Lod); this.m_nodes.Add(stack.Cell.PackId32(), node2); } childIdx++; } } builtNode = defaultNode; }
private unsafe void BuildNode <TDataEnum>(ref StackData <TDataEnum> stack, out MyOctreeNode builtNode) where TDataEnum : struct, IEnumerator <TLeafData> { var currentNode = stack.DefaultNode; if (stack.Cell.Lod == 0) { // bottom level containing leaf data for (int i = 0; i < 8; ++i) { bool movedNext = stack.Data.MoveNext(); Debug.Assert(movedNext); currentNode.Data[i] = stack.Data.Current; } } else { --stack.Cell.Lod; Vector3I currentPosition = stack.Cell.CoordInLod; Vector3I childBase = currentPosition << 1; Vector3I childOffset; MyOctreeNode childNode; for (int i = 0; i < 8; ++i) { ComputeChildCoord(i, out childOffset); stack.Cell.CoordInLod = childBase + childOffset; BuildNode(ref stack, out childNode); if (!childNode.HasChildren && MyOctreeNode.AllDataSame(childNode.Data)) { currentNode.SetChild(i, false); currentNode.Data[i] = childNode.Data[0]; } else { currentNode.SetChild(i, true); currentNode.Data[i] = m_nodeFilter(childNode.Data, stack.Cell.Lod); m_nodes.Add(stack.Cell.PackId32(), childNode); } } ++stack.Cell.Lod; stack.Cell.CoordInLod = currentPosition; } builtNode = currentNode; }
private unsafe void WriteRange( MyCellCoord cell, TLeafData defaultData, MyStorageData source, MyStorageDataTypeEnum type, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max) { var nodeKey = cell.PackId32(); MyOctreeNode node; if (!m_nodes.TryGetValue(nodeKey, out node)) { for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { node.Data[i] = defaultData; } } if (cell.Lod == 0) { var childBase = cell.CoordInLod << 1; Vector3I childOffset; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { ComputeChildCoord(i, out childOffset); var child = childBase + childOffset; if (!child.IsInsideInclusive(ref min, ref max)) { continue; } child -= min; child += readOffset; node.Data[i] = source.Get(type, ref child); } m_nodes[nodeKey] = node; } else { var childBase = cell.CoordInLod << 1; Vector3I childOffset; var minInChild = (min >> cell.Lod) - childBase; var maxInChild = (max >> cell.Lod) - childBase; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { ComputeChildCoord(i, out childOffset); if (!childOffset.IsInsideInclusive(ref minInChild, ref maxInChild)) { continue; } var childCell = new MyCellCoord(cell.Lod - 1, childBase + childOffset); WriteRange(childCell, node.Data[i], source, type, ref readOffset, ref min, ref max); var childKey = childCell.PackId32(); var childNode = m_nodes[childKey]; if (!childNode.HasChildren && MyOctreeNode.AllDataSame(childNode.Data)) { node.SetChild(i, false); node.Data[i] = childNode.Data[0]; m_nodes.Remove(childKey); } else { node.SetChild(i, true); node.Data[i] = m_nodeFilter(childNode.Data, cell.Lod); } } m_nodes[nodeKey] = node; } }