
com.harium.propan.math.Intersector Maven / Gradle / Ivy
The newest version!
package com.harium.propan.math;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.math.collision.Ray;
public class Intersector {
public final static float NO_COLLISION = -1;
public static boolean intersectRayBoundsFast(Ray ray, BoundingBox aabb, Matrix4 matrix) {
return intersectRayBounds(ray, aabb, matrix) != NO_COLLISION;
}
// Based on code at: http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/
public static float intersectRayBounds(Ray ray, BoundingBox aabb, Matrix4 matrix) {
float intersectionDistance = NO_COLLISION;
float tMin = 0.0f;
float tMax = 100000.0f;
Vector3 OBBPositionWorldspace = matrix.getTranslation(new Vector3());
Vector3 delta = OBBPositionWorldspace.sub(ray.origin);
// Test intersection with the 2 planes perpendicular to the OBB's X axis
{
Vector3 xaxis = new Vector3(matrix.val[Matrix4.M00], matrix.val[Matrix4.M10], matrix.val[Matrix4.M20]);
float e = xaxis.dot(delta);
float f = ray.direction.dot(xaxis);
if (Math.abs(f) > 0.001f) { // Standard case
float t1 = (e + aabb.min.x) / f; // Intersection with the "left" plane
float t2 = (e + aabb.max.x) / f; // Intersection with the "right" plane
// t1 and t2 now contain distances betwen ray origin and ray-plane intersections
// We want t1 to represent the nearest intersection,
// so if it's not the case, invert t1 and t2
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
} // swap t1 and t2
// tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs)
if (t2 < tMax)
tMax = t2;
// tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs)
if (t1 > tMin)
tMin = t1;
// And here's the trick :
// If "far" is closer than "near", then there is NO intersection.
// See the images in the tutorials for the visual explanation.
if (tMax < tMin)
return NO_COLLISION;
} else { // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection"
if (-e + aabb.min.x > 0.0f || -e + aabb.max.x < 0.0f)
return NO_COLLISION;
}
}
// Test intersection with the 2 planes perpendicular to the OBB's Y axis
// Exactly the same thing than above.
{
Vector3 yaxis = new Vector3(matrix.val[Matrix4.M01], matrix.val[Matrix4.M11], matrix.val[Matrix4.M21]);
float e = yaxis.dot(delta);
float f = ray.direction.dot(yaxis);
if (Math.abs(f) > 0.001f) {
float t1 = (e + aabb.min.y) / f;
float t2 = (e + aabb.max.y) / f;
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax)
tMax = t2;
if (t1 > tMin)
tMin = t1;
if (tMin > tMax)
return NO_COLLISION;
} else {
if (-e + aabb.min.y > 0.0f || -e + aabb.max.y < 0.0f)
return NO_COLLISION;
}
}
// Test intersection with the 2 planes perpendicular to the OBB's Z axis
// Exactly the same thing than above.
{
Vector3 zaxis = new Vector3(matrix.val[Matrix4.M02], matrix.val[Matrix4.M12], matrix.val[Matrix4.M22]);
float e = zaxis.dot(delta);
float f = ray.direction.dot(zaxis);
if (Math.abs(f) > 0.001f) {
float t1 = (e + aabb.min.z) / f;
float t2 = (e + aabb.max.z) / f;
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax)
tMax = t2;
if (t1 > tMin)
tMin = t1;
if (tMin > tMax)
return NO_COLLISION;
} else {
if (-e + aabb.min.z > 0.0f || -e + aabb.max.z < 0.0f)
return NO_COLLISION;
}
}
intersectionDistance = tMin;
return intersectionDistance;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy