#pragma once

#include "point3d.h"
#include "unitvec.h"

class Plane;
class Sphere;
class Cylinder;
class Cone;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ray ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class Ray SIGNATURED
{
 public:
	Point3D origin;
	UnitVector direction;

	Ray()	{}
	Ray(const Point3D &origin, const UnitVector &direction) : origin(origin), direction(direction)	{}

	//
	// Ray projection functions
	//
	void Project(Scalar length, Point3D *result);
	Scalar LengthToClosestPointTo(const Point3D &point);
	void ClosestPointTo(const Point3D &point, Point3D *result)
	{
		Check(this);
		Check(result);
		Check(&point);
		Project(LengthToClosestPointTo(point), result);
	}

	//
	// Ray intersection functions
	//
	Scalar DistanceTo(const Plane &plane, Scalar *product) const;
	Scalar DistanceTo(const Sphere &sphere, Scalar *penetration) const;

	//
	// Test support
	//
	Logical TestInstance() const;
	static Logical TestClass();
};

extern Scalar Find_Closest_Approach(const Point3D& origin1, const Vector3D& velocity1, Point3D *result1, const Point3D& origin2, const Vector3D& velocity2, Point3D *result2, Scalar *time, Logical *constant);