//***************************************************************************************
//
// File supervisor: Softimage Rendering & Pipeline team
//
// (c) Copyright 2001-2005 Avid Technology, Inc. . All rights reserved.
//
//***************************************************************************************

/**************************************************************************************
THIS CODE IS PUBLISHED AS A SAMPLE ONLY AND IS PROVIDED "AS IS".
IN NO EVENT SHALL SOFTIMAGE, AVID TECHNOLOGY, INC. AND/OR THEIR RESPECTIVE
SUPPLIERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS CODE .

COPYRIGHT NOTICE. Copyright © 1999-2005 Avid Technology Inc. . All rights reserved. 

SOFTIMAGE is a registered trademark of Avid Technology Inc. or its subsidiaries 
or divisions. Windows NT is a registered trademark of Microsoft Corp. All other
trademarks contained herein are the property of their respective owners. 
****************************************************************************************/
/*! \file cnv_camera_anim.cpp
/*!
	implementation file for camera animation related classes
*/

#include "stdafx.h"
#include "cnv_camera_anim.h"
#include <xsi_x3dobject.h>
#include <xsi_camera.h>
#include <xsi_kinematics.h>
#include <Model.h>
#include <Camera.h>
#include <XSICamera.h>
#include <FTKUtil.h>
#include "cmdstubs.h"

/**************************************************************************************
CCameraAnimationFromXSI
**************************************************************************************/
CCameraAnimationFromXSI::CCameraAnimationFromXSI(short in_CryFiletype) : CHierarchyTraverserCallback(in_CryFiletype) 
{
	m_pAnimationPlotter = NULL;
};

CCameraAnimationFromXSI::~CCameraAnimationFromXSI() {};

CStatus CCameraAnimationFromXSI::Execute(CdotXSIConverter *in_pContext, CRef in_XSIParent, CSLTemplate *in_pFTKParent, CHierarchyElementInfo* in_pInfo, CRef *io_pXSIModel, CSLTemplate **io_pFTKModel)
{
	CStatus status = CStatus::OK;

	if ((*io_pFTKModel) && ((*io_pFTKModel)->Type() == CSLTemplate::SI_MODEL))
	{
		CSLModel* l_pFTKModel = (CSLModel*)*io_pFTKModel;

        if (l_pFTKModel && l_pFTKModel->Primitive() && (l_pFTKModel->Primitive()->Type() == CSLTemplate::SI_CAMERA) )
		{
			CSLCamera* l_pFTKCamera = (CSLCamera*)l_pFTKModel->Primitive();
			Camera l_XSICamera = (Camera) *io_pXSIModel;

			X3DObject l_XSIInterest = l_XSICamera.GetInterest();
			if((l_XSIInterest.IsValid() && (l_XSIInterest.IsAnimated())))
			{
				// extract the roll animation
				CRefArray l_RefArray = l_XSICamera.GetKinematics().GetConstraints();
				CRef l_DirCns = l_RefArray.GetItem(L"Direction Cns");	// this is the default name (99% case)

				if (l_DirCns.IsValid())
				{
					FTKUParameterAnimationFromXSI(l_pFTKCamera, ((ProjectItem) l_DirCns).GetParameters(), CSLFCurve::SI_ROLL, m_pAnimationPlotter, L"roll");
				}

				// extract the supported interest transform animation
				CParameterRefArray l_InterestParameters = l_XSIInterest.GetParameters();
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_InterestParameters, CSLFCurve::SI_INTEREST_X, m_pAnimationPlotter, L"posx");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_InterestParameters, CSLFCurve::SI_INTEREST_Y, m_pAnimationPlotter, L"posy");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_InterestParameters, CSLFCurve::SI_INTEREST_Z, m_pAnimationPlotter, L"posz");
			}

			if(l_XSICamera.IsAnimated())
			{
				CParameterRefArray l_XSICameraParameters = l_XSICamera.GetParameters();

				// extract the supported camera animation
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_POSITION_X, m_pAnimationPlotter, L"posx");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_POSITION_Y, m_pAnimationPlotter, L"posy");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_POSITION_Z, m_pAnimationPlotter, L"posz");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_FOV, m_pAnimationPlotter, L"fov");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_NEAR, m_pAnimationPlotter, L"near");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_FAR, m_pAnimationPlotter, L"far");
			}
		}
	}
	return status;
}

