1 /*
2 Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4 This file is part of COLLADAMax.
5 
6 Portions of the code are:
7 Copyright (c) 2005-2007 Feeling Software Inc.
8 Copyright (c) 2005-2007 Sony Computer Entertainment America
9 
10 Based on the 3dsMax COLLADASW Tools:
11 Copyright (c) 2005-2006 Autodesk Media Entertainment
12 
13 Licensed under the MIT Open Source License,
14 for details please see LICENSE file or the website
15 http://www.opensource.org/licenses/mit-license.php
16 */
17 
18 #include "COLLADAMaxStableHeaders.h"
19 #include "COLLADAMaxAnimationCreator.h"
20 
21 
22 #define COLORRGB_CONTROL_CLASS_ID     Class_ID(0x118f7c01,0xfeee238a)
23 #define SCALEXYZ_CONTROL_CLASS_ID     Class_ID(0x118f7c01,0xfeee238b)
24 
25 
26 namespace COLLADAMax
27 {
28 
29     //------------------------------
AnimationCreator(DocumentImporter * documentImporter)30 	AnimationCreator::AnimationCreator( DocumentImporter* documentImporter )
31 		: ImporterBase(documentImporter)
32 	{
33 	}
34 
35     //------------------------------
~AnimationCreator()36 	AnimationCreator::~AnimationCreator()
37 	{
38 	}
39 
40 	//------------------------------
createMaxFloatController(COLLADAFW::AnimationCurve * animationCurve,bool isLinear)41 	Control* AnimationCreator::createMaxFloatController( COLLADAFW::AnimationCurve* animationCurve, bool isLinear )
42 	{
43 		Class_ID controllerClassID(isLinear ? LININTERP_FLOAT_CLASS_ID : HYBRIDINTERP_FLOAT_CLASS_ID, 0);
44 		return createMaxController( CTRL_FLOAT_CLASS_ID, controllerClassID );
45 	}
46 
47 	//------------------------------
createMaxTransformationController(COLLADAFW::AnimationCurve * animationCurve)48 	Control* AnimationCreator::createMaxTransformationController( COLLADAFW::AnimationCurve* animationCurve )
49 	{
50 		Class_ID controllerClassID(PRS_CONTROL_CLASS_ID, 0);
51 		return createMaxController( CTRL_MATRIX3_CLASS_ID, controllerClassID );
52 	}
53 
54 	//------------------------------
createMaxConstantFloatController(float constantValue)55 	Control* AnimationCreator::createMaxConstantFloatController( float constantValue )
56 	{
57 		Class_ID controllerClassID(LININTERP_FLOAT_CLASS_ID, 0);
58 		Control* maxController = createMaxController( CTRL_FLOAT_CLASS_ID, controllerClassID );
59 		maxController->SetValue(0, &constantValue);
60 		return maxController;
61 	}
62 
63 	//------------------------------
createMaxColorRGBAController()64 	Control* AnimationCreator::createMaxColorRGBAController()
65 	{
66 		// Create the controller: Point4 doesn't have a linear controller.
67 		//return createMaxController( CTRL_POINT3_CLASS_ID, Class_ID (HYBRIDINTERP_COLOR_CLASS_ID, 0) );
68 		return createMaxController( CTRL_POINT3_CLASS_ID, COLORRGB_CONTROL_CLASS_ID );
69 	}
70 
71 
72 	//------------------------------
createMaxScaleController()73 	Control* AnimationCreator::createMaxScaleController()
74 	{
75 		// Create the controller: Point4 doesn't have a linear controller.
76 		return createMaxController( CTRL_SCALE_CLASS_ID, SCALEXYZ_CONTROL_CLASS_ID );
77 	}
78 
79 	//------------------------------
createMaxController(SClass_ID controllerSuperClassID,Class_ID controllerClassID)80 	Control* AnimationCreator::createMaxController( SClass_ID controllerSuperClassID, Class_ID controllerClassID )
81 	{
82 		Control* maxController = (Control*)createMaxObject( controllerSuperClassID, controllerClassID);
83 
84 		// TODO
85 		// Set the out-of-range types.
86 		//maxController->SetORT(ToORT(curve->GetPreInfinity()), ORT_BEFORE);
87 		//maxController->SetORT(ToORT(curve->GetPostInfinity()), ORT_AFTER);
88 
89 		return maxController;
90 	}
91 
92 	//------------------------------
cloneController(Control * controllerToClone,ConversionFunctorType conversionFunctor)93 	Control* AnimationCreator::cloneController( Control* controllerToClone, ConversionFunctorType conversionFunctor )
94 	{
95 		static Class_ID linearFloatClassId(LININTERP_FLOAT_CLASS_ID, 0);
96 		static Class_ID hybridFloatClassId(HYBRIDINTERP_FLOAT_CLASS_ID, 0);
97 
98 #ifdef MAX_2011_OR_NEWER
99 		DefaultRemapDir remapDir;
100 		Control* clonedController = (Control*)controllerToClone->Clone(remapDir);
101 #else
102 		Control* clonedController = (Control*)controllerToClone->Clone();
103 #endif
104 		if ( (controllerToClone->SuperClassID() == CTRL_FLOAT_CLASS_ID) && (conversionFunctor) )
105 		{
106 			//we can only scale float controller
107 			//we only need to scale, if there is a conversion functor
108 			Class_ID controllerClassID = clonedController->ClassID();
109 
110 			IKeyControl* clonedKeyController = GetKeyControlInterface( clonedController );
111 
112 			if ( controllerClassID == linearFloatClassId )
113 			{
114 				int keyCount = clonedKeyController->GetNumKeys();
115 				for ( int i = 0; i < keyCount; ++i)
116 				{
117 					ILinFloatKey key;
118 					clonedKeyController->GetKey(i, &key);
119 					key.val = (*conversionFunctor)(key.val);
120 					clonedKeyController->SetKey(i, &key);
121 				}
122 			}
123 			else if ( controllerClassID == hybridFloatClassId )
124 			{
125 				int keyCount = clonedKeyController->GetNumKeys();
126 				for ( int i = 0; i < keyCount; ++i)
127 				{
128 					IBezFloatKey key;
129 					clonedKeyController->GetKey(i, &key);
130 					key.val = (*conversionFunctor)(key.val);
131 					key.intan = (*conversionFunctor)(key.intan);
132 					key.outtan = (*conversionFunctor)(key.outtan);
133 					clonedKeyController->SetKey(i, &key);
134 				}
135 			}
136 		}
137 		return clonedController;
138 	}
139 
140 } // namespace COLLADAMax
141