Exemplo n.º 1
0
        public static GTABoundingBox2 ComputeBoundingBox(Entity e, Vector3 offset, float scale = 0.5f)
        {
            var m  = e.Model;
            var rv = new GTABoundingBox2
            {
                Min = new GTAVector2(float.PositiveInfinity, float.PositiveInfinity),
                Max = new GTAVector2(float.NegativeInfinity, float.NegativeInfinity)
            };
            Vector3 gmin;
            Vector3 gmax;

            m.GetDimensions(out gmin, out gmax);
            var bbox = new SharpDX.BoundingBox((SharpDX.Vector3) new GTAVector(gmin), (SharpDX.Vector3) new GTAVector(gmax));
            //Console.WriteLine(bbox.GetCorners()[0]);

            /*
             * for (int i = 0; i < bbox.GetCorners().Length; ++i) {
             *  for (int j = 0; j < bbox.GetCorners().Length; ++j) {
             *      if (j == i) continue;
             *      var c1 = bbox.GetCorners()[i];
             *      var c2 = bbox.GetCorners()[j];
             *      HashFunctions.Draw3DLine(e.GetOffsetInWorldCoords(new Vector3(c1.X, c1.Y, c1.Z)), e.GetOffsetInWorldCoords(new Vector3(c2.X, c2.Y, c2.Z)), 0,0);
             *  }
             * }
             */
            /*
             * for (int i = 0; i < bbox.GetCorners().Length; ++i)
             * {
             *  var corner = bbox.GetCorners()[i];
             *  var cornerinworld = e.GetOffsetInWorldCoords(new Vector3(corner.X, corner.Y, corner.Z));
             *
             *
             * }*/
            //UI.Notify(e.HeightAboveGround.ToString());
            var sp = HashFunctions.Convert3dTo2d(e.GetOffsetInWorldCoords(e.Position));

            foreach (var corner in bbox.GetCorners())
            {
                var c = new Vector3(corner.X, corner.Y, corner.Z);

                c = e.GetOffsetInWorldCoords(c);
                var s = HashFunctions.Convert3dTo2d(c);
                if (s.X == -1f || s.Y == -1f)
                {
                    rv.Min.X = float.PositiveInfinity;
                    rv.Max.X = float.NegativeInfinity;
                    rv.Min.Y = float.PositiveInfinity;
                    rv.Max.Y = float.NegativeInfinity;
                    return(rv);
                }

                /*
                 * if(s.X == -1) {
                 *  if (sp.X < 0.5) s.X = 0f;
                 *  if (sp.X >= 0.5) s.X = 1f;
                 * }
                 * if(s.Y == -1) {
                 *  if (sp.Y < 0.5) s.Y = 0f;
                 *  if (sp.Y >= 0.5) s.Y = 1f;
                 * }
                 */
                rv.Min.X = Math.Min(rv.Min.X, s.X);
                rv.Min.Y = Math.Min(rv.Min.Y, s.Y);
                rv.Max.X = Math.Max(rv.Max.X, s.X);
                rv.Max.Y = Math.Max(rv.Max.Y, s.Y);
            }

//            int width = 1280;
//            int height = 960;
//            int x = (int)(rv.Min.X * width);
//            int y = (int)(rv.Min.Y * height);
//            int x2 = (int)(rv.Max.X * width);
//            int y2 = (int)(rv.Max.Y * height);
//            float w = rv.Max.X - rv.Min.X;
//            float h = rv.Max.Y - rv.Min.Y;
//            HashFunctions.DrawRect(rv.Min.X + w/2, rv.Min.Y + h/2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y, 255, 255, 255, 100);
//            new UIRectangle(new Point((int)(rv.Min.X * 1920), (int)(rv.Min.Y * 1080)), rv.)
            return(rv);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Check the intersection between an <see cref="OrientedBoundingBox"/> and <see cref="BoundingBox"/>
        /// </summary>
        /// <param name="box">The BoundingBox to test.</param>
        /// <returns>The type of containment the two objects have.</returns>
        /// <remarks>
        /// For accuracy, The transformation matrix for the <see cref="OrientedBoundingBox"/> must not have any scaling applied to it.
        /// Anyway, scaling using Scale method will keep this method accurate.
        /// </remarks>
        public ContainmentType Contains(ref BoundingBox box)
        {
            var cornersCheck = Contains(box.GetCorners());

            if (cornersCheck != ContainmentType.Disjoint)
            {
                return(cornersCheck);
            }

            var boxCenter  = box.Minimum + (box.Maximum - box.Minimum) / 2f;
            var boxExtents = box.Maximum - boxCenter;

            var SizeA = Extents;
            var SizeB = boxExtents;
            var RotA  = GetRows(ref Transformation);

            float ExtentA, ExtentB, Separation;
            int   i, k;

            Matrix R;                   // Rotation from B to A

            Matrix.Invert(ref Transformation, out R);
            var AR = new Matrix();      // absolute values of R matrix, to use with box extents

            for (i = 0; i < 3; i++)
            {
                for (k = 0; k < 3; k++)
                {
                    AR[i, k] = Math.Abs(R[i, k]);
                }
            }


            // Vector separating the centers of Box B and of Box A
            var vSepWS = boxCenter - Center;
            // Rotated into Box A's coordinates
            var vSepA = new Vector3(Vector3.Dot(vSepWS, RotA[0]), Vector3.Dot(vSepWS, RotA[1]), Vector3.Dot(vSepWS, RotA[2]));

            // Test if any of A's basis vectors separate the box
            for (i = 0; i < 3; i++)
            {
                ExtentA    = SizeA[i];
                ExtentB    = Vector3.Dot(SizeB, new Vector3(AR[i, 0], AR[i, 1], AR[i, 2]));
                Separation = Math.Abs(vSepA[i]);

                if (Separation > ExtentA + ExtentB)
                {
                    return(ContainmentType.Disjoint);
                }
            }

            // Test if any of B's basis vectors separate the box
            for (k = 0; k < 3; k++)
            {
                ExtentA    = Vector3.Dot(SizeA, new Vector3(AR[0, k], AR[1, k], AR[2, k]));
                ExtentB    = SizeB[k];
                Separation = Math.Abs(Vector3.Dot(vSepA, new Vector3(R[0, k], R[1, k], R[2, k])));

                if (Separation > ExtentA + ExtentB)
                {
                    return(ContainmentType.Disjoint);
                }
            }

            // Now test Cross Products of each basis vector combination ( A[i], B[k] )
            for (i = 0; i < 3; i++)
            {
                for (k = 0; k < 3; k++)
                {
                    int i1 = (i + 1) % 3, i2 = (i + 2) % 3;
                    int k1 = (k + 1) % 3, k2 = (k + 2) % 3;
                    ExtentA    = SizeA[i1] * AR[i2, k] + SizeA[i2] * AR[i1, k];
                    ExtentB    = SizeB[k1] * AR[i, k2] + SizeB[k2] * AR[i, k1];
                    Separation = Math.Abs(vSepA[i2] * R[i1, k] - vSepA[i1] * R[i2, k]);
                    if (Separation > ExtentA + ExtentB)
                    {
                        return(ContainmentType.Disjoint);
                    }
                }
            }

            // No separating axis found, the boxes overlap
            return(ContainmentType.Intersects);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit) operation,
 /// so all the passed points will fit in the current view.
 /// </summary>
 /// <param name="boundingBox">The bounding box.</param>
 /// <returns>The zoom to fit vector</returns>
 public Vector3 GetZoomToExtentsShiftVector(ref BoundingBox boundingBox)
 {
     return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners()) * pNear.Normal);
 }
