//===========================================================================//
// File:	point.hh                                                            //
// Project: MUNGA           Brick: Math Library                              //
// Contents: Interface specification of the point class                      //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/19/94  JMA  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(POINT_HPP)
#	define POINT_HPP

#	if !defined(VECTOR3D_HPP)
#		include <vector3d.hpp>
#	endif

	class Origin;
	class Vector4D;
	class AffineMatrix;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Point3D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	class Point3D:
		public Vector3D
	{
	public:
		static const Point3D
			Identity;

		//
		// Constructors
		//
		Point3D()
			{}
		Point3D(
			Scalar x,
			Scalar y,
			Scalar z
		):
			Vector3D(x,y,z)
				{}

		//
		// Assignment operators
		//
		Point3D&
			operator=(const Vector3D& v)
				{Vector3D::operator=(v); return *this;}
		Point3D&
			operator=(const Vector4D& v);
		Point3D&
			operator=(const Origin &p);
		Point3D&
			operator=(const AffineMatrix &matrix);

		//
		// Math operators
		//
		Point3D&
			Negate(const Vector3D &v)
				{Vector3D::Negate(v); return *this;}

		Point3D&
			Add(
				const Vector3D& v1,
				const Vector3D& v2
			)
				{Vector3D::Add(v1,v2); return *this;}
		Point3D&
			operator+=(const Vector3D& v)
				{return Add(*this,v);}

		Point3D&
			Subtract(
				const Point3D& p,
				const Vector3D& v
			)
				{Vector3D::Subtract(p,v); return *this;}
		Point3D&
			operator-=(const Vector3D& v)
				{return Subtract(*this,v);}

		Scalar
			operator*(const Vector3D& v) const
				{return Vector3D::operator*(v);}

		Point3D&
			Multiply(
				const Point3D& p,
				Scalar scale
			)
				{Vector3D::Multiply(p,scale); return *this;}
		Point3D&
			operator*=(Scalar value)
				{return Multiply(*this,value);}

		Point3D&
			Multiply(
				const Point3D& p,
				const Vector3D& v
			)
				{Vector3D::Multiply(p,v); return *this;}
		Point3D&
			operator*=(const Vector3D &v)
				{return Multiply(*this,v);}

		Point3D&
			Divide(
				const Vector3D& v,
				Scalar scale
			)
				{Vector3D::Divide(v,scale); return *this;}
		Point3D&
			operator/=(Scalar value)
				{return Divide(*this,value);}

		Point3D&
			Divide(
				const Vector3D& v1,
				const Vector3D& v2
			)
				{Vector3D::Divide(v1,v2); return *this;}
		Point3D&
			operator/=(const Vector3D &v)
				{return Divide(*this,v);}

		//
		// Transforms
		//
		Point3D&
			Multiply(
				const Vector3D &v,
				const AffineMatrix &m
			)
				{Vector3D::Multiply(v,m); return *this;}
		Point3D&
			Multiply(
				const Point3D &p,
				const AffineMatrix &m
			);
		Point3D&
			operator*=(const AffineMatrix &m)
				{Point3D src(*this); return Multiply(src,m);}
		Point3D&
			MultiplyByInverse(
				const Vector3D &v,
				const LinearMatrix &m
			)
				{Vector3D::MultiplyByInverse(v,m); return *this;}
		Point3D&
			MultiplyByInverse(
				const Point3D &p,
				const LinearMatrix &m
			);

		//
		// Miscellaneous functions
		//
		Point3D&
			Combine(
				const Vector3D& v1,
				Scalar t1,
				const Vector3D& v2,
				Scalar t2
			)
				{Vector3D::Combine(v1,t1,v2,t2); return *this;}

		//
		// Template support functions
		//
		Point3D&
			Lerp(
				const Vector3D& v1,
				const Vector3D& v2,
				Scalar t
			)
				{Vector3D::Lerp(v1,v2,t); return *this;}

		static Logical
			TestClass();
	};

#endif

#if !defined(AFFNMTRX_HPP)
#	include <affnmtrx.hpp>
#endif
