SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/input/raycast/RayCollisions.java

45 lines
1.5 KiB
Java

package speiger.src.coreengine.rendering.input.raycast;
import speiger.src.coreengine.math.vector.floats.Vec3f;
public class RayCollisions
{
public static RayResult intersectQuad(Ray ray, Vec3f first, Vec3f second, Vec3f third, Vec3f fourth)
{
RayResult result = intersectTriangle(ray, first, second, third);
return result != null ? result : intersectTriangle(ray, first, fourth, third);
}
public static RayResult intersectTriangle(Ray ray, Vec3f first, Vec3f second, Vec3f third)
{
first = first.asImmutable();
second = second.asImmutable();
third = third.asImmutable();
RayResult result = intersectPlane(ray, first, second, third);
if(result == null) return null;
Vec3f hit = result.getHit();
Vec3f cross = second.sub(first).crossProduct(third.sub(first), Vec3f.ZERO);
if(cross.dotProduct(second.sub(first).crossProduct(hit.sub(first))) > 0)
{
if(cross.dotProduct(third.sub(second).crossProduct(hit.sub(second))) > 0)
{
if(cross.dotProduct(first.sub(third).crossProduct(hit.sub(third))) > 0)
{
return result;
}
}
}
return null;
}
static RayResult intersectPlane(Ray ray, Vec3f first, Vec3f second, Vec3f third)
{
Vec3f cross = second.sub(first).crossProduct(third.sub(first), Vec3f.ZERO);
Vec3f distance = ray.distance();
double hitDot = distance.dotProduct(cross);
if(Math.abs(hitDot) < 0.0000000001D) return null;
double step = first.sub(ray.start()).dotProduct(cross) / hitDot;
return new RayResult(ray, ray.interpolate((float)step), step);
}
}