/// <summary> /// Determine whether a box and a sphere intersect. /// </summary> /// <param name="box">Box physics object</param> /// <param name="sphere">Sphere physics object</param> public static bool BoxSphereCollision(BoxBody box, SphereBody sphere) { // reference frame: box at (0, 0, 0), sides aligned with axes var sphereCoordsRelative = sphere.Position - box.Position; // to transform coordinate system to have box be axis-aligned, we apply // the reverse of the rotation to the sphere coordinates var inverse = new Quaternion(box.Rotation.X, box.Rotation.Y, box.Rotation.Z, -box.Rotation.W); var sphereCoordsTransformed = Vector3.Transform(sphereCoordsRelative, inverse); // to check collision, we need to know if the shortest distance between the box // and the center of the sphere is smaller than the radius of the sphere // X coordinate of closest point = sphere.X if sphere.x is between the minimum // and maximum x coordinate of the box - same for y and z var boxMinX = -box.Size.X / 2; var boxMaxX = +box.Size.X / 2; var boxMinY = -box.Size.Y / 2; var boxMaxY = +box.Size.Y / 2; var boxMinZ = -box.Size.Z / 2; var boxMaxZ = +box.Size.Z / 2; var closestPointToSphereX = Math.Clamp(sphereCoordsTransformed.X, boxMinX, boxMaxX); var closestPointToSphereY = Math.Clamp(sphereCoordsTransformed.Y, boxMinY, boxMaxY); var closestPointToSphereZ = Math.Clamp(sphereCoordsTransformed.Z, boxMinZ, boxMaxZ); return(Vector3.DistanceSquared(sphereCoordsTransformed, new Vector3(closestPointToSphereX, closestPointToSphereY, closestPointToSphereZ)) < Math.Pow(sphere.Radius, 2)); }
/// <summary> /// Finds the vertices of a box body. /// </summary> /// <returns>A List containing the positions of the vertices.</returns> public static Vector3[] FindVertices(BoxBody box) { var vertices = new Vector3[8]; var boxMinX = -box.Size.X / 2; var boxMaxX = +box.Size.X / 2; var boxMinY = -box.Size.Y / 2; var boxMaxY = +box.Size.Y / 2; var boxMinZ = -box.Size.Z / 2; var boxMaxZ = +box.Size.Z / 2; vertices[0] = new Vector3(boxMinX, boxMinY, boxMinZ); vertices[1] = new Vector3(boxMinX, boxMinY, boxMaxZ); vertices[2] = new Vector3(boxMinX, boxMaxY, boxMinZ); vertices[3] = new Vector3(boxMinX, boxMaxY, boxMaxZ); vertices[4] = new Vector3(boxMaxX, boxMinY, boxMinZ); vertices[5] = new Vector3(boxMaxX, boxMinY, boxMaxZ); vertices[6] = new Vector3(boxMaxX, boxMaxY, boxMinZ); vertices[7] = new Vector3(boxMaxX, boxMaxY, boxMaxZ); // The resulting vectors are still relative to the axis-aligned box for (var i = 0; i < vertices.Length; i++) { vertices[i] = Vector3.Transform(vertices[i], box.Rotation) + box.Position; } return(vertices); }
/// <summary> /// Creates a box body. /// </summary> /// <param name="simulation">The simulation to use.</param> /// <param name="position">The position of the body.</param> /// <param name="rotation">The rotation of the body.</param> /// <param name="size">The size of the body (length in x, y and z direction).</param> /// <returns>The box body that was created.</returns> public static BoxBody Create(PhysicsSimulation simulation, Vector3 position, Quaternion rotation, Vector3 size) { var obj = new BoxBody(simulation); obj.Size = size; obj.Position = position; obj.Rotation = rotation; obj.Vertices = FindVertices(obj); simulation.Register(obj); return(obj); }
public static BoxBody Create(PhysicsSimulation simulation, Vector3 position, Quaternion rotation, Vector3 size) { var shape = new Box(size.X, size.Y, size.Z); shape.ComputeInertia(1, out var inertia); var index = simulation.Simulation.Shapes.Add(shape); var collidable = new CollidableDescription(index, 0.1f); var activity = new BodyActivityDescription(0); var pose = new RigidPose(position, rotation); var descriptor = BodyDescription.CreateDynamic(pose, inertia, collidable, activity); var handle = simulation.Simulation.Bodies.Add(descriptor); var obj = new BoxBody(simulation, handle); simulation.Register(obj); return(obj); }
/// <summary> /// Determine whether a capsule and a box intersect. /// </summary> /// <param name="capsule">The capsule</param> /// <param name="box">The box</param> public static bool CapsuleBoxCollision(CapsuleBody capsule, BoxBody box) { throw new NotImplementedException("Capsule-box collision checks are not implemented."); }
/// <summary> /// Determine whether two boxes intersect. /// </summary> /// <remarks> /// Not 100% accurate; it only checks vertex-face collisions, not edge-edge. /// However, this should be accurate enough for our use case. /// </remarks> /// <param name="firstBox">The first box</param> /// <param name="secondBox">The second box</param> public static bool BoxBoxCollision(BoxBody firstBox, BoxBody secondBox) { return(firstBox.ContainsAnyPoint(secondBox.Vertices) || secondBox.ContainsAnyPoint(firstBox.Vertices)); }