Пример #1
0
        public void CreatePruningTree(string mapName)
        {
            int num  = 0;
            int num2 = this.Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE;

            while (num2 != 1)
            {
                if ((num2 % HeightmapNode.HEIGHTMAP_BRANCH_FACTOR) != 0)
                {
                    object[] args = new object[] { mapName };
                    MyLog.Default.Error("Cannot build prunning tree for heightmap face {0}!", args);
                    object[] objArray2 = new object[] { HeightmapNode.HEIGHTMAP_BRANCH_FACTOR, HeightmapNode.HEIGHTMAP_LEAF_SIZE };
                    MyLog.Default.Error("Heightmap resolution must be divisible by {1}, and after that a power of {0}. Failing to achieve so will disable several important optimizations!!", objArray2);
                    return;
                }
                num++;
                num2 /= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
            }
            this.PruningTree = new HeightmapLevel[num];
            int rowStart = this.GetRowStart(0);

            if (num == 0)
            {
                float positiveInfinity = float.PositiveInfinity;
                float negativeInfinity = float.NegativeInfinity;
                int   num10            = rowStart;
                int   num11            = 0;
                while (num11 < HeightmapNode.HEIGHTMAP_LEAF_SIZE)
                {
                    int num12 = 0;
                    while (true)
                    {
                        if (num12 >= HeightmapNode.HEIGHTMAP_LEAF_SIZE)
                        {
                            num10 += this.m_realResolution;
                            num11++;
                            break;
                        }
                        float num13 = this.Data[num10 + num12] * 1.525902E-05f;
                        if (positiveInfinity > num13)
                        {
                            positiveInfinity = num13;
                        }
                        if (negativeInfinity < num13)
                        {
                            negativeInfinity = num13;
                        }
                        num12++;
                    }
                }
                this.Root.Max = negativeInfinity;
                this.Root.Min = positiveInfinity;
            }
            else
            {
                int num1 = HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
                num2 = this.Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE;
                this.PruningTree[0].Nodes = new HeightmapNode[num2 * num2];
                this.PruningTree[0].Res   = (uint)num2;
                int index = 0;
                int num14 = 0;
                while (num14 < num2)
                {
                    int num15 = rowStart;
                    int num16 = 0;
                    while (true)
                    {
                        if (num16 >= num2)
                        {
                            rowStart += HeightmapNode.HEIGHTMAP_LEAF_SIZE * this.m_realResolution;
                            num14++;
                            break;
                        }
                        float num17 = float.PositiveInfinity;
                        float num18 = float.NegativeInfinity;
                        int   num19 = num15 - this.m_realResolution;
                        int   num20 = -1;
                        while (true)
                        {
                            if (num20 > HeightmapNode.HEIGHTMAP_LEAF_SIZE)
                            {
                                HeightmapNode node = new HeightmapNode {
                                    Max = num18,
                                    Min = num17
                                };
                                this.PruningTree[0].Nodes[index] = node;
                                index++;
                                num15 += HeightmapNode.HEIGHTMAP_LEAF_SIZE;
                                num16++;
                                break;
                            }
                            int num21 = -1;
                            while (true)
                            {
                                if (num21 > HeightmapNode.HEIGHTMAP_LEAF_SIZE)
                                {
                                    num19 += this.m_realResolution;
                                    num20++;
                                    break;
                                }
                                float num22 = this.Data[num19 + num21] * 1.525902E-05f;
                                if (num17 > num22)
                                {
                                    num17 = num22;
                                }
                                if (num18 < num22)
                                {
                                    num18 = num22;
                                }
                                num21++;
                            }
                        }
                    }
                }
                int num5  = 0;
                int num23 = 1;
                while (num23 < num)
                {
                    rowStart = 0;
                    int num24 = num2 / HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
                    this.PruningTree[num23].Nodes = new HeightmapNode[num24 * num24];
                    this.PruningTree[num23].Res   = (uint)num24;
                    index = 0;
                    int num25 = 0;
                    while (true)
                    {
                        if (num25 >= num24)
                        {
                            num5++;
                            num2 = num24;
                            num23++;
                            break;
                        }
                        int num26 = rowStart;
                        int num27 = 0;
                        while (true)
                        {
                            if (num27 >= num24)
                            {
                                rowStart += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR * num2;
                                num25++;
                                break;
                            }
                            float min   = float.PositiveInfinity;
                            float max   = float.NegativeInfinity;
                            int   num30 = num26;
                            int   num31 = 0;
                            while (true)
                            {
                                if (num31 >= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR)
                                {
                                    this.PruningTree[num23].Nodes[index] = new HeightmapNode {
                                        Max = max,
                                        Min = min
                                    };
                                    index++;
                                    num26 += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
                                    num27++;
                                    break;
                                }
                                int num32 = 0;
                                while (true)
                                {
                                    if (num32 >= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR)
                                    {
                                        num30 += num2;
                                        num31++;
                                        break;
                                    }
                                    HeightmapNode node2 = this.PruningTree[num5].Nodes[num30 + num32];
                                    if (min > node2.Min)
                                    {
                                        min = node2.Min;
                                    }
                                    if (max < node2.Max)
                                    {
                                        max = node2.Max;
                                    }
                                    num32++;
                                }
                            }
                        }
                    }
                }
                float positiveInfinity = float.PositiveInfinity;
                float negativeInfinity = float.NegativeInfinity;
                rowStart = 0;
                int num33 = 0;
                while (num33 < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR)
                {
                    int num34 = 0;
                    while (true)
                    {
                        if (num34 >= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR)
                        {
                            num33++;
                            break;
                        }
                        rowStart++;
                        HeightmapNode node3 = this.PruningTree[num - 1].Nodes[rowStart];
                        if (positiveInfinity > node3.Min)
                        {
                            positiveInfinity = node3.Min;
                        }
                        if (negativeInfinity < node3.Max)
                        {
                            negativeInfinity = node3.Max;
                        }
                        num34++;
                    }
                }
                this.Root.Max = negativeInfinity;
                this.Root.Min = positiveInfinity;
            }
        }
