Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
 /// <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.");
 }
Пример #6
0
 /// <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));
 }