//***************************************************************************************
//
// 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_modelinfo_anim.cpp
/*!
	implementation file for model level info animation related classes
*/

#include "stdafx.h"
#include "cnv_modelinfo_anim.h"
#include "cnv_hierarchyelementinfo.h"
#include "FTKUtil.h"
#include <Model.h>
#include <Visibility.h>
#include <XSITransform.h>
#include <XSILimit.h>
#include <xsi_x3dobject.h>
#include "cmdstubs.h"
#include <xsi_model.h>
#include <xsi_kinematics.h>
#include <xsi_kinematicstate.h>
#include <xsi_chainelement.h>
#include <xsi_chaineffector.h>
#include <xsi_customoperator.h>
#include "plugin_stub.h"

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

CModelInfoAnimationFromXSI::~CModelInfoAnimationFromXSI() {};

CStatus CModelInfoAnimationFromXSI::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 != NULL)
	{
		CSLModel *l_pFTKModel = (CSLModel *) *io_pFTKModel;
		X3DObject l_XSIModel = (X3DObject) *io_pXSIModel;

		// check if we must bail out sooner
		if(l_pFTKModel->Template() == NULL)
			return status;

		// Fill in the transform now
		CRefArray l_Parameters = l_XSIModel.GetKinematics().GetLocal().GetAnimatedParameters(siAnySource);

		if((l_pFTKModel->XSITransform() != NULL) && (l_Parameters.GetCount()))
		{
			// we export everything that is animated, except the min and max stuff
			int		loop;
			int		l_RemainingParams = l_Parameters.GetCount();

			for(loop = 0; loop < l_Parameters.GetCount(); loop++)
			{
				Parameter l_Parameter = l_Parameters[loop];
				CString l_ParamName = l_Parameter.GetScriptName();

				if(!wcswcs(l_ParamName.GetWideString(), L"min") && !wcswcs(l_ParamName.GetWideString(), L"max"))
				{
					FTKUParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_Parameter, m_pAnimationPlotter, l_ParamName.GetWideString());					
					l_RemainingParams --;
				}
			}
			
			if(l_RemainingParams)
			{
				// limits
				CSLXSILimit** l_pFTKLimits = l_pFTKModel->XSITransform()->GetXSILimitList();
				
				for (loop = 0; loop < l_pFTKModel->XSITransform()->GetXSILimitCount(); loop++)
				{
					CString l_ParamName;
					const SI_Char* l_pParamName = l_pFTKLimits[loop]->GetParameterName();

					l_ParamName.PutAsciiString(l_pParamName);

					Parameter l_MinLimit, l_MaxLimit;
					l_MinLimit = l_Parameters.GetItem(l_ParamName + L"minlimit");
					l_MaxLimit = l_Parameters.GetItem(l_ParamName + L"maxlimit");

					if(l_MinLimit.IsValid())
					{
						FTKUParameterAnimationFromXSI(l_pFTKLimits[loop], CSLFCurve::SI_PARAMETER, l_MinLimit, m_pAnimationPlotter, L"minlimit");
					}

					if(l_MaxLimit.IsValid())
					{
						FTKUParameterAnimationFromXSI(l_pFTKLimits[loop], CSLFCurve::SI_PARAMETER, l_MaxLimit, m_pAnimationPlotter, L"maxlimit");
					}
				}
			}
			LONG Format = in_pContext->exportproperty().GetParameterValue (L"format");

			if((Format != DOTXSI_FORMAT_5_0) && (Format != DOTXSI_FORMAT_5_0_BINARY))
			{
				// polymatricks
				CSLXSIPolymatricks *l_pPolymatricks = l_pFTKModel->XSITransform()->GetPolymatricks();

				if(l_pPolymatricks)
				{
					// Check for polymatricks
					CRefArray l_NestedComponents = l_XSIModel.GetKinematics().GetLocal().GetNestedObjects();
					CustomOperator op;
					CRefArray l_PolymatricksAnimatedParameters;

					// find all the animated parameters
					int loop, count = l_NestedComponents.GetCount();
					for(loop = 0; loop < count; loop ++)
					{
						op = l_NestedComponents[loop];
						if(op.IsValid() && (op.GetType() == L"polymatricks"))
						{
							l_PolymatricksAnimatedParameters = op.GetAnimatedParameters(siAnySource);
							break;
						}
					}

					if(l_PolymatricksAnimatedParameters.GetCount())
					{

						// go through the polymatricks template and check if any of these match
						for(loop = 0; loop < l_pPolymatricks->GetTransformNodeCount(); loop++)
						{
							CSLTemplate *l_pNode = l_pPolymatricks->GetTransformNodes()[loop];
							CString l_NodeName;
							l_NodeName.PutAsciiString(l_pNode->GetName());

							if((l_pNode->Type() == CSLTemplate::XSI_TRANSLATE) || (l_pNode->Type() == CSLTemplate::XSI_SCALE))
							{
								Parameter l_Param;
								
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_X");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"x");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Y");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"y");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Z");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"z");
							}
							else if(l_pNode->Type() == CSLTemplate::XSI_ROTATE)
							{
								Parameter l_Param;
								
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_X");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"x");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Y");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"y");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Z");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"z");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Angle");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"angle");
							}
							else if(l_pNode->Type() == CSLTemplate::XSI_SHEAR)
							{
								Parameter l_Param;
								
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_X1");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"x1");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Y1");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"y1");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Z1");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"z1");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_X2");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"x2");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Y2");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"y2");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Z2");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"z2");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_Angle");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"angle");
							}
							else if(l_pNode->Type() == CSLTemplate::XSI_LOOKAT)
							{
								Parameter l_Param;
								
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_PX");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"px");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_PY");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"py");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_PZ");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"pz");

								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_IX");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"ix");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_IY");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"iy");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_IZ");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"iz");

								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_UX");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"ux");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_UY");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"uy");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_UZ");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"uz");
							}
							else if(l_pNode->Type() == CSLTemplate::XSI_MATRIX)
							{
								Parameter l_Param;
								
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_00");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_00");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_01");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_01");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_02");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_02");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_03");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_03");

								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_10");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_10");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_11");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_11");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_12");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_12");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_13");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_13");

								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_20");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_20");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_21");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_21");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_22");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_22");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_23");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_23");

								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_30");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_30");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_31");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_31");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_32");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_32");
								l_Param = l_PolymatricksAnimatedParameters.GetItem(l_NodeName + L"_33");
								if(l_Param.IsValid())	
									FTKUParameterAnimationFromXSI(l_pNode, CSLFCurve::SI_PARAMETER, l_Param, m_pAnimationPlotter, L"_33");
							}
						}
					}
				}
			}
		}

		// Get the properties for further usage
		CRefArray l_Properties = l_XSIModel.GetLocalProperties();

		// Get the visility, it's stored in the visibility.viewvis property
		// Note: this property does not existe for the Scene_Root
		if ((!in_pContext->scene().GetRoot().IsEqualTo(l_XSIModel)) && (l_pFTKModel->Visibility() != NULL))
		{			
			Parameter l_Parameter = ((ProjectItem)l_Properties.GetItem(L"visibility")).GetParameter( L"viewvis");
			// extract the visibility animation
			FTKUParameterAnimationFromXSI(l_pFTKModel->Visibility(), CSLFCurve::SI_NODEVIS, l_Parameter, m_pAnimationPlotter, L"viewvis");
		}
	}

	return status;
}

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

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

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

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

