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 "COLLADASaxFWLNodeLoader.h"
13 #include "COLLADASaxFWLFilePartLoader.h"
14 #include "COLLADASaxFWLGeometryMaterialIdInfo.h"
15 
16 #include "COLLADAFWVisualScene.h"
17 #include "COLLADAFWNode.h"
18 #include "COLLADAFWGeometry.h"
19 #include "COLLADAFWMaterial.h"
20 #include "COLLADAFWCamera.h"
21 #include "COLLADAFWLight.h"
22 #include "COLLADAFWSkinControllerData.h"
23 #include "COLLADAFWTranslate.h"
24 #include "COLLADAFWRotate.h"
25 #include "COLLADAFWScale.h"
26 #include "COLLADAFWSkew.h"
27 #include "COLLADAFWLookat.h"
28 #include "COLLADAFWMatrix.h"
29 
30 
31 
32 namespace COLLADASaxFWL
33 {
34 
35     //------------------------------
NodeLoader()36 	NodeLoader::NodeLoader(  )
37         : mCurrentInstanceGeometry (0)
38         , mCurrentInstanceController (0)
39         , mCurrentMaterialBinding(0)
40         , mCurrentMaterialInfo(0)
41         , mCurrentInstanceControllerData(0)
42 	{
43 	}
44 
45 	//------------------------------
~NodeLoader()46 	NodeLoader::~NodeLoader()
47 	{
48 	}
49 
50 	//------------------------------
beginNode(const node__AttributeData & attributeData)51 	bool NodeLoader::beginNode( const node__AttributeData& attributeData )
52 	{
53 		COLLADAFW::Node* newNode = new COLLADAFW::Node( getHandlingFilePartLoader()->createUniqueIdFromId(attributeData.id, COLLADAFW::Node::ID()));
54 
55 		if ( attributeData.name )
56 			newNode->setName ( (const char*)attributeData.name );
57 		else if ( attributeData.id )
58 			newNode->setName ( (const char*)attributeData.id );
59 
60 		if ( attributeData.id )
61 			newNode->setOriginalId ( (const char*)attributeData.id );
62 
63 		if ( attributeData.type == ENUM__NodeType__JOINT ) {
64 			newNode->setType ( COLLADAFW::Node::JOINT );
65 			if ( attributeData.sid )
66 				newNode->setSid( (const char*) attributeData.sid );
67 			else if ( attributeData.id )
68 				newNode->setSid( (const char*) attributeData.id );
69 		}
70 
71 		getHandlingFilePartLoader()->addToSidTree(attributeData.id, attributeData.sid, newNode);
72 
73 		if ( mNodeStack.empty() )
74 		{
75 			// we are a direct child of a container
76 			handleRootNode(newNode);
77 		}
78 		else
79 		{
80 			//we are a child of another node
81 			COLLADAFW::Node* parentNode = mNodeStack.top();
82 			parentNode->getChildNodes().append(newNode);
83 		}
84 		mNodeStack.push(newNode);
85 		return true;
86 	}
87 
88 	//------------------------------
endNode()89 	bool NodeLoader::endNode()
90 	{
91 		mNodeStack.pop();
92 		getHandlingFilePartLoader()->moveUpInSidTree();
93 		return true;
94 	}
95 
96 	//------------------------------
97 	template<class Transformationtype>
beginTransformation(const char * sid)98 	bool NodeLoader::beginTransformation( const char* sid )
99 	{
100 		mTransformationLoader.beginTransformation<Transformationtype>();
101 		getHandlingFilePartLoader()->addToSidTree( 0, sid, mTransformationLoader.getCurrentTransformation());
102 		return true;
103 	}
104 
105 
106 	//------------------------------
endTransformation()107 	bool NodeLoader::endTransformation()
108 	{
109 		COLLADABU_ASSERT(!mNodeStack.empty());
110 		mNodeStack.top()->getTransformations().append( mTransformationLoader.getCurrentTransformation());
111 		getHandlingFilePartLoader()->moveUpInSidTree();
112 		mTransformationLoader.endTransformation();
113 		return true;
114 	}
115 
116 
117 	//------------------------------
endInstanceWithMaterial()118 	bool NodeLoader::endInstanceWithMaterial()
119 	{
120 		mCurrentMaterialInfo = 0;
121 		mCurrentMaterialBindings.clear();
122 		return true;
123 	}
124 
125 	//------------------------------
begin__node(const node__AttributeData & attributeData)126 	bool NodeLoader::begin__node( const node__AttributeData& attributeData )
127 	{
128 		return beginNode(attributeData);
129 	}
130 
131 	//------------------------------
end__node()132 	bool NodeLoader::end__node()
133 	{
134 		return endNode();
135 	}
136 
137 
138 	//------------------------------
begin__translate(const translate__AttributeData & attributeData)139 	bool NodeLoader::begin__translate( const translate__AttributeData& attributeData )
140 	{
141 		return beginTransformation<COLLADAFW::Translate>( attributeData.sid );
142 	}
143 
144 	//------------------------------
end__translate()145 	bool NodeLoader::end__translate()
146 	{
147 		return endTransformation();
148 	}
149 
150 	//------------------------------
data__translate(const float * data,size_t length)151 	bool NodeLoader::data__translate( const float* data, size_t length )
152 	{
153 		return mTransformationLoader.dataTranslate( data, length);
154 	}
155 
156 	//------------------------------
begin__rotate(const rotate__AttributeData & attributeData)157 	bool NodeLoader::begin__rotate( const rotate__AttributeData& attributeData )
158 	{
159 		return beginTransformation<COLLADAFW::Rotate>( attributeData.sid );
160 	}
161 
162 	//------------------------------
end__rotate()163 	bool NodeLoader::end__rotate()
164 	{
165 		return endTransformation();
166 	}
167 
168 	//------------------------------
data__rotate(const float * data,size_t length)169 	bool NodeLoader::data__rotate( const float* data, size_t length )
170 	{
171 		return mTransformationLoader.dataRotate( data, length);
172 	}
173 
174 	//------------------------------
begin__matrix(const matrix__AttributeData & attributeData)175 	bool NodeLoader::begin__matrix( const matrix__AttributeData& attributeData )
176 	{
177 		return beginTransformation<COLLADAFW::Matrix>( attributeData.sid );
178 	}
179 
180 	//------------------------------
end__matrix()181 	bool NodeLoader::end__matrix()
182 	{
183 		return endTransformation();
184 	}
185 
186 	//------------------------------
data__matrix(const float * data,size_t length)187 	bool NodeLoader::data__matrix( const float* data, size_t length )
188 	{
189 		return mTransformationLoader.dataMatrix( data, length);
190 	}
191 
192 	//------------------------------
begin__scale(const scale__AttributeData & attributeData)193 	bool NodeLoader::begin__scale( const scale__AttributeData& attributeData )
194 	{
195 		return beginTransformation<COLLADAFW::Scale>( attributeData.sid );
196 	}
197 
198 	//------------------------------
end__scale()199 	bool NodeLoader::end__scale()
200 	{
201 		return endTransformation();
202 	}
203 
204 	//------------------------------
data__scale(const float * data,size_t length)205 	bool NodeLoader::data__scale( const float* data, size_t length )
206 	{
207 		return mTransformationLoader.dataScale( data, length);
208 	}
209 
210     //------------------------------
begin__skew(const skew__AttributeData & attributeData)211     bool NodeLoader::begin__skew ( const skew__AttributeData& attributeData )
212     {
213         return beginTransformation<COLLADAFW::Skew>( attributeData.sid );
214     }
215 
216     //------------------------------
end__skew()217     bool NodeLoader::end__skew ()
218     {
219         return endTransformation();
220     }
221 
222     //------------------------------
data__skew(const float * data,size_t length)223 	bool NodeLoader::data__skew( const float* data, size_t length )
224 	{
225 		return mTransformationLoader.dataSkew( data, length);
226     }
227 
228 	//------------------------------
begin__lookat(const lookat__AttributeData & attributeData)229 	bool NodeLoader::begin__lookat ( const lookat__AttributeData& attributeData )
230 	{
231 		return beginTransformation<COLLADAFW::Lookat>( attributeData.sid );
232 	}
233 
234 	//------------------------------
end__lookat()235 	bool NodeLoader::end__lookat ()
236 	{
237 		return endTransformation();
238 	}
239 
240 	//------------------------------
data__lookat(const float * data,size_t length)241 	bool NodeLoader::data__lookat( const float* data, size_t length )
242 	{
243 		return mTransformationLoader.dataLookat( data, length);
244 	}
245 
246     //------------------------------
begin__instance_geometry(const instance_geometry__AttributeData & attributeData)247 	bool NodeLoader::begin__instance_geometry( const instance_geometry__AttributeData& attributeData )
248 	{
249 		COLLADAFW::Node* currentNode = mNodeStack.top();
250 
251 		COLLADAFW::UniqueId instantiatedGeometryUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl( attributeData.url, COLLADAFW::Geometry::ID());
252 		mCurrentMaterialInfo = &getHandlingFilePartLoader()->getMeshMaterialIdInfo();
253 
254         COLLADAFW::UniqueId uniqueId = getHandlingFilePartLoader()->createUniqueId ( COLLADAFW::InstanceGeometry::ID() );
255 		COLLADAFW::InstanceGeometry* instanceGeometry = FW_NEW COLLADAFW::InstanceGeometry ( uniqueId, instantiatedGeometryUniqueId );
256 		mCurrentInstanceGeometry = instanceGeometry;
257 		instanceGeometry->setName(currentNode->getName());
258 		currentNode->getInstanceGeometries().append(instanceGeometry);
259 
260 		return true;
261 	}
262 
263 
264 	//------------------------------
end__instance_geometry()265 	bool NodeLoader::end__instance_geometry()
266 	{
267         FilePartLoader::copyStlContainerToArray( mCurrentMaterialBindings, mCurrentInstanceGeometry->getMaterialBindings());
268         mCurrentInstanceGeometry = 0;
269         endInstanceWithMaterial();
270 
271         return true;
272 	}
273 
274     //------------------------------
begin__bind_material()275     bool NodeLoader::begin__bind_material ()
276     {
277         return true;
278     }
279 
280     //------------------------------
end__bind_material()281     bool NodeLoader::end__bind_material ()
282     {
283         return true;
284     }
285 
286 	//------------------------------
begin__instance_material(const instance_material__AttributeData & attributeData)287 	bool NodeLoader::begin__instance_material( const instance_material__AttributeData& attributeData )
288 	{
289         if ( mCurrentInstanceGeometry || mCurrentInstanceController )
290         {
291             COLLADAFW::MaterialId materialId = attributeData.symbol ? mCurrentMaterialInfo->getMaterialId((const char*)attributeData.symbol) : 0;
292             mCurrentMaterialBinding = new COLLADAFW::MaterialBinding(materialId, getHandlingFilePartLoader()->createUniqueIdFromUrl(attributeData.target, COLLADAFW::Material::ID()));
293 
294             if ( attributeData.symbol )
295                 mCurrentMaterialBinding->setName((const char*)attributeData.symbol);
296         }
297 
298 		return true;
299 	}
300 
301 	//------------------------------
end__instance_material()302 	bool NodeLoader::end__instance_material()
303 	{
304         if ( mCurrentInstanceGeometry || mCurrentInstanceController )
305         {
306             FilePartLoader::copyStlContainerToArray( mCurrentTextureCoordinateBindings, mCurrentMaterialBinding->getTextureCoordinateBindingArray());
307             mCurrentMaterialBindings.insert(*mCurrentMaterialBinding);
308             delete mCurrentMaterialBinding;
309             mCurrentMaterialBinding = 0;
310             mCurrentTextureCoordinateBindings.clear();
311         }
312 
313         return true;
314 	}
315 
316 	//------------------------------
begin__bind_vertex_input(const bind_vertex_input__AttributeData & attributeData)317 	bool NodeLoader::begin__bind_vertex_input( const bind_vertex_input__AttributeData& attributeData )
318 	{
319         if ( mCurrentInstanceGeometry || mCurrentInstanceController )
320         {
321             COLLADAFW::TextureCoordinateBinding texCoordinateBinding;
322             texCoordinateBinding.setSetIndex ( (size_t)attributeData.input_set );
323             texCoordinateBinding.setSemantic( attributeData.semantic );
324             texCoordinateBinding.setTextureMapId ( getHandlingFilePartLoader()->getTextureMapIdBySematic( attributeData.semantic ) );
325             mCurrentTextureCoordinateBindings.insert(texCoordinateBinding);
326         }
327 		return true;
328 	}
329 
330 	//------------------------------
begin__instance_node(const instance_node__AttributeData & attributeData)331 	bool NodeLoader::begin__instance_node( const instance_node__AttributeData& attributeData )
332 	{
333 		COLLADAFW::Node* currentNode = mNodeStack.top();
334 		COLLADAFW::UniqueId instantiatedNodeUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl( attributeData.url, COLLADAFW::Node::ID() );
335 
336         COLLADAFW::UniqueId instanceNodeUniqueId = getHandlingFilePartLoader()->createUniqueId( COLLADAFW::InstanceNode::ID() );
337 		COLLADAFW::InstanceNode* instanceNode = FW_NEW COLLADAFW::InstanceNode(instanceNodeUniqueId,instantiatedNodeUniqueId);
338 		if( attributeData.name )
339 			instanceNode->setName( attributeData.name );
340 		currentNode->getInstanceNodes().append(instanceNode);
341 
342 		return true;
343 	}
344 
345     //------------------------------
end__instance_node()346     bool NodeLoader::end__instance_node ()
347     {
348         return true;
349     }
350 
351     //------------------------------
begin__instance_camera(const instance_camera__AttributeData & attributeData)352 	bool NodeLoader::begin__instance_camera( const instance_camera__AttributeData& attributeData )
353 	{
354         COLLADAFW::Node* currentNode = mNodeStack.top();
355 		COLLADAFW::UniqueId instantiatedCameraUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl( attributeData.url, COLLADAFW::Camera::ID() );
356 
357         COLLADAFW::UniqueId instanceCameraUniqueId = getHandlingFilePartLoader()->createUniqueId( COLLADAFW::InstanceCamera::ID() );
358 		COLLADAFW::InstanceCamera* instanceCamera = FW_NEW COLLADAFW::InstanceCamera(instanceCameraUniqueId, instantiatedCameraUniqueId);
359 		currentNode->getInstanceCameras().append(instanceCamera);
360 
361 		return true;
362 	}
363 
364     //------------------------------
end__instance_camera()365     bool NodeLoader::end__instance_camera ()
366     {
367         return true;
368     }
369 
370     //------------------------------
begin__instance_light(const instance_light__AttributeData & attributeData)371 	bool NodeLoader::begin__instance_light( const instance_light__AttributeData& attributeData )
372 	{
373 		COLLADAFW::Node* currentNode = mNodeStack.top();
374 		COLLADAFW::UniqueId instantiatedLightUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl( attributeData.url, COLLADAFW::Light::ID() );
375 
376         COLLADAFW::UniqueId instanceLightUniqueId = getHandlingFilePartLoader()->createUniqueId( COLLADAFW::InstanceLight::ID() );
377 		COLLADAFW::InstanceLight* instanceLight = FW_NEW COLLADAFW::InstanceLight(instanceLightUniqueId, instantiatedLightUniqueId);
378 		currentNode->getInstanceLights().append(instanceLight);
379 
380 		return true;
381 	}
382 
383     //------------------------------
end__instance_light()384     bool NodeLoader::end__instance_light ()
385     {
386         return true;
387     }
388 
389 	//------------------------------
begin__instance_controller(const instance_controller__AttributeData & attributeData)390 	bool NodeLoader::begin__instance_controller( const instance_controller__AttributeData& attributeData )
391 	{
392 		COLLADAFW::Node* currentNode = mNodeStack.top();
393 		COLLADAFW::UniqueId instantiatedControllerUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl( attributeData.url, COLLADAFW::SkinControllerData::ID() );
394 		mCurrentMaterialInfo = &getHandlingFilePartLoader()->getMeshMaterialIdInfo();
395 
396         COLLADAFW::UniqueId uniqueId = getHandlingFilePartLoader()->createUniqueId ( COLLADAFW::InstanceController::ID() );
397 		COLLADAFW::InstanceController* instanceController = FW_NEW COLLADAFW::InstanceController( uniqueId, instantiatedControllerUniqueId);
398 		mCurrentInstanceController = instanceController;
399 		currentNode->getInstanceControllers().append(instanceController);
400 
401 		Loader::InstanceControllerData instanceControllerData;
402 		instanceControllerData.instanceController = instanceController;
403 		Loader::InstanceControllerDataList& instanceControllerDataList = getHandlingFilePartLoader()->getInstanceControllerDataListByControllerUniqueId(instantiatedControllerUniqueId);
404 		instanceControllerDataList.push_back(instanceControllerData);
405 		mCurrentInstanceControllerData = &instanceControllerDataList.back();
406 
407 		return true;
408 	}
409 
410 	//------------------------------
end__instance_controller()411 	bool NodeLoader::end__instance_controller()
412 	{
413         FilePartLoader::copyStlContainerToArray( mCurrentMaterialBindings, mCurrentInstanceController->getMaterialBindings());
414         mCurrentInstanceController = 0;
415 		mCurrentInstanceControllerData = 0;
416         endInstanceWithMaterial();
417 
418 		return true;
419 	}
420 
421 	//------------------------------
data__skeleton(COLLADABU::URI value)422 	bool NodeLoader::data__skeleton( COLLADABU::URI value )
423 	{
424 		if (mCurrentInstanceControllerData)
425 		{
426 			mCurrentInstanceControllerData->skeletonRoots.push_back( value );
427             mCurrentInstanceControllerData->instanceController->skeletons().push_back( value );
428 		}
429 
430 		return true;
431 	}
432 
433 } // namespace COLLADASaxFWL
434