wchar_t *CCameraAnimationFromXSI::GetClassID(){return L"CCameraAnimationFromXSI";}


CAnimationPlotter *CCameraAnimationFromXSI::GetAnimationPlotter()
{
	return m_pAnimationPlotter;
}

void CCameraAnimationFromXSI::SetAnimationPlotter(CAnimationPlotter *in_pAnimationPlotter)
{
	m_pAnimationPlotter = in_pAnimationPlotter;
}



/**************************************************************************************
CCameraAnimationToXSI
**************************************************************************************/
CCameraAnimationToXSI::CCameraAnimationToXSI(short in_CryFiletype) : CHierarchyTraverserCallback(in_CryFiletype) {};

CCameraAnimationToXSI::~CCameraAnimationToXSI() {};

CStatus CCameraAnimationToXSI::Execute(CdotXSIConverter *in_pContext, CRef in_XSIParent, CSLTemplate *in_pFTKParent, CHierarchyElementInfo* in_pInfo, CRef *io_pXSIModel, CSLTemplate **io_pFTKModel)
{
	CStatus status = CStatus::OK;

	if ((*io_pFTKModel) && ((*io_pFTKModel)->Type() == CSLTemplate::SI_MODEL))
	{
		CSLModel* l_pFTKModel = (CSLModel*)*io_pFTKModel;

        if (l_pFTKModel && l_pFTKModel->Primitive() && (l_pFTKModel->Primitive()->Type() == CSLTemplate::SI_CAMERA))
		{
			CSLCamera* l_pFTKCamera = (CSLCamera*)l_pFTKModel->Primitive();

			if(l_pFTKCamera->GetFCurveCount())
			{
				Camera l_XSICamera = (Camera) *io_pXSIModel;

				CParameterRefArray l_InterestParams = l_XSICamera.GetInterest().GetParameters();
				CParameterRefArray l_CameraParams = l_XSICamera.GetParameters();

				CSLFCurve** l_ppFTKFCurve = l_pFTKCamera->FCurves();
				LONG l_nFTKFCurveCount = l_pFTKCamera->GetFCurveCount();

				for (LONG loop = 0; loop < l_nFTKFCurveCount; loop++)
				{
					// special case: in the case of the camera interest animation we want to pass the interest itself
					if (l_ppFTKFCurve[loop]->GetFCurveType() == CSLFCurve::SI_INTEREST_X
						|| l_ppFTKFCurve[loop]->GetFCurveType() == CSLFCurve::SI_INTEREST_Y
						|| l_ppFTKFCurve[loop]->GetFCurveType() == CSLFCurve::SI_INTEREST_Z )
					{
						FTKUParameterAnimationToXSI(l_ppFTKFCurve[loop], l_InterestParams);
					}
					else if (l_ppFTKFCurve[loop]->GetFCurveType() == CSLFCurve::SI_ROLL)
					{
						CRefArray l_RefArray = l_XSICamera.GetKinematics().GetConstraints();
						CRef l_DirCns = l_RefArray.GetItem(L"Direction Cns");	// this is the default name (99% case)

						if (l_DirCns.IsValid())
						{
							FTKUParameterAnimationToXSI(l_ppFTKFCurve[loop], ((ProjectItem)l_DirCns).GetParameters());
						}
					}
					else
					{
						FTKUParameterAnimationToXSI(l_ppFTKFCurve[loop], l_CameraParams);
					}
				}
			}
		}
	}

	return status;
}

wchar_t *CCameraAnimationToXSI::GetClassID(){return L"CCameraAnimationToXSI";}

/**************************************************************************************
CXSICameraAnimationFromXSI
**************************************************************************************/
CXSICameraAnimationFromXSI::CXSICameraAnimationFromXSI(short in_CryFiletype) : CHierarchyTraverserCallback(in_CryFiletype) 
{
	m_pAnimationPlotter = NULL;
};

