/// <summary> /// Intersectses this instance. /// </summary> /// <param name="center">The center.</param> /// <param name="radius">The radius.</param> /// <param name="boxCollider">The box collider.</param> /// <returns>true if intersects</returns> private bool Intersects(Vector3 center, float radius, BoundingOrientedBox boxCollider) { Vector2 circleDistance = Vector2.Zero; circleDistance.X = Math.Abs(center.Z - boxCollider.Center.Z); circleDistance.Y = Math.Abs(center.Y - boxCollider.Center.Y); if (circleDistance.X > (boxCollider.HalfExtent.Z + radius)) { return(false); } if (circleDistance.Y > (boxCollider.HalfExtent.Y + radius)) { return(false); } if (circleDistance.X <= (boxCollider.HalfExtent.Z)) { return(true); } if (circleDistance.Y <= (boxCollider.HalfExtent.Y)) { return(true); } var cornerDistanceSq = Math.Sqrt(circleDistance.X - boxCollider.HalfExtent.Z) + Math.Sqrt(circleDistance.Y - boxCollider.HalfExtent.Y); return(cornerDistanceSq <= (Math.Sqrt(radius))); }
public ContainmentType Contains(BoundingOrientedBox box) { if (!box.Intersects(this)) { return(ContainmentType.Disjoint); } XMVector v_center = this.center; XMVector v_radius = XMVector.Replicate(this.radius); XMVector radiusSq = v_radius * v_radius; XMVector boxCenter = box.Center; XMVector boxExtents = box.Extents; XMVector boxOrientation = box.Orientation; Debug.Assert(Internal.XMQuaternionIsUnit(boxOrientation), "Reviewed"); XMVector insideAll = XMVector.TrueInt; for (int i = 0; i < BoundingOrientedBox.CornerCount; i++) { XMVector c = XMVector3.Rotate(boxExtents * CollisionGlobalConstants.BoxOffsets[i], boxOrientation) + boxCenter; XMVector d = XMVector3.LengthSquare(XMVector.Subtract(v_center, c)); insideAll = XMVector.AndInt(insideAll, XMVector.LessOrEqual(d, radiusSq)); } return(XMVector3.EqualInt(insideAll, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects); }
/// <summary> /// Intersectses the sphere with box. /// </summary> /// <param name="center">The center.</param> /// <param name="radius">The radius.</param> /// <param name="boxCollider">The box collider.</param> /// <returns> /// True if intersects /// </returns> public CollisionType CheckCollisionType(Vector3 center, float radius, BoundingOrientedBox boxCollider, string tag) { CollisionType res = CollisionType.NONE; bool collides = this.Intersects(center, radius, boxCollider); if (collides) { if (tag.Equals(KILLERTAG)) { res = CollisionType.KILLER; } else { Vector2 CB = new Vector2(boxCollider.Center.Z - center.Z, boxCollider.Center.Y - center.Y); CB.Normalize(); var angle = Vector2.Angle(-Vector2.UnitY, CB); if (angle > -rad30 && angle < rad30) { res = CollisionType.GROUND; } else { res = CollisionType.KILLER; } } } return(res); }
public ContainmentType Contains(BoundingOrientedBox box) { if (!box.Intersects(this)) { return(ContainmentType.Disjoint); } XMVector boxCenter = this.center; XMVector boxExtents = this.extents; // Subtract off the AABB center to remove a subtract below XMVector o_center = box.Center - boxCenter; XMVector o_extents = box.Extents; XMVector o_orientation = box.Orientation; Debug.Assert(Internal.XMQuaternionIsUnit(o_orientation), "Reviewed"); XMVector inside = XMVector.TrueInt; for (int i = 0; i < BoundingOrientedBox.CornerCount; i++) { XMVector c = XMVector3.Rotate(o_extents * CollisionGlobalConstants.BoxOffsets[i], o_orientation) + o_center; XMVector d = c.Abs(); inside = XMVector.AndInt(inside, XMVector.LessOrEqual(d, boxExtents)); } return(XMVector3.EqualInt(inside, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects); }
protected override void Initialize() { // Create a box that is centered on the origin and extends from (-3, -3, -3) to (3, 3, 3) box = new BoundingOrientedBox(Vector3.Zero, new Vector3(3), Quaternion.Identity); // Create our frustum to simulate a camera sitting at the origin, looking down the X axis, with a 16x9 // aspect ratio, a near plane of 1, and a far plane of 5 Matrix frustumView = Matrix.CreateLookAt(Vector3.Zero, Vector3.UnitX, Vector3.Up); Matrix frustumProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 16f / 9f, 1f, 5f); frustum = new BoundingFrustum(frustumView * frustumProjection); // Create a sphere that is centered on the origin and has a radius of 3 sphere = new BoundingSphere(Vector3.Zero, 3f); }
/// <summary> /// Determines whether the given BoundingOrientedBox contains/intersects/is disjoint from the triangle /// (v0,v1,v2) /// </summary> public static ContainmentType Contains(ref BoundingOrientedBox obox, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2) { // Transform the triangle into the local space of the box, so we can use a // faster axis-aligned box test. // Note than when transforming more than one point, using an intermediate matrix // is faster than doing multiple quaternion transforms directly. Quaternion qinv; Quaternion.Conjugate(ref obox.Orientation, out qinv); Matrix minv; Matrix.CreateFromQuaternion(ref qinv, out minv); Triangle localTri = new Triangle(); localTri.V0 = Vector3.TransformNormal(v0 - obox.Center, minv); localTri.V1 = Vector3.TransformNormal(v1 - obox.Center, minv); localTri.V2 = Vector3.TransformNormal(v2 - obox.Center, minv); return OriginBoxContains(ref obox.HalfExtent, ref localTri); }
public void RunTests() { Random random = new Random(1); for (int i = 0; i < 10000; i++) { TestRandomObjects( random, new BoundingOrientedBoxOps(), new BoundingOrientedBoxOps(), (b1, b2) => b1.Contains(ref b2), (b1, b2) => b1.Intersects(ref b2)); TestRandomObjects( random, new BoundingOrientedBoxOps(), new BoundingBoxOps(), (b1, b2) => b1.Contains(ref b2), (b1, b2) => b1.Intersects(ref b2)); TestRandomObjects( random, new BoundingBoxOps(), new BoundingOrientedBoxOps(), (b1, b2) => BoundingOrientedBox.Contains(ref b1, ref b2), (b1, b2) => b2.Intersects(ref b1)); TestRandomObjects( random, new BoundingBoxOps(), new BoundingBoxOps(), (b1, b2) => b1.Contains(b2), (b1, b2) => b1.Intersects(b2)); TestRandomObjects( random, new BoundingSphereOps(), new TriangleOps(), (b, t) => TriangleTest.Contains(ref b, ref t), (b, t) => TriangleTest.Intersects(ref b, ref t)); TestRandomObjects( random, new BoundingBoxOps(), new TriangleOps(), (b, t) => TriangleTest.Contains(ref b, ref t), (b, t) => TriangleTest.Intersects(ref b, ref t.V0, ref t.V1, ref t.V2)); TestRandomObjects( random, new BoundingOrientedBoxOps(), new TriangleOps(), (b, t) => TriangleTest.Contains(ref b, ref t), (b, t) => TriangleTest.Intersects(ref b, ref t.V0, ref t.V1, ref t.V2)); } Console.WriteLine("Passed: {0} Failed: {1}", TestsPassed, TestsFailed); Debug.WriteLine("Passed: {0} Failed: {1}", TestsPassed, TestsFailed); }
/// <summary> /// Renders the outline of an oriented bounding box /// </summary> /// <param name="box">Oriented bounding box to render</param> /// <param name="color">Color of the box lines</param> public void DrawWireBox(BoundingOrientedBox box, Color color) { DrawWireShape(box.GetCorners(), cubeIndices, color); }
// Set up initial bounding shapes for the primary (static) and secondary (moving) // bounding shapes along with relevant camera position information. protected override void Initialize() { Console.WriteLine("DEBUG - Game Initialize!"); debugDraw = new DebugDraw(GraphicsDevice); Components.Add(new FrameRateCounter(this)); // Primary frustum Matrix m1 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1.77778F, 0.5f, 10.0f); Matrix m2 = Matrix.CreateTranslation(new Vector3(0, 0, -7)); primaryFrustum = new BoundingFrustum(Matrix.Multiply(m2, m1)); cameraOrigins[FrustumGroupIndex] = Vector3.Zero; // Primary axis-aligned box primaryAABox.Min = new Vector3(CAMERA_SPACING - 3, -4, -5); primaryAABox.Max = new Vector3(CAMERA_SPACING + 3, 4, 5); cameraOrigins[AABoxGroupIndex] = new Vector3(CAMERA_SPACING, 0, 0); // Primary oriented box primaryOBox.Center = new Vector3(-CAMERA_SPACING, 0, 0); primaryOBox.HalfExtent = new Vector3(3, 4, 5); primaryOBox.Orientation = Quaternion.CreateFromYawPitchRoll(0.8f, 0.7f, 0); cameraOrigins[OBoxGroupIndex] = primaryOBox.Center; // Primary sphere primarySphere.Center = new Vector3(0, 0, -CAMERA_SPACING); primarySphere.Radius = 5; cameraOrigins[SphereGroupIndex] = primarySphere.Center; // Primary ray primaryRay.Position = new Vector3(0, 0, CAMERA_SPACING); primaryRay.Direction = Vector3.UnitZ; cameraOrigins[RayGroupIndex] = primaryRay.Position; // Initialize all of the secondary objects with default values Vector3 half = new Vector3(0.5F, 0.5F, 0.5F); for (int i = 0; i < NumGroups; i++) { secondarySpheres[i] = new BoundingSphere(Vector3.Zero, 1.0f); secondaryOBoxes[i] = new BoundingOrientedBox(Vector3.Zero, half, Quaternion.Identity); secondaryAABoxes[i] = new BoundingBox(-half, half); secondaryTris[i] = new Triangle(); } rayHitResult = null; currentCamera = 3; cameraOrtho = false; cameraYaw = (float)Math.PI * 0.75F; cameraPitch = MathHelper.PiOver4; cameraDistance = 20; cameraTarget = cameraOrigins[0]; paused = false; base.Initialize(); }
private void Animate(double fTime) { float t = (float)(fTime * 0.2); float camera0OriginX = this.cameraOrigins[0].X; float camera1OriginX = this.cameraOrigins[1].X; float camera2OriginX = this.cameraOrigins[2].X; float camera3OriginX = this.cameraOrigins[3].X; float camera3OriginZ = this.cameraOrigins[3].Z; // animate sphere 0 around the frustum { BoundingSphere sphere = this.secondarySpheres[0].Sphere; sphere.Center = new XMFloat3 { X = 10 * XMScalar.Sin(3 * t), Y = 7 * XMScalar.Cos(5 * t), Z = sphere.Center.Z }; this.secondarySpheres[0].Sphere = sphere; } // animate oriented box 0 around the frustum { BoundingOrientedBox box = this.secondaryOrientedBoxes[0].Box; box.Center = new XMFloat3 { X = 8 * XMScalar.Sin(3.5f * t), Y = 5 * XMScalar.Cos(5.1f * t), Z = box.Center.Z }; box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 1.4f, t * 0.2f, t); this.secondaryOrientedBoxes[0].Box = box; } // animate aligned box 0 around the frustum { BoundingBox box = this.secondaryAABoxes[0].Box; box.Center = new XMFloat3 { X = 10 * XMScalar.Sin(2.1f * t), Y = 7 * XMScalar.Cos(3.8f * t), Z = box.Center.Z }; this.secondaryAABoxes[0].Box = box; } // animate sphere 1 around the aligned box { BoundingSphere sphere = this.secondarySpheres[1].Sphere; sphere.Center = new XMFloat3 { X = 8 * XMScalar.Sin(2.9f * t) + camera1OriginX, Y = 8 * XMScalar.Cos(4.6f * t), Z = 8 * XMScalar.Cos(1.6f * t) }; this.secondarySpheres[1].Sphere = sphere; } // animate oriented box 1 around the aligned box { BoundingOrientedBox box = this.secondaryOrientedBoxes[1].Box; box.Center = new XMFloat3 { X = 8 * XMScalar.Sin(3.2f * t) + camera1OriginX, Y = 8 * XMScalar.Cos(2.1f * t), Z = 8 * XMScalar.Sin(1.6f * t) }; box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.7f, t * 1.3f, t); this.secondaryOrientedBoxes[1].Box = box; } // animate aligned box 1 around the aligned box { BoundingBox box = this.secondaryAABoxes[1].Box; box.Center = new XMFloat3 { X = 8 * XMScalar.Sin(1.1f * t) + camera1OriginX, Y = 8 * XMScalar.Cos(5.8f * t), Z = 8 * XMScalar.Cos(3.0f * t) }; this.secondaryAABoxes[1].Box = box; } // animate sphere 2 around the oriented box { BoundingSphere sphere = this.secondarySpheres[2].Sphere; sphere.Center = new XMFloat3 { X = 8 * XMScalar.Sin(2.2f * t) + camera2OriginX, Y = 8 * XMScalar.Cos(4.3f * t), Z = 8 * XMScalar.Cos(1.8f * t) }; this.secondarySpheres[2].Sphere = sphere; } // animate oriented box 2 around the oriented box { BoundingOrientedBox box = this.secondaryOrientedBoxes[2].Box; box.Center = new XMFloat3 { X = 8 * XMScalar.Sin(3.7f * t) + camera2OriginX, Y = 8 * XMScalar.Cos(2.5f * t), Z = 8 * XMScalar.Sin(1.1f * t) }; box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.9f, t * 1.8f, t); this.secondaryOrientedBoxes[2].Box = box; } // animate aligned box 2 around the oriented box { BoundingBox box = this.secondaryAABoxes[2].Box; box.Center = new XMFloat3 { X = 8 * XMScalar.Sin(1.3f * t) + camera2OriginX, Y = 8 * XMScalar.Cos(5.2f * t), Z = 8 * XMScalar.Cos(3.5f * t) }; this.secondaryAABoxes[2].Box = box; } // triangle points in local space - equilateral triangle with radius of 2 XMVector trianglePointA = new(0, 2, 0, 0); XMVector trianglePointB = new(1.732f, -1, 0, 0); XMVector trianglePointC = new(-1.732f, -1, 0, 0); XMMatrix triangleCoords; XMMatrix translation; // animate triangle 0 around the frustum triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t); translation = XMMatrix.Translation( 5 * XMScalar.Sin(5.3f * t) + camera0OriginX, 5 * XMScalar.Cos(2.3f * t), 5 * XMScalar.Sin(3.4f * t)); triangleCoords = XMMatrix.Multiply(triangleCoords, translation); this.secondaryTriangles[0].PointA = XMVector3.Transform(trianglePointA, triangleCoords); this.secondaryTriangles[0].PointB = XMVector3.Transform(trianglePointB, triangleCoords); this.secondaryTriangles[0].PointC = XMVector3.Transform(trianglePointC, triangleCoords); // animate triangle 1 around the aligned box triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t); translation = XMMatrix.Translation( 8 * XMScalar.Sin(5.3f * t) + camera1OriginX, 8 * XMScalar.Cos(2.3f * t), 8 * XMScalar.Sin(3.4f * t)); triangleCoords = XMMatrix.Multiply(triangleCoords, translation); this.secondaryTriangles[1].PointA = XMVector3.Transform(trianglePointA, triangleCoords); this.secondaryTriangles[1].PointB = XMVector3.Transform(trianglePointB, triangleCoords); this.secondaryTriangles[1].PointC = XMVector3.Transform(trianglePointC, triangleCoords); // animate triangle 2 around the oriented box triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t); translation = XMMatrix.Translation( 8 * XMScalar.Sin(5.3f * t) + camera2OriginX, 8 * XMScalar.Cos(2.3f * t), 8 * XMScalar.Sin(3.4f * t)); triangleCoords = XMMatrix.Multiply(triangleCoords, translation); this.secondaryTriangles[2].PointA = XMVector3.Transform(trianglePointA, triangleCoords); this.secondaryTriangles[2].PointB = XMVector3.Transform(trianglePointB, triangleCoords); this.secondaryTriangles[2].PointC = XMVector3.Transform(trianglePointC, triangleCoords); // animate primary ray (this is the only animated primary object) this.primaryRay.Direction = new XMVector(XMScalar.Sin(t * 3), 0, XMScalar.Cos(t * 3), 0); // animate sphere 3 around the ray { BoundingSphere sphere = this.secondarySpheres[3].Sphere; sphere.Center = new XMFloat3(camera3OriginX - 3, 0.5f * XMScalar.Sin(t * 5), camera3OriginZ); this.secondarySpheres[3].Sphere = sphere; } // animate aligned box 3 around the ray { BoundingBox box = this.secondaryAABoxes[3].Box; box.Center = new XMFloat3(camera3OriginX + 3, 0.5f * XMScalar.Sin(t * 4), camera3OriginZ); this.secondaryAABoxes[3].Box = box; } // animate oriented box 3 around the ray { BoundingOrientedBox box = this.secondaryOrientedBoxes[3].Box; box.Center = new XMFloat3(camera3OriginX, 0.5f * XMScalar.Sin(t * 4.5f), camera3OriginZ + 3); box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.9f, t * 1.8f, t); this.secondaryOrientedBoxes[3].Box = box; } // animate triangle 3 around the ray triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t); translation = XMMatrix.Translation( camera3OriginX, 0.5f * XMScalar.Cos(4.3f * t), camera3OriginZ - 3); triangleCoords = XMMatrix.Multiply(triangleCoords, translation); this.secondaryTriangles[3].PointA = XMVector3.Transform(trianglePointA, triangleCoords); this.secondaryTriangles[3].PointB = XMVector3.Transform(trianglePointB, triangleCoords); this.secondaryTriangles[3].PointC = XMVector3.Transform(trianglePointC, triangleCoords); }
public bool Intersects(BoundingOrientedBox box) { return(box.Intersects(this)); }
public static BoundingSphere CreateFromOrientedBox(BoundingOrientedBox box) { // Bounding box orientation is irrelevant because a sphere is rotationally invariant return(new BoundingSphere(box.Center, XMVector3.Length(box.Extents).X)); }
/// <summary> /// Determines whether the given BoundingOrientedBox contains/intersects/is disjoint from the /// given triangle. /// </summary> public static ContainmentType Contains(ref BoundingOrientedBox obox, ref Triangle triangle) { return Contains(ref obox, ref triangle.V0, ref triangle.V1, ref triangle.V2); }
/// <summary> /// Intersectses this instance. /// </summary> /// <param name="center">The center.</param> /// <param name="radius">The radius.</param> /// <param name="boxCollider">The box collider.</param> /// <returns>true if intersects</returns> private bool Intersects(Vector3 center, float radius, BoundingOrientedBox boxCollider) { Vector2 circleDistance = Vector2.Zero; circleDistance.X = Math.Abs(center.Z - boxCollider.Center.Z); circleDistance.Y = Math.Abs(center.Y - boxCollider.Center.Y); if (circleDistance.X > (boxCollider.HalfExtent.Z + radius)) { return false; } if (circleDistance.Y > (boxCollider.HalfExtent.Y + radius)) { return false; } if (circleDistance.X <= (boxCollider.HalfExtent.Z)) { return true; } if (circleDistance.Y <= (boxCollider.HalfExtent.Y)) { return true; } var cornerDistanceSq = Math.Sqrt(circleDistance.X - boxCollider.HalfExtent.Z) + Math.Sqrt(circleDistance.Y - boxCollider.HalfExtent.Y); return (cornerDistanceSq <= (Math.Sqrt(radius))); }
/// <summary> /// Intersectses the sphere with box. /// </summary> /// <param name="center">The center.</param> /// <param name="radius">The radius.</param> /// <param name="boxCollider">The box collider.</param> /// <returns> /// True if intersects /// </returns> public CollisionType CheckCollisionType(Vector3 center, float radius, BoundingOrientedBox boxCollider, string tag) { CollisionType res = CollisionType.NONE; bool collides = this.Intersects(center, radius, boxCollider); if (collides) { if (tag.Equals(KILLERTAG)) { res = CollisionType.KILLER; } else { Vector2 CB = new Vector2(boxCollider.Center.Z - center.Z, boxCollider.Center.Y - center.Y); CB.Normalize(); var angle = Vector2.Angle(-Vector2.UnitY, CB); if (angle > -rad30 && angle < rad30) { res = CollisionType.GROUND; } else { res = CollisionType.KILLER; } } } return res; }