1 /* 2 Copyright (c) 2008-2009 NetAllied Systems GmbH 3 4 This file is part of DAE2MA. 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 Copyright (c) 2004-2005 Alias Systems Corp. 10 11 Licensed under the MIT Open Source License, 12 for details please see LICENSE file or the website 13 http://www.opensource.org/licenses/mit-license.php 14 */ 15 16 #ifndef __DAE2MA_DOCUMENT_IMPORTER_H__ 17 #define __DAE2MA_DOCUMENT_IMPORTER_H__ 18 19 #include "DAE2MAStableHeaders.h" 20 #include "DAE2MAPrerequisites.h" 21 #include "DAE2MANode.h" 22 #include "DAE2MASaxErrorHandler.h" 23 #include "DAE2MAExtraDataCallbackHandler.h" 24 25 #include "COLLADAFWIWriter.h" 26 #include "COLLADAFWFileInfo.h" 27 #include "COLLADAFWInstanceVisualScene.h" 28 #include "COLLADAFWFormula.h" 29 #include "COLLADAFWEffect.h" 30 31 #include "COLLADASaxFWLLoader.h" 32 33 #include "MayaDMMesh.h" 34 35 #include "COLLADABUIDList.h" 36 37 #include <set> 38 39 40 namespace DAE2MA 41 { 42 class NodeImporter; 43 class VisualSceneImporter; 44 class GeometryImporter; 45 class MaterialImporter; 46 class EffectImporter; 47 class CameraImporter; 48 class LightImporter; 49 class ImageImporter; 50 class AnimationImporter; 51 class ControllerImporter; 52 53 54 /** 55 * The main importer class. This class imports all data of the scene. 56 * 57 * We have to parse the document always for two times. Once to get the used visual scene, 58 * which is always in the current scene. This element is always at the end of a collada 59 * document, why we have to parse always twice. The order to handle the parsed data: 60 * 61 * 1.) First parsing: 62 * 1.1) Import asset 63 * 1.2) Copy some of the elements, so we don't need to parse once more again. 64 * Following elements should be copied, the order doesn't matter: 65 * - Copy visual scene 66 * - Copy library nodes 67 * - Copy controllers 68 * - Copy materials 69 * - Copy images 70 * - Copy animation lists 71 * 1.3) Read scene (is always at the end of a collada document) 72 * 73 * 2.) Between first and second parsing: 74 * 2.1) Import referenced visual scene 75 * 2.3) Import referenced library nodes 76 * 2.4) Import node instances 77 * 2.5) Import morph controllers 78 * 2.6) Import (not just the referenced) materials 79 * 2.7) Import (not just the referenced) effects (now we know the image list...) 80 * 2.8) Import referenced images 81 * 2.9) Detect scale animations 82 * 83 * 3.) Second parsing: 84 * 3.1) Import all data directly, the order doesn't matter: 85 * - Import referenced geometries 86 * - Import (not just the referenced) cameras 87 * - Import (not just the referenced) lights 88 * - Import (not just the referenced) animations (in depend on scale animations) 89 * - Import referenced skinControllerDatas 90 * 4.) After second parsing: 91 * 4.1) Make all connections, the order doesn't matter: 92 * - controller 93 * - materials / effects 94 * - lights 95 * - effects 96 * - geometries 97 * - animations 98 */ 99 class DocumentImporter : public COLLADAFW::IWriter 100 { 101 102 private: 103 104 /** This names are reserved. Maya nodes can't have this names! */ 105 static const String RESERVED_NAMES[]; 106 static const size_t NUM_RESERVED_NAMES; 107 108 /** The Buffersize for the document to write. */ 109 static const int BUFFERSIZE; 110 111 /** 112 * An enum for the steps to do. See main documentation. 113 */ 114 enum ParseSteps 115 { 116 NO_PARSING = 0, 117 FIRST_PARSING, 118 IMPORT_ASSET, 119 COPY_ELEMENTS, // no order: scene, visual scene, library nodes, materials, animationLists, writeController 120 ELEMENTS_COPIED, 121 VISUAL_SCENE_IMPORTED, 122 SECOND_PARSING, 123 ANIMATIONS_IMPORTED, 124 GEOMETRY_IMPORTED, 125 MAKE_CONNECTIONS 126 }; 127 128 private: 129 130 /** The maya version of the current maya document. */ 131 const char* mMayaVersion; 132 133 /** The current parsing step. */ 134 ParseSteps mParseStep; 135 136 /** The sax loader. */ 137 // COLLADASaxFWL::Loader mSaxLoader; 138 139 /** The callback handler to parse the extra data elements. */ 140 ExtraDataCallbackHandler mMayaIdCallbackHandler; 141 142 /** The URI of the visual scene to use. */ 143 COLLADAFW::InstanceVisualScene* mInstanceVisualScene; 144 145 /** A copy of the framework's visual scene elements. */ 146 std::vector<COLLADAFW::VisualScene*> mVisualScenesList; 147 148 /** A copy of the framework's library nodes elements. */ 149 std::vector<COLLADAFW::LibraryNodes*> mLibraryNodesList; 150 151 /** A copy of the framework's library materials elements. */ 152 std::vector<COLLADAFW::Material*> mMaterialsList; 153 154 /** A copy of the framework's library effects elements. */ 155 std::vector<COLLADAFW::Effect*> mEffectsList; 156 157 /** A copy of the framework's animation list elements. */ 158 std::vector<COLLADAFW::AnimationList*> mAnimationListsList; 159 160 /** The buffer for fprintf. */ 161 char *mBuffer; // 2MB Puffer!! 162 163 /** The name of the collada file. */ 164 String mColladaFileName; 165 166 /** The name of the current maya ascii file. */ 167 COLLADABU::URI mMayaAsciiFileURI; 168 169 /** The current maya ascii file to import the data. */ 170 FILE* mFile; 171 172 /** The LC_NUMERIC locale that was set before the Streamwriter was instantiated. */ 173 String mLocale; 174 175 /** Tolerance value in double to compare values. */ 176 double mDigitTolerance; 177 178 /** 179 * How many real-world meters in one distance unit as a floating-point number. 180 * For example, 1.0 for the name "meter"; 1000 for the name "kilometer"; 181 * 0.3048 for the name "foot". 182 */ 183 double mLinearUnitConvertFactor; 184 COLLADAFW::FileInfo::UpAxisType mUpAxisType; 185 186 /** 187 * This unit convert factor calculates always the centimeter unit, because this is 188 * the maya internal unit. 189 * This is need for conversion of the skin controller bind shape and geometry (?) matrix 190 * translate values conversion, because maya doesn't calculate the right values on linear 191 * unit switching. 192 */ 193 double mLinearUnitMayaBindShapeBugConvertFactor; 194 195 /** Pointer to the visual scene importer. */ 196 VisualSceneImporter* mVisualSceneImporter; 197 198 /** Pointer to the node importer. 199 Used to store the mapping between unique node ids and the framework nodes. */ 200 NodeImporter* mNodeImporter; 201 202 /** Pointer to the geometry importer. */ 203 GeometryImporter* mGeometryImporter; 204 205 /** Pointer to the geometry importer. */ 206 MaterialImporter* mMaterialImporter; 207 208 /** Pointer to the geometry importer. */ 209 EffectImporter* mEffectImporter; 210 211 /** Pointer to the camera importer. */ 212 CameraImporter* mCameraImporter; 213 214 /** Pointer to the light importer. */ 215 LightImporter* mLightImporter; 216 217 /** Pointer to the image importer. */ 218 ImageImporter* mImageImporter; 219 220 /** Pointer to the animation importer. */ 221 AnimationImporter* mAnimationImporter; 222 223 /** Pointer to the controller importer. */ 224 ControllerImporter* mControllerImporter; 225 226 /** The variable tells, how many times the document is read. */ 227 size_t mNumDocumentParses; 228 229 /** The error handler for the sax parser. */ 230 SaxErrorHandler mSaxParserErrorHandler; 231 232 /** 233 * The list of all unique ids of maya nodes (dag nodes and depend nodes). 234 * A list of names which are either used up to multiple times for dag nodes in the scene 235 * graph or just once for any other maya depend object (materials, shading groups, material 236 * infos, animations, blend shapes, skin clusters, textures ). Used to avoid dublicate names. 237 */ 238 COLLADABU::IDList mGlobalNodeIdList; 239 240 /** 241 * The list of unique ids of maya depend nodes. Depend nodes are: materials, shading groups, 242 * material infos, animations, blend shapes, skin clusters, textures. Used to avoid dublicate 243 * names. 244 */ 245 COLLADABU::IDList mDependNodeIdList; 246 247 /** 248 * A list of names which are used up to multiple times for dag nodes in the scene graph. 249 * Used to avoid dublicate names. 250 */ 251 std::set<String> mDagNodeIdSet; 252 253 public: 254 255 /** Constructor. */ 256 DocumentImporter ( 257 const String& importFileName, 258 const String& mayaAsciiFileName, 259 const char* mayaVersion = MAYA_VERSION_DEFAULT ); 260 261 /** Destructor. */ 262 virtual ~DocumentImporter (); 263 getMayaVersion()264 const char* getMayaVersion() { return mMayaVersion; } 265 266 /** Imports the current scene. */ 267 void importCurrentScene (); 268 269 /** The callback handler to parse the extra data elements. */ getMayaIdCallbackHandler()270 const ExtraDataCallbackHandler& getMayaIdCallbackHandler () const { return mMayaIdCallbackHandler; } 271 272 /** The current maya ascii file to import the data. */ getFile()273 FILE* getFile () const { return mFile; } 274 275 /** Returns the tolerance value for double value comparison. */ getTolerance()276 const double getTolerance () const { return mDigitTolerance; } 277 278 /** Pointer to the visual scene importer. */ getVisualSceneImporter()279 VisualSceneImporter* getVisualSceneImporter () { return mVisualSceneImporter; } getVisualSceneImporter()280 const VisualSceneImporter* getVisualSceneImporter () const { return mVisualSceneImporter; } 281 282 /** Pointer to the node importer. 283 Used to store the mapping between unique node ids and the framework nodes. */ getNodeImporter()284 NodeImporter* getNodeImporter () { return mNodeImporter; } getNodeImporter()285 const NodeImporter* getNodeImporter () const { return mNodeImporter; } 286 287 /** Pointer to the geometry importer. */ getGeometryImporter()288 GeometryImporter* getGeometryImporter () { return mGeometryImporter; } getGeometryImporter()289 const GeometryImporter* getGeometryImporter () const { return mGeometryImporter; } 290 291 /** Pointer to the geometry importer. */ getMaterialImporter()292 MaterialImporter* getMaterialImporter () { return mMaterialImporter; } getMaterialImporter()293 const MaterialImporter* getMaterialImporter () const { return mMaterialImporter; } 294 295 /** Pointer to the geometry importer. */ getEffectImporter()296 EffectImporter* getEffectImporter () { return mEffectImporter; } getEffectImporter()297 const EffectImporter* getEffectImporter () const { return mEffectImporter; } 298 299 /** Pointer to the camera importer. */ getCameraImporter()300 CameraImporter* getCameraImporter () { return mCameraImporter; } getCameraImporter()301 const CameraImporter* getCameraImporter () const { return mCameraImporter; } 302 303 /** Pointer to the light importer. */ getLightImporter()304 LightImporter* getLightImporter () { return mLightImporter; } getLightImporter()305 const LightImporter* getLightImporter () const { return mLightImporter; } 306 307 /** Pointer to the image importer. */ getImageImporter()308 ImageImporter* getImageImporter () { return mImageImporter; } getImageImporter()309 const ImageImporter* getImageImporter () const { return mImageImporter; } 310 311 /** Pointer to the animation importer. */ getAnimationImporter()312 AnimationImporter* getAnimationImporter () { return mAnimationImporter; } getAnimationImporter()313 const AnimationImporter* getAnimationImporter () const { return mAnimationImporter; } 314 315 /** Pointer to the controller importer. */ getControllerImporter()316 ControllerImporter* getControllerImporter () { return mControllerImporter; } getControllerImporter()317 const ControllerImporter* getControllerImporter () const { return mControllerImporter; } 318 319 /** This method will be called if an error in the loading process occurred and the loader 320 cannot continue to to load. The writer should undo all operations that have been performed. 321 @param errorMessage A message containing informations about the error that occurred. 322 */ 323 virtual void cancel ( const String& errorMessage ); 324 325 /** This is the method called. The writer hast to prepare to receive data.*/ 326 virtual void start(); 327 328 /** Initializes the document importer.*/ 329 void initialize(); 330 331 /** 332 * This method is called after the last write method. No other methods will be called after this. 333 * After the read of the collada document, the connections can be written into the maya file. 334 */ 335 virtual void finish (); 336 337 /** 338 * Makes all the necessary connections. 339 */ 340 void writeConnections (); 341 342 /** When this method is called, the writer must write the global document asset. 343 @return The writer should return true, if writing succeeded, false otherwise.*/ 344 virtual bool writeGlobalAsset ( const COLLADAFW::FileInfo* asset ); 345 346 /** 347 * How many real-world meters in one distance unit as a floating-point number. 348 * For example, 1.0 for the name "meter"; 1000 for the name "kilometer"; 349 * 0.3048 for the name "foot". 350 */ getLinearUnitConvertFactor()351 const double getLinearUnitConvertFactor () const { return mLinearUnitConvertFactor; } 352 353 /** 354 * This unit convert factor calculates always the centimeter unit, because this is 355 * the maya internal unit. 356 * This is need for conversion of the skin controller bind shape and geometry (?) matrix 357 * translate values conversion, because maya doesn't calculate the right values on linear 358 * unit switching. 359 */ getLinearUnitMayaBindShapeBugConvertFactor()360 const double getLinearUnitMayaBindShapeBugConvertFactor () const { return mLinearUnitMayaBindShapeBugConvertFactor; } 361 362 /** When this method is called, the writer must write the scene. 363 @return The writer should return true, if writing succeeded, false otherwise. 364 <instance_physics_scene> 0 or more 365 <instance_visual_scene> 0 or 1 366 <instance_kinematics_scene> 0 or 1 367 */ 368 virtual bool writeScene ( const COLLADAFW::Scene* scene ); 369 370 /** When this method is called, the writer must write the entire visual scene. 371 @return The writer should return true, if writing succeeded, false otherwise.*/ 372 virtual bool writeVisualScene ( const COLLADAFW::VisualScene* visualScene ); 373 374 /** When this method is called, the writer must write the geometry. 375 @return The writer should return true, if writing succeeded, false otherwise.*/ 376 virtual bool writeGeometry ( const COLLADAFW::Geometry* geometry ); 377 378 /** When this method is called, the writer must handle all nodes contained in the 379 library nodes. 380 @return The writer should return true, if writing succeeded, false otherwise.*/ 381 virtual bool writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes ); 382 383 /** When this method is called, the writer must write the material. 384 @return The writer should return true, if writing succeeded, false otherwise.*/ 385 virtual bool writeMaterial ( const COLLADAFW::Material* material ); 386 387 /** When this method is called, the writer must write the effect. 388 @return The writer should return true, if writing succeeded, false otherwise.*/ 389 virtual bool writeEffect ( const COLLADAFW::Effect* effect ); 390 391 /** When this method is called, the writer must write the camera. 392 @return The writer should return true, if writing succeeded, false otherwise.*/ 393 virtual bool writeCamera( const COLLADAFW::Camera* camera ); 394 395 /** When this method is called, the writer must write the light. 396 @return The writer should return true, if writing succeeded, false otherwise.*/ 397 virtual bool writeLight( const COLLADAFW::Light* camera ); 398 399 /** When this method is called, the writer must write the image. 400 @return The writer should return true, if writing succeeded, false otherwise.*/ 401 virtual bool writeImage( const COLLADAFW::Image* image ); 402 403 /** When this method is called, the writer must write the Animation. 404 @return The writer should return true, if writing succeeded, false otherwise.*/ 405 virtual bool writeAnimation( const COLLADAFW::Animation* animation ); 406 407 /** When this method is called, the writer must write the AnimationList. 408 @return The writer should return true, if writing succeeded, false otherwise.*/ 409 virtual bool writeAnimationList( const COLLADAFW::AnimationList* animationList ); 410 411 /** When this method is called, the writer must write the AnimationClip. 412 @return The writer should return true, of writing succeeded, false otherwise.*/ writeAnimationClip(const COLLADAFW::AnimationClip * animationClip)413 virtual bool writeAnimationClip( const COLLADAFW::AnimationClip* animationClip ) { return true; } 414 415 /** When this method is called, the writer must write the skin controller data. 416 @return The writer should return true, if writing succeeded, false otherwise.*/ 417 virtual bool writeSkinControllerData( const COLLADAFW::SkinControllerData* skinControllerData ); 418 419 /** When this method is called, the writer must write the controller. 420 @return The writer should return true, if writing succeeded, false otherwise.*/ 421 virtual bool writeController( const COLLADAFW::Controller* Controller ); 422 423 /** When this method is called, the writer must write the formulas. All the formulas of the entire 424 COLLADA file are contained in @a formulas. 425 @return The writer should return true, if writing succeeded, false otherwise.*/ 426 virtual bool writeFormulas( const COLLADAFW::Formulas* formulas ); 427 428 virtual bool writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene ); 429 430 /** 431 * Replace offending characters by some that are supported within maya. 432 */ 433 static String frameworkNameToMayaName ( const String& name ); 434 435 /** 436 * The list of all unique ids of maya nodes (dag nodes and depend nodes). 437 * A list of names which are either used up to multiple times for dag nodes in the scene 438 * graph or just once for any other maya depend object (materials, shading groups, material 439 * infos, animations, blend shapes, skin clusters, textures ). Used to avoid dublicate names. 440 */ 441 String addGlobalNodeId ( 442 const String& newId, 443 bool returnConverted = true, 444 bool alwaysAddNumberSuffix = false ); 445 446 /** 447 * The list of unique ids of maya depend nodes. Depend nodes are: materials, shading groups, 448 * material infos, animations, blend shapes, skin clusters, textures. Used to avoid dublicate 449 * names. 450 */ 451 String addDependNodeId ( 452 const String& newId, 453 bool returnConverted = true, 454 bool alwaysAddNumberSuffix = false ); 455 456 /** 457 * The list of unique ids of maya depend nodes. Depend nodes are: materials, shading groups, 458 * material infos, animations, blend shapes, skin clusters, textures. Used to avoid dublicate 459 * names. 460 */ 461 bool containsDependNodeId ( const String& id ); 462 463 /** 464 * A list of names which are used up to multiple times for dag nodes in the scene graph. 465 * Used to avoid duplicate names. 466 */ 467 void addDagNodeId ( const String& newId ); 468 469 /** 470 * A list of names which are used up to multiple times for dag nodes in the scene graph. 471 * Used to avoid duplicate names. 472 */ 473 bool containsDagNodeId ( const String& id ); 474 475 /** 476 * Returns the framework material with the given id. 477 */ 478 const COLLADAFW::Material* getMaterialById ( const COLLADAFW::UniqueId& materialId ); 479 480 private: 481 482 /** Reads the collada document. */ 483 void readColladaDocument (); 484 485 /** Create the maya ascii file (where with which name???) */ 486 bool createMayaAsciiFile (); 487 void closeMayaAsciiFile (); 488 489 /** 490 * Returns the name of the current collada file to export. 491 * @return const String& Name of the current collada file 492 */ 493 const String& getColladaFilename () const; 494 495 /** 496 * After we have imported the geometries, we can create the necessary uv-choosers. 497 * We can't create them earlier, about we need to know, if the geometry has more than 498 * one uv-set (texture coordinates). 499 */ 500 void createUvChoosers (); 501 502 /** Convert the value to a valid maya unit value in depend on the current precision. */ 503 double toMayaUnitValue ( double unitValue ); 504 505 /** Maps unique ids of nodes to the frame word node itself. */ 506 void importNodes (); 507 508 /** 509 * Import the data of the visual scene. 510 */ 511 void importVisualScene (); 512 513 /** 514 * First import materials, then effects and after this images. 515 * The order of the import is relevant, about we have to know which effects are used 516 * by this material. After the import of the effects, we know which images we need. 517 * We have to import this before we write the animations in the second parsing, about 518 * to know the animated effects. 519 */ 520 void importMaterials (); 521 522 /** 523 * First import materials, then effects and after this images. 524 * The order of the import is relevant, about we have to know which effects are used 525 * by this material. After the import of the effects, we know which images we need. 526 * We have to import this before we write the animations in the second parsing, about 527 * to know the animated effects. 528 */ 529 void importEffects (); 530 531 /** 532 * First import materials, then effects and after this images. 533 * The order of the import is relevant, about we have to know which effects are used 534 * by this material. After the import of the effects, we know which images we need. 535 * We have to import this before we write the animations in the second parsing, about 536 * to know the animated effects. 537 */ 538 void importImages (); 539 540 /** 541 * Imports the morph controllers. 542 */ 543 void importMorphControllers (); 544 545 /** 546 * After we have imported the visual scene, we can detect the scale animations. 547 * 548 * We need the information about scale animations to adjust the physical dimension of a 549 * scale animation. To get this info, we have to get the transformations of the transform 550 * animations and have to check for scale animations. Scale animations must have a physical 551 * dimension number (double) instead of length (distance)! 552 * The transformations exist after the first parsing, after the visual scene is imported. 553 * So we have to store the animation lists in the first parsing. After the visual scene 554 * import we can iterate over the animation lists and determine the scale animations. After 555 * we know the scale animations, we can import the animations with the correct physical 556 * dimension. After we have imported all animations, we can write the animation connections 557 * from the stored animation lists. 558 */ 559 void detectScaleAnimations (); 560 561 void importAnimationLists (); 562 563 /** 564 * Get the minimum and the maximum time values of the animations to get the start 565 * time and the end time of the animation. This times we have to set as the 566 * "playbackOptions" in the "sceneConfigurationScriptNode". 567 */ 568 void importPlaybackOptions (); 569 570 /** 571 * The list of all unique ids of maya nodes (dag nodes and depend nodes). 572 * A list of names which are either used up to multiple times for dag nodes in the scene 573 * graph or just once for any other maya depend object (materials, shading groups, material 574 * infos, animations, blend shapes, skin clusters, textures ). Used to avoid duplicate names. 575 */ 576 bool containsGlobalNodeId ( const String& id ); 577 578 /** 579 * Recursive call to find the node with the given id in the given node list. 580 */ 581 const COLLADAFW::Node* findNode ( 582 const COLLADAFW::UniqueId& nodeId, 583 const COLLADAFW::NodePointerArray &nodes ); 584 585 /** Imports the current scene. */ 586 void exportScene(); 587 588 /** Parse the current collada file and creates the parsing libraries: 589 we want access to the libraries during import/export time. */ 590 void createLibraries(); 591 592 /** Releases the import/export libraries */ 593 void releaseLibraries(); 594 595 }; 596 } 597 598 #endif // __DAE2MA_DOCUMENT_IMPORTER_H__