1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of COLLADASaxFrameworkLoader.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #include "COLLADASaxFWLStableHeaders.h"
12 #include "COLLADASaxFWLPostProcessor.h"
13 
14 #include "COLLADASaxFWLFormulasLinker.h"
15 #include "COLLADASaxFWLKinematicsSceneCreator.h"
16 
17 #include "COLLADAFWIWriter.h"
18 #include "COLLADAFWMorphController.h"
19 #include "COLLADAFWFormulas.h"
20 #include "COLLADAFWKinematicsScene.h"
21 
22 
23 namespace COLLADASaxFWL
24 {
25 
26     //------------------------------
PostProcessor(Loader * colladaLoader,SaxParserErrorHandler * saxParserErrorHandler,int objectFlags,int & parsedObjectFlags)27 	PostProcessor::PostProcessor( Loader* colladaLoader, SaxParserErrorHandler* saxParserErrorHandler, int objectFlags, int& /*[in,out]*/ parsedObjectFlags )
28 		: DocumentProcessor( colladaLoader, saxParserErrorHandler, objectFlags, parsedObjectFlags)
29 	{
30 	}
31     //------------------------------
~PostProcessor()32 	PostProcessor::~PostProcessor()
33 	{
34 	}
35 
36 	//---------------------------------
postProcess()37 	void PostProcessor::postProcess()
38 	{
39 		if ( (getObjectFlags() & Loader::ANIMATION_LIST_FLAG) != 0 )
40 		{
41 			createMissingAnimationLists();
42 		}
43 
44 		if ( (getObjectFlags() & Loader::EFFECT_FLAG) != 0 )
45 		{
46 			writeEffects();
47 		}
48 
49 		if ( (getObjectFlags() & Loader::LIGHT_FLAG) != 0 )
50 		{
51 			writeLights();
52 		}
53 
54 		if ( (getObjectFlags() & Loader::CAMERA_FLAG) != 0 )
55 		{
56 			writeCameras();
57 		}
58 
59 		if ( (getObjectFlags() & Loader::CONTROLLER_FLAG) != 0 )
60 		{
61 			createAndWriteSkinControllers();
62 			writeMorphControllers();
63 		}
64 
65 		if ( (getObjectFlags() & Loader::VISUAL_SCENES_FLAG) != 0 )
66 		{
67 			writeVisualScenes();
68 		}
69 
70 		if ( (getObjectFlags() & Loader::LIBRARY_NODES_FLAG) != 0 )
71 		{
72 			writeLibraryNodes();
73 		}
74 
75 		if ( (getObjectFlags() & Loader::ANIMATION_LIST_FLAG) != 0 )
76 		{
77 			writeAnimationLists();
78 		}
79 
80 		if ( (getObjectFlags() & Loader::FORMULA_FLAG) != 0 )
81 		{
82 			linkAndWriteFormulas();
83 		}
84 
85 		if ( (getObjectFlags() & Loader::KINEMATICS_FLAG) != 0 )
86 		{
87 			createAndWriteKinematicsScene();
88 		}
89 	}
90 
91 	//-----------------------------
writeVisualScenes()92 	void PostProcessor::writeVisualScenes()
93 	{
94 		for ( size_t i = 0, count = mVisualScenes.size(); i < count; ++i)
95 		{
96 			COLLADAFW::VisualScene *visualScene = mVisualScenes[i];
97 			writer()->writeVisualScene(visualScene);
98 		}
99 	}
100 
101 	//-----------------------------
writeLibraryNodes()102 	void PostProcessor::writeLibraryNodes()
103 	{
104 		for ( size_t i = 0, count = mLibraryNodes.size(); i < count; ++i)
105 		{
106 			COLLADAFW::LibraryNodes *libraryNodes = mLibraryNodes[i];
107 			writer()->writeLibraryNodes(libraryNodes);
108 		}
109 	}
110 
111 	//-----------------------------
writeEffects()112 	void PostProcessor::writeEffects()
113 	{
114 		for ( size_t i = 0, count = mEffects.size(); i < count; ++i)
115 		{
116 			COLLADAFW::Effect *effect = mEffects[i];
117 			writer()->writeEffect(effect);
118 		}
119 	}
120 
121 	//-----------------------------
writeLights()122 	void PostProcessor::writeLights()
123 	{
124 		for ( size_t i = 0, count = mLights.size(); i < count; ++i)
125 		{
126 			COLLADAFW::Light *light = mLights[i];
127 			writer()->writeLight(light);
128 		}
129 	}
130 
131 	//-----------------------------
writeCameras()132 	void PostProcessor::writeCameras()
133 	{
134 		for ( size_t i = 0, count = mCameras.size(); i < count; ++i)
135 		{
136 			COLLADAFW::Camera *camera = mCameras[i];
137 			writer()->writeCamera(camera);
138 		}
139 	}
140 
141 	//-----------------------------
createMissingAnimationLists()142 	void PostProcessor::createMissingAnimationLists()
143 	{
144 		Loader::AnimationSidAddressBindingList::const_iterator it = mAnimationSidAddressBindings.begin();
145 		for ( ; it != mAnimationSidAddressBindings.end(); ++it )
146 		{
147 			const Loader::AnimationSidAddressBinding& binding = *it;
148 			createMissingAnimationList( binding );
149 		}
150 	}
151 
152 	//-----------------------------
createMissingAnimationList(const Loader::AnimationSidAddressBinding & binding)153 	void PostProcessor::createMissingAnimationList( const Loader::AnimationSidAddressBinding& binding )
154 	{
155 		const SidTreeNode* sidTreeNode = resolveSid( binding.sidAddress);
156 		if ( sidTreeNode )
157 		{
158 			if ( sidTreeNode->getTargetType() == SidTreeNode::TARGETTYPECLASS_ANIMATABLE )
159 			{
160 				COLLADAFW::Animatable* animatable = sidTreeNode->getAnimatableTarget();
161 				COLLADAFW::UniqueId animationListUniqueId = animatable->getAnimationList();
162 				if ( !animationListUniqueId.isValid() )
163 				{
164 					animationListUniqueId = createUniqueId( COLLADAFW::AnimationList::ID() );
165 					animatable->setAnimationList( animationListUniqueId );
166 				}
167 				COLLADAFW::AnimationList*& animationList = getAnimationListByUniqueId(animationListUniqueId);
168 
169 				if ( !animationList )
170 				{
171 					animationList = new COLLADAFW::AnimationList( animationListUniqueId );
172 				}
173 
174 				// TODO handle this for arrays
175 				COLLADAFW::AnimationList::AnimationBinding animationBinding;
176 				animationBinding.animation = binding.animationInfo.uniqueId;
177 				animationBinding.animationClass = binding.animationInfo.animationClass;
178 
179 				switch ( binding.sidAddress.getMemberSelection() )
180 				{
181 				case SidAddress::MEMBER_SELECTION_ONE_INDEX:
182 					animationBinding.firstIndex = binding.sidAddress.getFirstIndex();
183 					animationBinding.secondIndex = 0;
184 					animationBinding.animationClass = COLLADAFW::AnimationList::ARRAY_ELEMENT_1D;
185 					break;
186 				case SidAddress::MEMBER_SELECTION_TWO_INDICES:
187 					animationBinding.firstIndex = binding.sidAddress.getFirstIndex();
188 					animationBinding.secondIndex = binding.sidAddress.getSecondIndex();
189 					animationBinding.animationClass = COLLADAFW::AnimationList::ARRAY_ELEMENT_2D;
190 					break;
191 				default:
192 					animationBinding.firstIndex = 0;
193 					animationBinding.secondIndex = 0;
194 				}
195 
196 				animationList->getAnimationBindings().append( animationBinding );
197 			}
198 		}
199 
200 	}
201 
202 	//-----------------------------
writeMorphControllers()203 	bool PostProcessor::writeMorphControllers()
204 	{
205 		const Loader::MorphControllerList& morphControllerList = mColladaLoader->getMorphControllerList();
206 		Loader::MorphControllerList::const_iterator it = morphControllerList.begin();
207 		for ( ; it != morphControllerList.end(); ++it)
208 		{
209 			const COLLADAFW::MorphController* morphController = *it;
210 			const COLLADAFW::UniqueId& morphControllerUniqueId = morphController->getUniqueId();
211 			const Loader::InstanceControllerDataList& instanceControllerDataList = getInstanceControllerDataListByControllerUniqueId(morphControllerUniqueId);
212 
213 			// Set the InstanciatedObjectId of the instance controller
214 			Loader::InstanceControllerDataList::const_iterator it = instanceControllerDataList.begin();
215 			for ( ; it != instanceControllerDataList.end(); ++it )
216 			{
217 				const Loader::InstanceControllerData& instanceControllerData = *it;
218 				instanceControllerData.instanceController->setInstanciatedObjectId( morphControllerUniqueId );
219 			}
220 
221 			if ( ! writer()->writeController( morphController ) )
222 				return false;
223 		}
224 		return true;
225 	}
226 
227 	//-----------------------------
writeAnimationLists()228 	void PostProcessor::writeAnimationLists()
229 	{
230 		Loader::UniqueIdAnimationListMap::const_iterator it = mUniqueIdAnimationListMap.begin();
231 		for ( ; it != mUniqueIdAnimationListMap.end(); ++it )
232 		{
233 			COLLADAFW::AnimationList* animationList = it->second;
234 			writer()->writeAnimationList( animationList );
235 		}
236 	}
237 
238 	//-----------------------------
linkAndWriteFormulas()239 	void PostProcessor::linkAndWriteFormulas()
240 	{
241 		COLLADAFW::Formulas* formulas = FW_NEW COLLADAFW::Formulas();
242 		COLLADAFW::FormulaArray& formulaList = formulas->getFormulas();
243 
244 		Loader::UniqueIdFormulaMap::const_iterator it = mFormulasMap.begin();
245 		for (; it != mFormulasMap.end(); ++it)
246 		{
247 			formulaList.append( it->second );
248 		}
249 
250 		FormulasLinker formulasLinker(this, formulaList);
251 		formulasLinker.link();
252 
253 		writer()->writeFormulas(formulas);
254 		FW_DELETE formulas;
255 	}
256 
257 	//-----------------------------
createAndWriteKinematicsScene()258 	void PostProcessor::createAndWriteKinematicsScene()
259 	{
260 		KinematicsSceneCreator kinematicsSceneCreator( this );
261 		COLLADAFW::KinematicsScene* kinematicsScene = kinematicsSceneCreator.createAndGetKinematicsScene();
262 		writer()->writeKinematicsScene( kinematicsScene );
263 		FW_DELETE kinematicsScene;
264 	}
265 
266 
267 
268 
269 } // namespace COLLADASaxFWL
270