コード例 #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;
        }
コード例 #2
0
        public bool IntersectLineFace(ref LineD ll, int face, out double startOffset, out double endOffset)
        {
            Vector2 start, end;
            Vector3 from, to;

            from = ll.From;
            to   = ll.To;

            MyCubemapHelpers.CalculateTexcoordForFace(ref from, face, out start);
            MyCubemapHelpers.CalculateTexcoordForFace(ref to, face, out end);

            int steps = (int)Math.Ceiling((end - start).Length() * m_heightmap.Resolution);

            double stepsR = 1d / steps;

            for (int i = 0; i < steps; i++)
            {
                from = ll.From + ll.Direction * ll.Length * i * stepsR;
                to   = ll.From + ll.Direction * ll.Length * (i + 1) * stepsR;

                var flen  = from.Length();
                var tolen = to.Length();

                MyCubemapHelpers.CalculateTexcoordForFace(ref from, face, out start);
                MyCubemapHelpers.CalculateTexcoordForFace(ref to, face, out end);

                from.X = start.X;
                from.Y = start.Y;
                from.Z = (flen - m_radius - m_minHillHeight) * m_heightRatioRecip;

                to.X = end.X;
                to.Y = end.Y;
                to.Z = (tolen - m_radius - m_minHillHeight) * m_heightRatioRecip;

                float newStart, newEnd;
                if (m_heightmap[face].QueryLine(ref from, ref to, out newStart, out newEnd))
                {
                    startOffset = Math.Max((i + newStart) * stepsR, 0);
                    endOffset   = 1.0;
                    return(true);
                }
            }

            startOffset = 0;
            endOffset   = 1;
            return(false);
        }
コード例 #3
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;
        }
コード例 #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;
        }
コード例 #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));
        }