Ejemplo n.º 1
0
        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;
            }
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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;
            }
        }