CGlobalTransformAnimationFromXSI::~CGlobalTransformAnimationFromXSI() {};

CStatus CGlobalTransformAnimationFromXSI::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 != NULL)
	{
		CSLModel *l_pFTKModel = (CSLModel *) *io_pFTKModel;
		X3DObject l_XSIModel = (X3DObject) *io_pXSIModel;

		// check if we must bail out sooner
		if(l_pFTKModel->Template() == NULL)
			return status;

		// Fill in the transform now
		if(l_pFTKModel->XSITransform() != NULL)
		{
			// extract the supported transform animation
			Parameter l_ParameterToPlot, l_ParameterProxy;
			// Fill in the transform now
			CRefArray	l_Parameters = l_XSIModel.GetKinematics().GetGlobal().GetAnimatedParameters(siAnySource);

			int loop;

			CParameterRefArray	l_LocalParameters = l_XSIModel.GetKinematics().GetLocal().GetParameters();
			for(loop = 0; loop < l_Parameters.GetCount(); loop++)
			{
				Parameter l_ParameterProxy = l_Parameters.GetItem(loop);
				CString l_ParamName = l_ParameterProxy.GetScriptName();

				l_ParameterToPlot = l_LocalParameters.GetItem(l_ParamName);
				if(l_ParameterToPlot.IsValid())
				{
					FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, l_ParamName.GetWideString());
				}
			}
		}
	}

	return status;
}

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

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

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

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