Exemplo n.º 4
0
 /// <summary>
 /// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation,
 /// so all the passed points will fit in the current view.
 /// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
 /// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
 /// </summary>
 /// <param name="boundingBox">The bounding box.</param>
 /// <returns>The zoom to fit distance</returns>
 public float GetZoomToExtentsShiftDistance(ref BoundingBox boundingBox)
 {
     return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners()));
 }
Exemplo n.º 5
0
 public void Contains(ref BoundingBox box, out ContainmentType result)
 {
     result = this.Contains(box.GetCorners());
 }
Exemplo n.º 6
0
        public static GTABoundingBox2 ComputeBoundingBox(Entity e, Vector3 offset, float scale = 0.5f)
        {
            var m  = e.Model;
            var rv = new GTABoundingBox2
            {
                Min = new GTAVector2(float.PositiveInfinity, float.PositiveInfinity),
                Max = new GTAVector2(float.NegativeInfinity, float.NegativeInfinity)
            };
            Vector3 gmin;
            Vector3 gmax;

            m.GetDimensions(out gmin, out gmax);
            var bbox = new SharpDX.BoundingBox((SharpDX.Vector3) new GTAVector(gmin), (SharpDX.Vector3) new GTAVector(gmax));
            //Console.WriteLine(bbox.GetCorners()[0]);

            /*
             * for (int i = 0; i < bbox.GetCorners().Length; ++i) {
             *  for (int j = 0; j < bbox.GetCorners().Length; ++j) {
             *      if (j == i) continue;
             *      var c1 = bbox.GetCorners()[i];
             *      var c2 = bbox.GetCorners()[j];
             *      HashFunctions.Draw3DLine(e.GetOffsetInWorldCoords(new Vector3(c1.X, c1.Y, c1.Z)), e.GetOffsetInWorldCoords(new Vector3(c2.X, c2.Y, c2.Z)), 0,0);
             *  }
             * }
             */
            /*
             * for (int i = 0; i < bbox.GetCorners().Length; ++i)
             * {
             *  var corner = bbox.GetCorners()[i];
             *  var cornerinworld = e.GetOffsetInWorldCoords(new Vector3(corner.X, corner.Y, corner.Z));
             *
             *
             * }*/
            //UI.Notify(e.HeightAboveGround.ToString());
            var sp = HashFunctions.Convert3dTo2d(e.GetOffsetInWorldCoords(e.Position));

            foreach (var corner in bbox.GetCorners())
            {
                var c = new Vector3(corner.X, corner.Y, corner.Z);

                c = e.GetOffsetInWorldCoords(c);
                var s = HashFunctions.Convert3dTo2d(c);
                if (s.X == -1f || s.Y == -1f)
                {
                    rv.Min.X = float.PositiveInfinity;
                    rv.Max.X = float.NegativeInfinity;
                    rv.Min.Y = float.PositiveInfinity;
                    rv.Max.Y = float.NegativeInfinity;
                    return(rv);
                }

                /*
                 * if(s.X == -1) {
                 *  if (sp.X < 0.5) s.X = 0f;
                 *  if (sp.X >= 0.5) s.X = 1f;
                 * }
                 * if(s.Y == -1) {
                 *  if (sp.Y < 0.5) s.Y = 0f;
                 *  if (sp.Y >= 0.5) s.Y = 1f;
                 * }
                 */
                rv.Min.X = Math.Min(rv.Min.X, s.X);
                rv.Min.Y = Math.Min(rv.Min.Y, s.Y);
                rv.Max.X = Math.Max(rv.Max.X, s.X);
                rv.Max.Y = Math.Max(rv.Max.Y, s.Y);
            }

            float w = rv.Max.X - rv.Min.X;
            float h = rv.Max.Y - rv.Min.Y;

//            just for debug purposes, show visible and not visible entities in other color
//            if (CheckVisible(e))
//            {
//                HashFunctions.DrawRect(rv.Min.X + w / 2, rv.Min.Y + h / 2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y,
//                    Color.White, 100);
//            }
//            else
//            {
//                HashFunctions.DrawRect(rv.Min.X + w / 2, rv.Min.Y + h / 2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y,
//                    Color.Red, 100);
//            }
//            HashFunctions.DrawRect(rv.Min.X + w/2, rv.Min.Y + h/2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y, 255, 255, 255, 100);
            return(rv);
        }