# Collision and Intersection

The term collision can be used to refer to physical interactions (where physical objects collide and bump off one another), and also to non-physical intersections. This article is about non-physical (mathematical) collisions.

Non-physical collisions are interesting because they take less resources than physical ones. You cn optimize your game if you find a way to simulate a certain effect in a non-physical way, using mathematical techniques such as ray casting.

One example for an optimization is a physical vehicle's wheels. You could make the wheels fully physical disks, and have jME calculate every tiny force – sounds very accurate, but is total overkill. An more performant solution is to cast four rays down from the vehicle and calculate the intersections with the floor and other obstacles. These non-physical wheels require (in the simplest case) only four calculations to achieve an effect that players can hardly distinguish from the real thing.

## Bounding Volumes

A com.jme3.bounding.BoundingVolume is an interface for dealing with containment of a collection of points. All BoundingVolumes are Collidable and are used as optimization to calculate non-physical collisions more quickly: It's faster to calculate an intersection between simple shapes like spheres and boxes than between complex shapes. In cases where precision is not relevant, you wrap a complex model in a simpler shape to improve collision detection performance.

- Type.Sphere: com.jme3.bounding.BoundingSphere is a sphere used as a container for a group of vertices of a piece of geometry. A BoundingSphere has a center and a radius.
- Type.AABB = Axis-aligned bounding box. A com.jme3.bounding.BoundingBox is an axis-aligned cuboid used as a container for a group of vertices of a piece of geometry. A BoundingBox has a center and extents from that center along the x, y and z axis.
- Type.OBB = Oriented bounding box. (not in use)
- Type.Capsule

Note: Physical objects have their own “bounding volumes” called CollisionShapes.

## Collisions

The interface com.jme3.collision.Collidable declares one method that returns how many collisions were found between two Collidables: `collideWith(Collidable other, CollisionResults results)`.

A `com.jme3.collision.CollisionResults` object is an ArrayList of comparable `com.jme3.collision.CollisionResult` objects.

You can iterate over the CollisionResults to identify the other parties involved in the collision. Note that jME counts all collisions, this means a ray intersecting a box will be counted as two hits, one on the front where the ray enters, and one on the back where the ray exits.

CollisionResults Method | Usage
--- | ---
size() | Returns the number of CollisionResult objects.
getClosestCollision() | Returns the CollisionResult with the lowest distance.
getFarthestCollision() | Returns the CollisionResult with the farthest distance.
getCollision(i) | Returns the CollisionResult at index i.

A CollisionResult object contains information about the second party of the collision event.

CollisionResult Method | Usage
--- | ---
getContactPoint() | Returns the contact point coordinate on the second party, as Vector3f.
getContactNormal() | Returns the Normal vector at the contact point, as Vector3f.
getDistance() | Returns the distance between the Collidable and the second party, as float.
getGeometry() | Returns the Geometry of the second party.
getTriangle(t) | Binds t to the triangle t on the second party's mesh that was hit.
getTriangleIndex() | Returns the index of the triangle on the second party's mesh that was hit. (?)

Assume you have two collidables a and b and want to detect collisions between them. The collision parties can be Geometries, Nodes with Geometries attached (including the rootNode), Planes, Quads, Lines, or Rays.

The following code snippet can be triggered by listeners (e.g. after an input action such as a click), or timed in the update loop.

      // Calculate Results
      CollisionResults results = new CollisionResults();
      a.collideWith(b, results);

      System.out.println("Number of Collisions between" + a.getName()+ " and "
       + b.getName() " : " + results.size());

      // Use the results
      if (results.size() > 0) {
        CollisionResult closest  = results.getClosestCollision();
        System.out.println("What was hit? " + closest.getGeometry().getName() );
        System.out.println("Where was it hit? " + closest.getContactPoint() );
        System.out.println("Distance? " + closest.getDistance() );
      } else {
        // how to react when no collision occured
      }
    }

You can also loop over all results and trigger different reactions depending on what was hit and where it was hit. In this example, we simply print info about them.

      // Calculate Results
      CollisionResults results = new CollisionResults();
      a.collideWith(b, results);

      System.out.println("Number of Collisions between" + a.getName()+ " and "
       + b.getName() " : " + results.size());

      // Use the results
      for (int i = 0; i < results.size(); i++) {
        // For each hit, we know distance, impact point, name of geometry.
        float     dist = results.getCollision(i).getDistance();
        Vector3f    pt = results.getCollision(i).getContactPoint();
        String   party = results.getCollision(i).getGeometry().getName();
        int        tri = results.getCollision(i).getTriangleIndex();
        Vector3f  norm = results.getCollision(i).getTriangle(new Triangle()).getNormal();

        System.out.println("Details of Collision #" + i + ":");
        System.out.println("  Party " + party + " was hit at " + pt + ", " + dist + " wu away.");
        System.out.println("  The hit triangle #" + tri + " has a normal vector of " + norm);
      }

Knowing the distance of the collisions is useful for example when you intersect Lines and Rays with other objects.

## Intersection

A com.jme3.math.Ray is an infinite line with a beginning, a direction, and no end; whereas a com.jme3.math.Line is an infinite line with only a direction (no beginning, no end).

Rays are used to detect where a 3D object is “looking” and whether one object can “see” the other.

- You can determine where a user has clicked by casting a ray from the camera in the direction of the camera. Now identify the closest collision of the ray with e.g. the rootNode.
- Or you cast a ray from a player in the direction of another player. Then you detect all collisions of this ray with other entities (walls, foliage, window panes) and use this to calculate whether one can see the other.

These simple ray-surface intersection tests are called Ray Casting. (As opposed to the more advanced Ray Tracing, Ray Casting does not follow a ray's reflection after the first hit, but the ray goes straight on.)

## Bounding Interval Hierarchy

com.jme3.collision.bih.BIHNode com.jme3.scene.CollisionData

## SweepSphere

A com.jme3.collision.SweepSphere implements a collidable “stretched” sphere that is shaped like a capsule (an upright cylinder with half a sphere on top and the second half at the bottom).

This shape is usually used to simulate simple non-physcial collisions for character entities in games. The sweep sphere can be used to check collision against a triangle or another sweep sphere.

view online version