Пример #2
0
        public void CreatePruningTree(string mapName)
        {
            int depth = 0;

            int res = Resolution;

            res /= HeightmapNode.HEIGHTMAP_LEAF_SIZE;

            // check if we get an even tree, for now we will rely on that.
            while (res != 1)
            {
                if (res % HeightmapNode.HEIGHTMAP_BRANCH_FACTOR != 0)
                {
                    MyDebug.FailRelease("Cannot build prunning tree for heightmap face {0}!", mapName);
                    MyDebug.FailRelease("Heightmap resolution must be divisible by {1}, and after that a power of {0}. Failing to achieve so will disable several important optimizations!!", HeightmapNode.HEIGHTMAP_BRANCH_FACTOR, HeightmapNode.HEIGHTMAP_LEAF_SIZE);
                    return;
                }
                depth++;
                res /= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
            }

            PruningTree = new HeightmapLevel[depth];

            int offset = GetRowStart(0);

            if (depth == 0)
            {
                float min = float.PositiveInfinity;
                float max = float.NegativeInfinity;

                int localOffset = offset;
                for (int y = 0; y < HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++y)
                {
                    for (int x = 0; x < HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++x)
                    {
                        float value = ((float)Data[localOffset + x] * MyCubemapHelpers.USHORT_RECIP);
                        if (min > value)
                        {
                            min = value;
                        }
                        if (max < value)
                        {
                            max = value;
                        }
                    }
                    localOffset += m_real_resolution;
                }

                Root.Max = max;
                Root.Min = min;
                return;
            }

            int nodes = HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;

            res = Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE;

            // prepare leaf level
            PruningTree[0].Nodes = new HeightmapNode[res * res];
            PruningTree[0].Res   = (uint)res;

            int cell = 0;

            for (int j = 0; j < res; ++j)
            {
                int coffset = offset;
                for (int i = 0; i < res; ++i)
                {
                    float min = float.PositiveInfinity;
                    float max = float.NegativeInfinity;

                    int localOffset = coffset - m_real_resolution;
                    for (int y = -1; y <= HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++y)
                    {
                        for (int x = -1; x <= HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++x)
                        {
                            float value = ((float)Data[localOffset + x] * MyCubemapHelpers.USHORT_RECIP);
                            if (min > value)
                            {
                                min = value;
                            }
                            if (max < value)
                            {
                                max = value;
                            }
                        }
                        localOffset += m_real_resolution;
                    }

                    PruningTree[0].Nodes[cell] = new HeightmapNode()
                    {
                        Max = max,
                        Min = min
                    };

                    cell++;
                    coffset += HeightmapNode.HEIGHTMAP_LEAF_SIZE;
                }
                offset += HeightmapNode.HEIGHTMAP_LEAF_SIZE * m_real_resolution;
            }

            int l = 0;

            for (int k = 1; k < depth; k++)
            {
                offset = 0;
                int levelRes = res / HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;

                PruningTree[k].Nodes = new HeightmapNode[levelRes * levelRes];
                PruningTree[k].Res   = (uint)levelRes;

                cell = 0;
                for (int j = 0; j < levelRes; ++j)
                {
                    int coffset = offset;
                    for (int i = 0; i < levelRes; ++i)
                    {
                        float min = float.PositiveInfinity;
                        float max = float.NegativeInfinity;

                        int localOffset = coffset;
                        for (int y = 0; y < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++y)
                        {
                            for (int x = 0; x < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++x)
                            {
                                HeightmapNode n = PruningTree[l].Nodes[localOffset + x];
                                if (min > n.Min)
                                {
                                    min = n.Min;
                                }
                                if (max < n.Max)
                                {
                                    max = n.Max;
                                }
                            }
                            localOffset += res;
                        }

                        PruningTree[k].Nodes[cell] = new HeightmapNode()
                        {
                            Max = max,
                            Min = min
                        };

                        cell++;
                        coffset += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
                    }
                    offset += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR * res;
                }

                // previous level
                l++;
                res = levelRes;
            }

            float tmin = float.PositiveInfinity;
            float tmax = float.NegativeInfinity;

            offset = 0;
            for (int y = 0; y < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++y)
            {
                for (int x = 0; x < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++x)
                {
                    HeightmapNode n = PruningTree[depth - 1].Nodes[offset++];
                    if (tmin > n.Min)
                    {
                        tmin = n.Min;
                    }
                    if (tmax < n.Max)
                    {
                        tmax = n.Max;
                    }
                }
            }

            Root.Max = tmax;
            Root.Min = tmin;
        }