CXSICameraAnimationFromXSI::~CXSICameraAnimationFromXSI() {};

CStatus CXSICameraAnimationFromXSI::Execute(CdotXSIConverter *in_pContext, CRef in_XSIParent, CSLTemplate *in_pFTKParent, CHierarchyElementInfo* in_pInfo, CRef *io_pXSIModel, CSLTemplate **io_pFTKModel)
{
	CStatus status = CStatus::OK;

	if ((*io_pFTKModel) && ((*io_pFTKModel)->Type() == CSLTemplate::SI_MODEL))
	{
		CSLModel* l_pFTKModel = (CSLModel*)*io_pFTKModel;

        if (l_pFTKModel && l_pFTKModel->Primitive() && (l_pFTKModel->Primitive()->Type() == CSLTemplate::XSI_CAMERA) )
		{
			CSLXSICamera* l_pFTKCamera = (CSLXSICamera*)l_pFTKModel->Primitive();
			Camera l_XSICamera = (Camera) *io_pXSIModel;

			if(l_XSICamera.IsAnimated())
			{
				CParameterRefArray l_XSICameraParameters = l_XSICamera.GetParameters();

				// extract the supported camera animation
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"fov");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"interestdist");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"near");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"far");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplane");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplanedist");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplanewidth");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplaneheight");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplaneoffx");
				FTKUParameterAnimationFromXSI(l_pFTKCamera, l_XSICameraParameters, CSLFCurve::SI_PARAMETER, m_pAnimationPlotter, L"projplaneoffy");
			}
		}
	}
	return status;
}

wchar_t *CXSICameraAnimationFromXSI::GetClassID(){return L"CXSICameraAnimationFromXSI";}


CAnimationPlotter *CXSICameraAnimationFromXSI::GetAnimationPlotter()
{
	return m_pAnimationPlotter;
}

void CXSICameraAnimationFromXSI::SetAnimationPlotter(CAnimationPlotter *in_pAnimationPlotter)
{
	m_pAnimationPlotter = in_pAnimationPlotter;
}



/**************************************************************************************
CXSICameraAnimationToXSI
**************************************************************************************/
CXSICameraAnimationToXSI::CXSICameraAnimationToXSI(short in_CryFiletype) : CHierarchyTraverserCallback(in_CryFiletype) {};

CXSICameraAnimationToXSI::~CXSICameraAnimationToXSI() {};

CStatus CXSICameraAnimationToXSI::Execute(CdotXSIConverter *in_pContext, CRef in_XSIParent, CSLTemplate *in_pFTKParent, CHierarchyElementInfo* in_pInfo, CRef *io_pXSIModel, CSLTemplate **io_pFTKModel)
{
	CStatus status = CStatus::OK;

	if ((*io_pFTKModel) && ((*io_pFTKModel)->Type() == CSLTemplate::SI_MODEL))
	{
		CSLModel* l_pFTKModel = (CSLModel*)*io_pFTKModel;

        if (l_pFTKModel && l_pFTKModel->Primitive() && (l_pFTKModel->Primitive()->Type() == CSLTemplate::XSI_CAMERA))
		{
			CSLXSICamera* l_pFTKCamera = (CSLXSICamera*)l_pFTKModel->Primitive();

			if(l_pFTKCamera->GetFCurveCount())
			{
				Camera l_XSICamera = (Camera) *io_pXSIModel;

				CParameterRefArray l_CameraParams = l_XSICamera.GetParameters();

				CSLFCurve** l_ppFTKFCurve = l_pFTKCamera->FCurves();
				LONG l_nFTKFCurveCount = l_pFTKCamera->GetFCurveCount();

				for (LONG loop = 0; loop < l_nFTKFCurveCount; loop++)
				{
					FTKUParameterAnimationToXSI(l_ppFTKFCurve[loop], l_CameraParams);
				}
			}
		}
	}

	return status;
}

wchar_t *CXSICameraAnimationToXSI::GetClassID(){return L"CXSICameraAnimationToXSI";}

