package speiger.src.coreengine.rendering.inputOld.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);
	}
}
