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