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); }
/// <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); }
/// <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); }
/// <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())); }
public void Contains(ref BoundingBox box, out ContainmentType result) { result = this.Contains(box.GetCorners()); }
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); }