Exemplo n.º 1
0
        /**
         * Takes the x and y bounds of the box and queries the heightmap for the minimum and maximum height in the box.
         *
         * The values are returned in the query box itself as the Z bounds.
         *
         * This only works if all vertices of the box are in the same face.
         */
        public unsafe void GetBounds(ref BoundingBox box)
        {
            int      firstFace = -1;
            Vector3 *corners   = stackalloc Vector3[8];

            box.GetCornersUnsafe(corners);

            for (int i = 0; i < 8; ++i)
            {
                int face;
                MyCubemapHelpers.GetCubeFace(ref corners[i], out face);

                if (firstFace == -1)
                {
                    firstFace = face;
                }
            }

            BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0));

            for (int i = 0; i < 8; ++i)
            {
                Vector2 tex;
                MyCubemapHelpers.CalculateTexcoordForFace(ref corners[i], firstFace, out tex);

                if (tex.X < query.Min.X)
                {
                    query.Min.X = tex.X;
                }
                if (tex.X > query.Max.X)
                {
                    query.Max.X = tex.X;
                }
                if (tex.Y < query.Min.Y)
                {
                    query.Min.Y = tex.Y;
                }
                if (tex.Y > query.Max.Y)
                {
                    query.Max.Y = tex.Y;
                }
            }

            m_heightmap.Faces[firstFace].GetBounds(ref query);

            box.Min.Z = query.Min.Z * m_heightRatio + InnerRadius;
            box.Max.Z = query.Max.Z * m_heightRatio + InnerRadius;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Get the minimum and maximum ranges of terrain height in the area determined by the provided points.
        /// </summary>
        /// <param name="localPoints">List of points to query</param>
        /// <param name="pointCount">Number of points</param>
        /// <param name="minHeight">The calculated minimum possible height of terrain</param>
        /// <param name="maxHeight">The calculated maximum possible height of terrain</param>
        public unsafe void GetBounds(Vector3 *localPoints, int pointCount, out float minHeight, out float maxHeight)
        {
            int firstFace = -1;

            for (int i = 0; i < pointCount; ++i)
            {
                int face;
                MyCubemapHelpers.GetCubeFace(ref localPoints[i], out face);

                if (firstFace == -1)
                {
                    firstFace = face;
                }
            }

            BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0));

            for (int i = 0; i < pointCount; ++i)
            {
                Vector2 tex;
                MyCubemapHelpers.CalculateTexcoordForFace(ref localPoints[i], firstFace, out tex);

                if (tex.X < query.Min.X)
                {
                    query.Min.X = tex.X;
                }
                if (tex.X > query.Max.X)
                {
                    query.Max.X = tex.X;
                }
                if (tex.Y < query.Min.Y)
                {
                    query.Min.Y = tex.Y;
                }
                if (tex.Y > query.Max.Y)
                {
                    query.Max.Y = tex.Y;
                }
            }

            m_heightmap.Faces[firstFace].GetBounds(ref query);

            minHeight = query.Min.Z * m_heightRatio + InnerRadius;
            maxHeight = query.Max.Z * m_heightRatio + InnerRadius;
        }
Exemplo n.º 3
0
        public unsafe bool IntersectLine(ref LineD ll, out double startOffset, out double endOffset)
        {
            var box = new BoundingBox(ll.From, ll.From);

            box.Include(ll.To);

            int  firstFace   = -1;
            uint faces       = 0;
            bool complicated = false;

            Vector3 *corners = stackalloc Vector3[8];

            box.GetCornersUnsafe(corners);

            for (int i = 0; i < 8; ++i)
            {
                int face;
                MyCubemapHelpers.GetCubeFace(ref corners[i], out face);

                if (firstFace == -1)
                {
                    firstFace = face;
                }
                else if (firstFace != face)
                {
                    complicated = true;
                }

                faces |= (uint)(1 << face);
            }

            if (complicated)
            {
                return(IntersectLineCornerCase(ref ll, faces, out startOffset, out endOffset));
            }

            // Later on we will have split the line per sextant already.

            // From here on I calculate how many times to split the line to account for the surface curvature.
            //

            return(IntersectLineFace(ref ll, firstFace, out startOffset, out endOffset));
        }
