public static void processSpherePlaneCollision(RigidBody plane,
			RigidBody sphere, double restitution, double timeStep) {

		// Predicted positions
		Vector3d planePosition = new Vector3d();
		Vector3d spherePosition = new Vector3d();
		Quat4d planeRotation = new Quat4d();
		Quat4d sphereRotration = new Quat4d();
		sphere.predictCollisionPosition(timeStep, spherePosition,
				sphereRotration);
		plane.predictCollisionPosition(timeStep, planePosition, planeRotation);

		// Collision normal
		Matrix3d planeRotationMatrix = new Matrix3d();
		planeRotationMatrix.set(planeRotation);

		// Non-interpenetrating pair
		if (((PlaneObject) plane.getCollisionObject()).getLocalSignedDistance(
				planePosition, planeRotationMatrix, spherePosition) > ((SphereObject) sphere
				.getCollisionObject()).getRadius()) {
			return;
		}
		Vector3d normal = new Vector3d(
				((PlaneObject) plane.getCollisionObject()).getNormal(null,
						planeRotationMatrix));

		// Intersecting points
		Vector3d relativePosition = new Vector3d(spherePosition);
		relativePosition.sub(planePosition);
		Vector3d rPlane = new Vector3d(normal);
		Vector3d rSphere = new Vector3d(normal);
		rPlane.scale(-((PlaneObject) plane.getCollisionObject())
				.getLocalSignedDistance(planePosition, planeRotationMatrix,
						spherePosition));
		rPlane.add(relativePosition);
		rSphere.scale(-((SphereObject) sphere.getCollisionObject()).getRadius());
		Matrix3d crossSphere = new Matrix3d(0, -rSphere.z, rSphere.y,
				rSphere.z, 0, -rSphere.x, -rSphere.y, rSphere.x, 0);

		// Relative velocity
		Vector3d relativeVelocity = new Vector3d();
		relativeVelocity.cross(sphere.getAngularVelocity(), rSphere);

		Vector3d angularVelocity = new Vector3d();
		angularVelocity.cross(plane.getAngularVelocity(), rPlane);
		relativeVelocity.sub(angularVelocity);
		relativeVelocity.add(sphere.getLinearVelocity());
		relativeVelocity.sub(plane.getLinearVelocity());

		// Separating velocity
		if (relativeVelocity.dot(normal) > 0) {
			return;
		}

		/*
		 * K = I/m + transpose(r*) I^-1 r*
		 */
		Matrix3d k = new Matrix3d(crossSphere);
		k.transpose();
		k.mul(sphere.getInertiaLocalInverse());
		k.mul(crossSphere);
		k.add(new Matrix3d(1 / sphere.getMass(), 0, 0, 0, 1 / sphere.getMass(),
				0, 0, 0, 1 / sphere.getMass()));

		processCollision(plane, rPlane, sphere, rSphere, relativeVelocity,
				normal, k, restitution, timeStep);
	}