Пример #3
0
        public unsafe void GetBounds(ref BoundingBox query)
        {
            float num = Math.Max(query.Width, query.Height);

            if (((num >= this.m_pixelSizeFour) && (this.PruningTree != null)) && (this.PruningTree.Length != 0))
            {
                double num2  = Math.Log((double)(((float)this.Resolution) / (num * HeightmapNode.HEIGHTMAP_LEAF_SIZE))) / Math.Log((double)HeightmapNode.HEIGHTMAP_BRANCH_FACTOR);
                uint   index = ((uint)(this.PruningTree.Length - 1)) - ((uint)MathHelper.Clamp(num2, 0.0, (double)(this.PruningTree.Length - 1)));
                Box2I  other = new Box2I(Vector2I.Zero, new Vector2I(((int)this.PruningTree[index].Res) - 1));
                Box2I  boxi2 = new Box2I(ref query, this.PruningTree[index].Res);
                boxi2.Intersect(ref other);
                query.Min.Z = float.PositiveInfinity;
                query.Max.Z = float.NegativeInfinity;
                int res = (int)this.PruningTree[index].Res;
                int y   = boxi2.Min.Y;
                while (y <= boxi2.Max.Y)
                {
                    int x = boxi2.Min.X;
                    while (true)
                    {
                        if (x > boxi2.Max.X)
                        {
                            y++;
                            break;
                        }
                        HeightmapNode node = this.PruningTree[index].Nodes[(y * res) + x];
                        if (query.Min.Z > node.Min)
                        {
                            query.Min.Z = node.Min;
                        }
                        if (query.Max.Z < node.Max)
                        {
                            query.Max.Z = node.Max;
                        }
                        x++;
                    }
                }
            }
            else
            {
                ushort    num5;
                Box2I     boxi3       = new Box2I(ref query, (uint)this.Resolution);
                Vector2I *vectoriPtr1 = (Vector2I *)ref boxi3.Min;
                vectoriPtr1[0] -= 1;
                Vector2I *vectoriPtr2 = (Vector2I *)ref boxi3.Max;
                vectoriPtr2[0] += 1;
                boxi3.Intersect(ref this.m_bounds);
                this.GetValue(boxi3.Min.X, boxi3.Min.Y, out num5);
                int num6 = 0xffff;
                int num7 = 0;
                int y    = boxi3.Min.Y;
                while (y <= boxi3.Max.Y)
                {
                    int x = boxi3.Min.X;
                    while (true)
                    {
                        if (x > boxi3.Max.X)
                        {
                            y++;
                            break;
                        }
                        this.GetValue(x, y, out num5);
                        if (num5 > num7)
                        {
                            num7 = num5;
                        }
                        if (num5 < num6)
                        {
                            num6 = num5;
                        }
                        x++;
                    }
                }
                int num8 = ((num7 - num6) * 2) / 3;
                num7       += num8;
                num6       -= num8;
                query.Min.Z = num6 * 1.525902E-05f;
                query.Max.Z = num7 * 1.525902E-05f;
            }
        }