CIKtoFKFromXSI::~CIKtoFKFromXSI() {};

CStatus CIKtoFKFromXSI::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 != NULL)
	{
		X3DObject l_XSIModel = (X3DObject) *io_pXSIModel;
		CSLModel *l_pFTKModel = (CSLModel *)*io_pFTKModel;

		// check if we must bail out sooner
		if(l_pFTKModel->Template() == NULL)
			return status;

		// Get the properties for further usage
		CRefArray l_Properties = l_XSIModel.GetLocalProperties();
		CString l_XSIModelType = l_XSIModel.GetType();

		// Fill in the transform now
		if((l_pFTKModel->XSITransform() != NULL) && ((l_XSIModelType == CString(L"root")) || (l_XSIModelType == CString(L"bone"))))
		{
			// extract the supported transform animation, IK joints and roots only have their position and rotation affected by the effector
			Parameter l_ParameterToPlot;
			Parameter l_ParameterProxy;
			
			ChainElement l_XSIChainElement = (ChainElement) l_XSIModel;
			X3DObject l_XSIEffector = (X3DObject) l_XSIChainElement.GetEffector();

			// just check for any animated parameter on the effector for posx, posy and posz in global or local
			l_ParameterProxy = l_XSIEffector.GetKinematics().GetGlobal().GetParameter(CString(L"posx"));

			if(!l_ParameterProxy.IsAnimated())
			{
				l_ParameterProxy = l_XSIEffector.GetKinematics().GetGlobal().GetParameter(CString(L"posy"));
			}
			if(!l_ParameterProxy.IsAnimated())
			{
				l_ParameterProxy = l_XSIEffector.GetKinematics().GetGlobal().GetParameter(CString(L"posz"));
			}
			if(!l_ParameterProxy.IsAnimated())
			{
				l_ParameterProxy = l_XSIEffector.GetKinematics().GetLocal().GetParameter(CString(L"posx"));
			}
			if(!l_ParameterProxy.IsAnimated())
			{
				l_ParameterProxy = l_XSIEffector.GetKinematics().GetLocal().GetParameter(CString(L"posy"));
			}
			if(!l_ParameterProxy.IsAnimated())
			{
				l_ParameterProxy = l_XSIEffector.GetKinematics().GetLocal().GetParameter(CString(L"posz"));
			}

			if(l_ParameterProxy.IsAnimated())
			{
				CRefArray l_Parameters = l_XSIModel.GetKinematics().GetLocal().GetParameters();
				l_ParameterToPlot = l_Parameters.GetItem(L"posx");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"posx");
				l_ParameterToPlot = l_Parameters.GetItem(L"posy");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"posy");
				l_ParameterToPlot = l_Parameters.GetItem(L"posz");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"posz");

				l_ParameterToPlot = l_Parameters.GetItem(L"rotx");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"rotx");
				l_ParameterToPlot = l_Parameters.GetItem(L"roty");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"roty");
				l_ParameterToPlot = l_Parameters.GetItem(L"rotz");
				FTKUProxyParameterAnimationFromXSI(l_pFTKModel->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"rotz");
			}

			// now check if the effector rotation needs to be plotted too

			Property	l_ChainProperty;
			
			l_XSIModel.GetLocalProperties().Find(CString(L"chain"), l_ChainProperty);
			if(l_ChainProperty.IsValid())
			{
				Parameter	l_EffectorRotationParameter = l_ChainProperty.GetParameter(L"effori");

				// find the effector FTK object
				CSLModel *l_pFTKEffector = in_pContext->FindModelByCRef(in_pContext->ftkscene()->Root(), l_XSIEffector);
				if((l_pFTKEffector != NULL) && (l_EffectorRotationParameter.IsValid()))
				{
					l_ParameterToPlot = l_XSIEffector.GetParameter(L"rotx");
					FTKUProxyParameterAnimationFromXSI(l_pFTKEffector->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"rotx");
					l_ParameterToPlot = l_XSIEffector.GetParameter(L"roty");
					FTKUProxyParameterAnimationFromXSI(l_pFTKEffector->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"roty");
					l_ParameterToPlot = l_XSIEffector.GetParameter(L"rotz");
					FTKUProxyParameterAnimationFromXSI(l_pFTKEffector->XSITransform(), CSLFCurve::SI_PARAMETER, l_ParameterProxy, l_ParameterToPlot, m_pAnimationPlotter, L"rotz");
				}
			}
		}
	}

	return status;
}

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

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

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

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