Exemplo n.º 4
0
        public unsafe void GetBounds(Vector3D *localPoints, int pointCount, out float minHeight, out float maxHeight)
        {
            int face = -1;

            for (int i = 0; i < pointCount; i++)
            {
                int     num3;
                Vector3 position = *((Vector3 *)(localPoints + i));
                MyCubemapHelpers.GetCubeFace(ref position, out num3);
                if (face == -1)
                {
                    face = num3;
                }
            }
            BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0f), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0f));

            for (int j = 0; j < pointCount; j++)
            {
                Vector2 vector2;
                Vector3 localPos = *((Vector3 *)(localPoints + j));
                MyCubemapHelpers.CalculateTexcoordForFace(ref localPos, face, out vector2);
                if (vector2.X < query.Min.X)
                {
                    query.Min.X = vector2.X;
                }
                if (vector2.X > query.Max.X)
                {
                    query.Max.X = vector2.X;
                }
                if (vector2.Y < query.Min.Y)
                {
                    query.Min.Y = vector2.Y;
                }
                if (vector2.Y > query.Max.Y)
                {
                    query.Max.Y = vector2.Y;
                }
            }
            this.m_heightmap.Faces[face].GetBounds(ref query);
            minHeight = (query.Min.Z * this.m_heightRatio) + this.InnerRadius;
            maxHeight = (query.Max.Z * this.m_heightRatio) + this.InnerRadius;
        }
Exemplo n.º 5
0
        protected unsafe ContainmentType IntersectBoundingBoxInternal(ref BoundingBox box, float lodLevel)
        {
            int  firstFace   = -1;
            uint faces       = 0;
            bool complicated = false;

            float minHeight;
            float maxHeight;

            Vector3 *corners = stackalloc Vector3[8];

            box.GetCornersUnsafe(corners);

            for (int i = 0; i < 8; ++i)
            {
                int face;
                MyCubemapHelpers.GetCubeFace(ref corners[i], out face);

                if (firstFace == -1)
                {
                    firstFace = face;
                }
                else if (firstFace != face)
                {
                    complicated = true;
                }

                faces |= (uint)(1 << face);
            }

            if (Vector3.Zero.IsInsideInclusive(ref box.Min, ref box.Max))
            {
                minHeight = 0;
            }
            else
            {
                var clamp = Vector3.Clamp(Vector3.Zero, box.Min, box.Max);
                minHeight = clamp.Length();
            }

            { // Calculate furthest point in BB
                Vector3 end;
                Vector3 c = box.Center;

                if (c.X < 0)
                {
                    end.X = box.Min.X;
                }
                else
                {
                    end.X = box.Max.X;
                }

                if (c.Y < 0)
                {
                    end.Y = box.Min.Y;
                }
                else
                {
                    end.Y = box.Max.Y;
                }

                if (c.Z < 0)
                {
                    end.Z = box.Min.Z;
                }
                else
                {
                    end.Z = box.Max.Z;
                }

                maxHeight = end.Length();
            }

            if (complicated)
            {
                return(IntersectBoundingBoxCornerCase(ref box, faces, corners, minHeight, maxHeight));
            }

            BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, minHeight), new Vector3(float.NegativeInfinity, float.NegativeInfinity, maxHeight));

            for (int i = 0; i < 8; ++i)
            {
                Vector2 tex;
                MyCubemapHelpers.CalculateTexcoordForFace(ref corners[i], firstFace, out tex);

                if (tex.X < query.Min.X)
                {
                    query.Min.X = tex.X;
                }
                if (tex.X > query.Max.X)
                {
                    query.Max.X = tex.X;
                }
                if (tex.Y < query.Min.Y)
                {
                    query.Min.Y = tex.Y;
                }
                if (tex.Y > query.Max.Y)
                {
                    query.Max.Y = tex.Y;
                }
            }

            query.Min.Z = ((query.Min.Z - m_radius - m_detailScale) - m_minHillHeight) * m_heightRatioRecip;
            query.Max.Z = ((query.Max.Z - m_radius) - m_minHillHeight) * m_heightRatioRecip;

            return(m_heightmap.Faces[firstFace].QueryHeight(ref query));
        }