/****************************************************************************************************

		TreeProjectionTransform.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Arnaud
		Date:	3/22/2005

****************************************************************************************************/

#ifndef __TreeProjectionTransform__
#define __TreeProjectionTransform__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "Plane.h"
#include "Matrix33.h"
#include "Vector2.h"
#include "Vector3.h"
#include "Transforms.h"

struct I3DShCamera;
class  TBBox3D;
class TPlane;
struct TStraightLine;



/// Used to store the steps of transformtion by TTreeProjectionTransform
///
struct ConTransformPoints : public TMCObject 
{
	TVector3 fObjectSp;		// the point before transformation in object coordinates
	TVector3 fGlobalSp;		// the point before projection in global coordinates
	TVector3 fProjectedSp;	// the point projected on the plane in global coordinates
	TVector3 fCameraSp;		// the point projected on the plane in camera coordinates
	TVector2 fLineArtSp;	// the projection on the screen
	real     fLastz;		// the distance from the screen
};

/// Used to store the steps of inverse transformtion by TTreeProjectionTransform
///
struct ConInverseTransformPoints : public TMCObject 
{
	TVector2 fLineArtSp;	// the point on the screen
	TVector3 fCameraSp;
	TVector3 fGlobalSp;
	TVector3 fPlaneSp;
};


/// \addtogroup Data
/// \{

/// TTreeProjectionTransform is a pipeline of transforms: <BR>
///	local => global => plane projection => eye => 2D projection
///
class TTreeProjectionTransform : public TMCObject
{
	public:
								TTreeProjectionTransform();
								~TTreeProjectionTransform();

		const TTransform3D*		GetTransform 	() const { return &fT; }
		const TPlane*	 		GetPlane 		() const {return fPlane;}
		const TTransform3D*		GetEyeTransform () const {return fEyeT;}
		const TTransform3D*		GetEyeInverseTransform () const {return fEyeInvT;}
		const I3DShCamera*		GetProjection 	() const {return fProj;}

		void 					SetTransform 	(const TTransform3D* aT);//, const TVector3& hotPoint);
		void 					SetPlane 		(const TPlane* aT)			{ fPlane = aT; }
		void 					SetEyeTransform (const TTransform3D* aT, const TTransform3D* aInvT);
		void 					SetProjection 	(I3DShCamera* aproj);

		boolean					Transform		(const TVector3& PP, 
												 TVector2& RR, 
												 ConTransformPoints* inter = 0,
												 boolean alreadyGlobal = false) const;
		boolean 				InverseTransform(const TVector2& iPoint, 
												 TVector2& 		pPoint, 
												 ConInverseTransformPoints* inter = 0) const;
		boolean 				TransformLine	(const TVector3& P1, 
											 	 const TVector3& P2,
											 	 TVector3& 		R1, 
											 	 TVector3& 		R2) const;
		boolean 				TransformPoint	(const TVector3& P1,
												 TVector3& 		R1) const;
		boolean 				InverseTransform(const TVector2& iPoint, 
												 TVector2& 		pPoint, 
												 ConInverseTransformPoints* inter,
												 TStraightLine*		aline) const;
		inline boolean			IsCameraIsometric() const	{ return fIsCameraIsometric; }
	protected:
		TTransform3D			fT;
		boolean 				fHasT;
		boolean					fIsCameraIsometric;
		const TPlane*	 		fPlane;
		const TTransform3D*		fEyeT;
		const TTransform3D*		fEyeInvT;
		I3DShCamera*			fProj;
};

/// \}

#endif