CModelInfoAnimationToXSI::~CModelInfoAnimationToXSI() {};

CStatus CModelInfoAnimationToXSI::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 != NULL)
	{
		CSLModel *l_pFTKModel = (CSLModel *) *io_pFTKModel;
		X3DObject l_XSIModel = (X3DObject) *io_pXSIModel;

		// Get the visility, it's stored in the visibility.viewvis property
		if(l_pFTKModel->Visibility() && (l_pFTKModel->Visibility()->GetFCurveCount() > 0))  
		{			
			// find the "Visibility" property
			Property l_Property = l_XSIModel.GetLocalProperties().GetItem(L"Visibility");

			if (l_Property.IsValid())
			{
				FTKUParameterAnimationToXSI(l_pFTKModel->Visibility()->FCurves()[0], l_Property.GetParameters());
			}
		}

		// Fill in the transform now
		if((l_pFTKModel->XSITransform() != NULL) && (l_pFTKModel->XSITransform()->GetFCurveCount()))
		{
			// transform animation
			LONG loop;
			CSLFCurve** l_ppFCurve = l_pFTKModel->XSITransform()->FCurves();
			LONG l_nFCurveCount = l_pFTKModel->XSITransform()->GetFCurveCount();
			CParameterRefArray	l_Parameters = l_XSIModel.GetKinematics().GetLocal().GetParameters();

			for (loop = 0; loop < l_nFCurveCount; loop++)
			{
				FTKUParameterAnimationToXSI(l_ppFCurve[loop], l_Parameters);
			}


			// limits
			CSLXSILimit** l_pFTKLimits = l_pFTKModel->XSITransform()->GetXSILimitList();
			
			for (loop = 0; loop < l_pFTKModel->XSITransform()->GetXSILimitCount(); loop++)
			{
				l_ppFCurve = l_pFTKLimits[loop]->FCurves();
				l_nFCurveCount = l_pFTKLimits[loop]->GetFCurveCount();

				CString l_LimitParamName;
				l_LimitParamName.PutAsciiString(l_pFTKLimits[loop]->GetParameterName());

				for (LONG loop2 = 0; loop2 < l_nFCurveCount; loop2++)
				{
					CString l_FCurveParamName;
					l_FCurveParamName.PutAsciiString(l_ppFCurve[loop2]->GetFCurveTypeAsString());
                    					
					FTKUParameterAnimationToXSI(l_ppFCurve[loop2], l_Parameters, l_LimitParamName+l_FCurveParamName);
				}
			}
		}

		// polymatricks
		if(l_pFTKModel->XSITransform()  && l_pFTKModel->XSITransform()->GetPolymatricks())
		{
			int loop;
			CSLXSIPolymatricks *l_pPolymatricks = l_pFTKModel->XSITransform()->GetPolymatricks();
			CRefArray l_NestedComponents = l_XSIModel.GetKinematics().GetLocal().GetNestedObjects();
			CustomOperator op;
			CParameterRefArray l_PolymatricksParameters;

			// find all the parameters
			int count = l_NestedComponents.GetCount();
			for(loop = 0; loop < count; loop ++)
			{
				op = l_NestedComponents[loop];
				if(op.IsValid() && (op.GetType() == L"polymatricks"))
				{
					l_PolymatricksParameters = op.GetParameters();
					break;
				}
			}

			for(loop = 0; loop < l_pPolymatricks->GetTransformNodeCount(); loop++)
			{
				CSLFCurve** l_ppPolymatricksFCurves = l_pPolymatricks->GetTransformNodes()[loop]->FCurves();

				CSLTemplate *l_pTransformNode = l_pPolymatricks->GetTransformNodes()[loop];
				int l_nFCurveCount = l_pTransformNode->GetFCurveCount();
				int loop2;

				for (loop2 = 0; loop2 < l_nFCurveCount; loop2++)
				{
					// now patch the final name
					CString l_ParamName;
					l_ParamName.PutAsciiString(l_pTransformNode->GetName());
					char *l_pFcurveType = (char*) l_ppPolymatricksFCurves[loop2]->GetFCurveTypeAsString();

					if(strcmp(l_pFcurveType, "x") == 0)
					{
						l_ParamName += L"_X";
					}
					else if(strcmp(l_pFcurveType, "y") == 0)
					{
						l_ParamName += L"_Y";
					}
					else if(strcmp(l_pFcurveType, "z") == 0)
					{
						l_ParamName += L"_Z";
					}
					else if(strcmp(l_pFcurveType, "angle") == 0)
					{
						l_ParamName += L"_Angle";
					}
					else if(strcmp(l_pFcurveType, "x1") == 0)
					{
						l_ParamName += L"_X1";
					}
					else if(strcmp(l_pFcurveType, "y1") == 0)
					{
						l_ParamName += L"_Y1";
					}
					else if(strcmp(l_pFcurveType, "z1") == 0)
					{
						l_ParamName += L"_Z1";
					}
					else if(strcmp(l_pFcurveType, "x2") == 0)
					{
						l_ParamName += L"_X2";
					}
					else if(strcmp(l_pFcurveType, "y2") == 0)
					{
						l_ParamName += L"_Y2";
					}
					else if(strcmp(l_pFcurveType, "z2") == 0)
					{
						l_ParamName += L"_Z2";
					}
					else if(strcmp(l_pFcurveType, "px") == 0)
					{
						l_ParamName += L"_PX";
					}
					else if(strcmp(l_pFcurveType, "py") == 0)
					{
						l_ParamName += L"_PY";
					}
					else if(strcmp(l_pFcurveType, "pz") == 0)
					{
						l_ParamName += L"_PZ";
					}
					else if(strcmp(l_pFcurveType, "ix") == 0)
					{
						l_ParamName += L"_IX";
					}
					else if(strcmp(l_pFcurveType, "iy") == 0)
					{
						l_ParamName += L"_IY";
					}
					else if(strcmp(l_pFcurveType, "iz") == 0)
					{
						l_ParamName += L"_IZ";
					}
					else if(strcmp(l_pFcurveType, "ux") == 0)
					{
						l_ParamName += L"_UX";
					}
					else if(strcmp(l_pFcurveType, "uy") == 0)
					{
						l_ParamName += L"_UY";
					}
					else if(strcmp(l_pFcurveType, "uz") == 0)
					{
						l_ParamName += L"_UZ";
					}
					else
					{
						CString l_Suffix;
						l_Suffix.PutAsciiString(l_pFcurveType);
						l_ParamName += l_Suffix;
					}

					FTKUParameterAnimationToXSI(l_ppPolymatricksFCurves[loop2], l_PolymatricksParameters, l_ParamName);
				}
			}
		}		
	}

	return status;
}

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