void	SMDImporter::CreateShapeClips()
{
	if ( !m_pVTA.GetUsed() )
		return;

	XSI::Application app;

	for (int v=0;v<m_pVTA.GetUsed();v++)
	{
		XSI::Geometry geo = m_pMesh.GetActivePrimitive().GetGeometry();
		XSI::MATH::CVector3Array positions( geo.GetPoints().GetPositionArray() );

		for (int i=0;i<m_pVTA[v].m_pVertices.GetUsed();i++)
		{
			VTAVertex* p = &m_pVTA[v].m_pVertices[i];

			positions[m_lVertexMap[p->m_iIndex]] = p->m_vPosition;
//			positions[p->m_iIndex]

		}
		
		geo.GetPoints().PutPositionArray(positions);

		XSI::CValueArray args(7);
		XSI::CValue retval;
		
		args[i++]= m_pMesh;
		args[i++]= L"FacialExpression";
		args[i++]= (long)XSI::siShapeObjectReferenceMode;
		args[i++]= (long)v;
		args[i++]= (long)0;
		args[i++]= (long)0;
		args[i++]= (long)XSI::siShapeContentPrimaryShape;
		
		app.ExecuteCommand( L"StoreShapeKey", args, retval );

	}

}
void	SMDImporter::CreateGeometry()
{

	if ( !m_pTriangles.GetUsed() )
		return;

	long t;

	XSI::MATH::CTransformation xfo;
	xfo.SetRotationFromXYZAnglesValues ( -1.570796, 0.0, 0.0 );

	for (t=0;t<m_pTriangles.GetUsed();t++)
	{
		for (int v=0;v<3;v++)
		{
			XSI::MATH::CVector3 vec = XSI::MATH::MapObjectPositionToWorldSpace ( xfo, m_pTriangles[t]->m_pVertex[v].m_vPosition );
			
			long outindex;
			compress.AddVertex ( vec.GetX(), 
									vec.GetY(), 
									vec.GetZ(), 
									m_pTriangles[t]->m_pVertex[v].m_vUV.GetX(), 
									m_pTriangles[t]->m_pVertex[v].m_vUV.GetY(),
									&m_pTriangles[t]->m_pVertex[v],
									&outindex);

			m_lVertexMap.Extend(1);
			m_lVertexMap[m_lVertexMap.GetUsed()-1] = outindex;
		}
	}

	XSI::MATH::CVector3Array verts(compress.GetCount());
	long vindex = 0;
	long cnt  = compress.GetCount ();
	for (t=0;t<compress.GetCount ();t++)
	{
		uvvec vec;
		compress.GetVertex (t, &vec);
		verts[t] = XSI::MATH::CVector3 ( vec.x, vec.y, vec.z );
	}
	
	
	XSI::CLongArray indices((m_pTriangles.GetUsed() * 3) + m_pTriangles.GetUsed());

	long iindex = 0;
	

	char *l_szGlobalTexture = m_pTriangles[0]->m_szTexture;
	CSIBCArray<TriCluster>	ClusterList;
	
	for (t=0;t<m_pTriangles.GetUsed();t++)
	{
		
		XSI::MATH::CVector3 vec1 = XSI::MATH::MapObjectPositionToWorldSpace ( xfo, m_pTriangles[t]->m_pVertex[0].m_vPosition );
		XSI::MATH::CVector3 vec2 = XSI::MATH::MapObjectPositionToWorldSpace ( xfo, m_pTriangles[t]->m_pVertex[1].m_vPosition );
		XSI::MATH::CVector3 vec3 = XSI::MATH::MapObjectPositionToWorldSpace ( xfo, m_pTriangles[t]->m_pVertex[2].m_vPosition );

		long i1 = compress.GetIndex ( vec1.GetX(), vec1.GetY(), vec1.GetZ(), m_pTriangles[t]->m_pVertex[0].m_vUV.GetX(), m_pTriangles[t]->m_pVertex[0].m_vUV.GetY());
		long i2 = compress.GetIndex ( vec2.GetX(), vec2.GetY(), vec2.GetZ(), m_pTriangles[t]->m_pVertex[1].m_vUV.GetX(), m_pTriangles[t]->m_pVertex[1].m_vUV.GetY());
		long i3 = compress.GetIndex ( vec3.GetX(), vec3.GetY(), vec3.GetZ(), m_pTriangles[t]->m_pVertex[2].m_vUV.GetX(), m_pTriangles[t]->m_pVertex[2].m_vUV.GetY());

		indices[iindex] = 3;
		indices[iindex+1] = i1;
		indices[iindex+2] = i2;
		indices[iindex+3] = i3;
		iindex += 4;

		if ( strcmp ( l_szGlobalTexture, m_pTriangles[t]->m_szTexture ))
		{
			//
			// found a local material
			//

			TriCluster* cls = NULL;

			for (int c=0;c<ClusterList.GetUsed();c++)
			{
				if ( !strcmp ( ClusterList[c].m_szName, m_pTriangles[t]->m_szTexture))
				{
					cls = &ClusterList[c];
					break;
				}

			}

			if ( cls == NULL )
			{
				ClusterList.Extend(1);
				strcpy ( ClusterList[ClusterList.GetUsed()-1].m_szName, m_pTriangles[t]->m_szTexture );
				cls = &ClusterList[ClusterList.GetUsed()-1];
			}

			cls->m_indices.Add ( t );

		}

	}

	char mname[1024];
	sprintf (mname, "mesh" );
	if ( m_pMeshNode )
	{
		sprintf (mname, FixName(m_pMeshNode->m_szName));
	}

	LPWSTR l_wszModelName;
	DSA2W(&l_wszModelName,mname);

	m_pModel.AddPolygonMesh ( verts, indices, l_wszModelName, m_pMesh );


	XSI::Application	app;
	XSI::CValueArray	args(4);
	XSI::CValue			outArg;
	XSI::CStatus		st;

	args[0] = XSI::CValue( XSI::CString(L"") );
	args[1] = XSI::CValue(false);
	args[0] = XSI::CValue(m_pMesh.GetRef());
	args[1] = XSI::CValue((long)XSI::siTxtUV);
	args[2] = XSI::CValue((long)XSI::siTxtDefaultSpherical);
	args[3] = XSI::CValue(XSI::CString(L"Texture_Support"));

	app.ExecuteCommand( L"CreateTextureSupport", args, outArg );

	XSI::CValueArray	moreargs(1);
	XSI::CValueArray	moreoutargs(3);
	moreargs[0] = m_pMesh.GetRef();
	app.ExecuteCommand(L"FreezeObj",moreargs, outArg);

	XSI::Material		l_matMaterial;
	st = m_pMesh.AddMaterial(L"Phong", true, L"CubeMat", l_matMaterial);
		
	XSI::OGLTexture		l_oglTexture(l_matMaterial.GetOGLTexture());

	XSI::CString		l_szFullNameDefaultOut	= l_oglTexture.GetFullName();
	int			l_nHeightDefaultOut		= l_oglTexture.GetHeight();
	int			l_nWidthDefaultOut		= l_oglTexture.GetWidth();

	

	// Now actually add a texture, so we can test it.
	args[0] = XSI::CValue( XSI::CString(L"Image") );
	args[1] = XSI::CValue(m_pMesh.GetRef());
	args[2] = XSI::CValue((short)1);
	args[3] = XSI::CValue(false);
	st = app.ExecuteCommand( L"BlendInPresets", args, outArg );

	
	//
	// create the texture and connect
	//
	
	XSI::CValueArray	clipargs(3);
	XSI::ImageClip2 l_pClip;
	
	char l_szTextureFullname[1024];
	sprintf ( l_szTextureFullname, "%s%s", m_szDirectory, m_pTriangles[0]->m_szTexture);
	char clipname[1024];
	_splitpath ( m_pTriangles[0]->m_szTexture, NULL, NULL, clipname, NULL );

	LPWSTR l_wszClipName;
	DSA2W(&l_wszClipName,l_szTextureFullname);

	LPWSTR l_wszClipName2;
	DSA2W(&l_wszClipName2,clipname);

	
	
	clipargs[0] = XSI::CValue( XSI::CString(l_wszClipName) );
	clipargs[1] = XSI::CValue( XSI::CString(l_wszClipName2) );
	clipargs[2] = XSI::CValue(l_pClip.GetRef());
	app.ExecuteCommand( L"SICreateImageClip", clipargs, outArg );
	
	XSI::CString		l_szMaterialName	= l_matMaterial.GetFullName(); 
	XSI::CString		l_szImageNode = l_szMaterialName + L".CubeMat.ambient_blend.Image.tex";
	XSI::CString		l_szFullclipname = L"Clips." +  XSI::CString(l_wszClipName2);
	
	XSI::CValueArray	clipargs2(2);
	clipargs2[0] = XSI::CValue( XSI::CString(l_szFullclipname) );
	clipargs2[1] = XSI::CValue( XSI::CString(l_szImageNode) );
	
	app.ExecuteCommand( L"SIConnectShaderToCnxPoint", clipargs2, outArg );

	//
	// Create all clusters
	//

	XSI::Geometry geom( m_pMesh.GetActivePrimitive().GetGeometry() );
	
	for (int b=0;b<ClusterList.GetUsed();b++)
	{
		TriCluster* cls = &ClusterList[b];
		
		
		sprintf ( l_szTextureFullname, "%s%s", m_szDirectory, cls->m_szName);
		_splitpath ( cls->m_szName, NULL, NULL, clipname, NULL );
		
		DSA2W(&l_wszClipName,l_szTextureFullname);
		DSA2W(&l_wszClipName2,clipname);
		
		XSI::CLongArray array;
		XSI::Cluster polyCluster ;
		geom.AddCluster( XSI::siPolygonCluster, l_wszClipName2, cls->m_indices, polyCluster ) ;
		
		st = polyCluster.AddMaterial(L"Phong", true, L"CubeMat", l_matMaterial);
		
		XSI::OGLTexture		l_oglTexture(l_matMaterial.GetOGLTexture());
	
		// Now actually add a texture, so we can test it.
		args[0] = XSI::CValue( XSI::CString(L"Image") );
		args[1] = XSI::CValue(polyCluster.GetRef());
		args[2] = XSI::CValue((short)1);
		args[3] = XSI::CValue(false);
		st = app.ExecuteCommand( L"BlendInPresets", args, outArg );
			

		
		
		
		clipargs[0] = XSI::CValue( XSI::CString(l_wszClipName) );
		clipargs[1] = XSI::CValue( XSI::CString(l_wszClipName2) );
		clipargs[2] = XSI::CValue(l_pClip.GetRef());
		app.ExecuteCommand( L"SICreateImageClip", clipargs, outArg );
		
		l_szMaterialName	= l_matMaterial.GetFullName(); 
		l_szImageNode = l_szMaterialName + L".CubeMat.ambient_blend.Image.tex";
		l_szFullclipname = L"Clips." +  XSI::CString(l_wszClipName2);
		
		clipargs2[0] = XSI::CValue( XSI::CString(l_szFullclipname) );
		clipargs2[1] = XSI::CValue( XSI::CString(l_szImageNode) );
		
		app.ExecuteCommand( L"SIConnectShaderToCnxPoint", clipargs2, outArg );
		
	}

	
	if ( m_pMesh.IsValid () )
	{
		XSI::Geometry geom( m_pMesh.GetActivePrimitive().GetGeometry() );
		XSI::PolygonMesh mesh(m_pMesh.GetActivePrimitive().GetGeometry());

		XSI::CPointRefArray Geompoints = geom.GetPoints();
		
				
		XSI::CTriangleRefArray triangles(geom.GetTriangles());
		XSI::ClusterProperty UVWProp(m_pMesh.GetMaterial().GetCurrentUV());
		
		if ( UVWProp.IsValid() )
		{

		XSI::CClusterPropertyElementArray clusterPropertyElements = UVWProp.GetElements();
		XSI::CDoubleArray elementArray = clusterPropertyElements.GetArray();
		
		long totalUvCount = elementArray.GetCount ();
		int cc=0;
		int uvc = 0;
		for (int c=0;c<m_pTriangles.GetUsed();c++)
		{
			long l_iNumVertex = indices[cc];
			
			cc++;
			for (int i=0;i<l_iNumVertex;i++)
			{
				long l_iID = indices[cc];
				cc++;
				
				uvvec vec;
				compress.GetVertex (l_iID, &vec);

				elementArray[ uvc * 3 ] = vec.u;
				
				elementArray[ (uvc * 3) + 1] = vec.v;
				elementArray[ (uvc * 3) + 2] = 0.0f;
				
				uvc++;
			}
			
			
			
		}


			clusterPropertyElements.PutArray(elementArray);
		}
	}

}
void SMDImporter::CreateAnimationSource()
{
	XSI::ActionSource actionSource;

	float animStart = 9999;
	float animEnd = -9999;

	XSI::CString animatedObjects;

	for (int c=0;c<m_pNodes.GetUsed();c++)
	{
		SMDNode* node = m_pNodes[c];

		if ( node->m_pKeys.GetUsed() > 1 )
		{
			if ( !actionSource.IsValid() )
			{
				LPWSTR l_wszActionName;
				DSA2W(&l_wszActionName,m_szActionName);

				actionSource = m_pModel.AddActionSource( l_wszActionName );
			}

			XSI::Parameter x = node->m_x3d.GetParameters().GetItem( L"posx" );
			XSI::Parameter y = node->m_x3d.GetParameters().GetItem( L"posy" );
			XSI::Parameter z = node->m_x3d.GetParameters().GetItem( L"posz" );

			XSI::Parameter rx = node->m_x3d.GetParameters().GetItem( L"rotx" );
			XSI::Parameter ry = node->m_x3d.GetParameters().GetItem( L"roty" );
			XSI::Parameter rz = node->m_x3d.GetParameters().GetItem( L"rotz" );

			node->m_fOldX = x.GetValue();
			node->m_fOldY = y.GetValue();
			node->m_fOldZ = z.GetValue();
			node->m_fOldRX = rx.GetValue();
			node->m_fOldRY = ry.GetValue();
			node->m_fOldRZ = rz.GetValue();


			XSI::FCurve fcrvx;
			x.AddFCurve( XSI::siStandardFCurve, fcrvx	);
			XSI::FCurve fcrvy;
			y.AddFCurve( XSI::siStandardFCurve, fcrvy	);
			XSI::FCurve fcrvz;
			z.AddFCurve( XSI::siStandardFCurve, fcrvz	);
			XSI::FCurve fcrvrx;
			rx.AddFCurve( XSI::siStandardFCurve, fcrvrx	);
			XSI::FCurve fcrvry;
			ry.AddFCurve( XSI::siStandardFCurve, fcrvry	);
			XSI::FCurve fcrvrz;
			rz.AddFCurve( XSI::siStandardFCurve, fcrvrz	);
			
			XSI::CTimeArray time(node->m_pKeys.GetUsed());
			XSI::CValueArray xv(node->m_pKeys.GetUsed());
			XSI::CValueArray yv(node->m_pKeys.GetUsed());
			XSI::CValueArray zv(node->m_pKeys.GetUsed());
			
			XSI::CValueArray rxv(node->m_pKeys.GetUsed());
			XSI::CValueArray ryv(node->m_pKeys.GetUsed());
			XSI::CValueArray rzv(node->m_pKeys.GetUsed());
	
			if ( node->m_pParent ==NULL )
			{
				for (int k=0;k<node->m_pKeys.GetUsed();k++)
				{
				
					if ( node->GetKey(k)->m_fTime < animStart )
					{
						animStart = node->GetKey(k)->m_fTime;
					}

					if ( node->GetKey(k)->m_fTime > animEnd )
					{
						animEnd = node->GetKey(k)->m_fTime;
					}

					XSI::MATH::CTransformation xfo1;
					XSI::MATH::CTransformation xfo2;
					
					xfo1.SetRotationFromXYZAnglesValues ( node->GetKey(k)->m_vRotation.GetX(), node->GetKey(k)->m_vRotation.GetY(), node->GetKey(k)->m_vRotation.GetZ() );
					xfo1.SetTranslationFromValues ( node->GetKey(k)->m_vPosition.GetX(), node->GetKey(k)->m_vPosition.GetY(), node->GetKey(k)->m_vPosition.GetZ() );

					xfo2.SetRotationFromXYZAnglesValues ( -1.570796, 0.0, 0.0 );
					xfo1.MulInPlace(xfo2);

					double dx,dy,dz;
					double drx, dry, drz;

					xfo1.GetTranslationValues ( dx, dy, dz);
					xfo1.GetRotationFromXYZAnglesValues(drx, dry, drz);

					time[k] = k;
					xv[k] = dx;
					yv[k] = dy;
					zv[k] = dz;
					
					rxv[k] = drx * 57.29577951308232286465;
					ryv[k] = dry * 57.29577951308232286465;
					rzv[k] = drz * 57.29577951308232286465;

				}
				
			} else {
				
				for (int k=0;k<node->m_pKeys.GetUsed();k++)
				{
					
					if ( node->GetKey(k)->m_fTime < animStart )
					{
						animStart = node->GetKey(k)->m_fTime;
					}

					if ( node->GetKey(k)->m_fTime > animEnd )
					{
						animEnd = node->GetKey(k)->m_fTime;
					}

					time[k] = k;
					xv[k] = node->GetKey(k)->m_vPosition.GetX();
					yv[k] = node->GetKey(k)->m_vPosition.GetY();
					zv[k] = node->GetKey(k)->m_vPosition.GetZ();
					
					rxv[k] = node->GetKey(k)->m_vRotation.GetX() * 57.29577951308232286465;
					ryv[k] = node->GetKey(k)->m_vRotation.GetY() * 57.29577951308232286465;
					rzv[k] = node->GetKey(k)->m_vRotation.GetZ() * 57.29577951308232286465;
				}
			}

			fcrvx.SetKeys ( time, xv );
			fcrvy.SetKeys ( time, yv );
			fcrvz.SetKeys ( time, zv );

			fcrvrx.SetKeys ( time, rxv );
			fcrvry.SetKeys ( time, ryv );
			fcrvrz.SetKeys ( time, rzv );

			LPWSTR l_wszModelName;
			DSA2W(&l_wszModelName,FixName(node->m_szName));
			XSI::CString cname = l_wszModelName;

			actionSource.AddSourceItem ( cname + L".kine.local.posx", fcrvx, true ); 
			actionSource.AddSourceItem ( cname + L".kine.local.posy", fcrvy, true );
			actionSource.AddSourceItem ( cname + L".kine.local.posz", fcrvz, true );

			actionSource.AddSourceItem ( cname + L".kine.local.rotx", fcrvrx, true ); 
			actionSource.AddSourceItem ( cname + L".kine.local.roty", fcrvry, true );
			actionSource.AddSourceItem ( cname + L".kine.local.rotz", fcrvrz, true );
		
			// build up the string list of objects that we want to remove animation from
			if (animatedObjects.IsEmpty() == false) {
				animatedObjects += L", ";
			}
			animatedObjects += node->m_x3d.GetFullName();
		}
	}

	if ( actionSource.IsValid() )
	{
		actionSource.PutParameterValue(L"FrameStart", (double)animStart);
		actionSource.PutParameterValue(L"FrameEnd", (double)animEnd);
	}

	// remove animation on all objects that were imported
	// and animated
	if (animatedObjects.IsEmpty() == false) {
		XSI::Application app;
		XSI::CValue out;
		XSI::CValueArray args(4);

		args[0] = animatedObjects;
		args[1] = XSI::CValue();
		args[2] = (long)XSI::siBranch;
		args[3] = (long)(XSI::siFCurveSource);
		app.ExecuteCommand(L"RemoveAllAnimation", args, out);
	}
}