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__