Sirikata
libmesh/plugins/collada/ColladaDocumentImporter.hpp
Go to the documentation of this file.
00001 /*  Sirikata libproxyobject -- COLLADA Document Importer
00002  *  ColladaDocumentImporter.hpp
00003  *
00004  *  Copyright (c) 2009, Mark C. Barnes
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_COLLADA_DOCUMENT_IMPORTER_
00034 #define _SIRIKATA_COLLADA_DOCUMENT_IMPORTER_
00035 
00036 #include "ColladaDocument.hpp"
00037 
00038 #include "COLLADABUhash_map.h"
00039 #include "COLLADAFWIWriter.h"
00040 #include "COLLADAFWGeometry.h"
00041 #include "COLLADAFWMesh.h"
00042 #include "COLLADAFWImage.h"
00043 #include "COLLADAFWMaterial.h"
00044 #include "COLLADAFWMaterialBinding.h"
00045 #include "COLLADAFWFileInfo.h"
00046 #include "COLLADAFWNode.h"
00047 #include "COLLADAFWColorOrTexture.h"
00048 #include "COLLADAFWEffect.h"
00049 #include "COLLADAFWEffectCommon.h"
00050 #include "COLLADAFWSkinControllerData.h"
00051 #include "COLLADAFWSkinController.h"
00052 #include "COLLADAFWAnimationList.h"
00053 #include <sirikata/mesh/Meshdata.hpp>
00054 
00056 
00057 namespace Sirikata {
00058 
00059 namespace Transfer {
00060 
00061 class URI;
00062 
00063 }
00064 
00065 namespace Models {
00066 
00068 
00073 class SIRIKATA_PLUGIN_EXPORT ColladaDocumentImporter
00074     :   public COLLADAFW::IWriter
00075 {
00076     public:
00077     explicit ColladaDocumentImporter ( Transfer::URI const& uri, const SHA256& hash );
00078     explicit ColladaDocumentImporter ( std::vector<Transfer::URI> uriList );
00079 
00080         ~ColladaDocumentImporter ();
00081 
00082         ColladaDocumentPtr getDocument () const;
00083 
00084 
00085         String documentURI() const;
00086 
00087         Mesh::MeshdataPtr getMeshdata() {
00088           return mMesh;
00089         }
00090 
00091     protected:
00092 
00093     private:
00094         ColladaDocumentImporter ( ColladaDocumentImporter const& ); // unimplemented
00095         ColladaDocumentImporter& operator = ( ColladaDocumentImporter const& ); // unimplemented
00096 
00097         void postProcess ();
00098 
00099         // Translates scene graph nodes into our runtime format. Part
00100         // of post processing step.
00101         void translateNodes();
00102         // Translates skin controllers into our runtime format and resolves
00103         // their various dependencies (jointes, meshes). Part of post processing
00104         // step.
00105         void translateSkinControllers();
00106 
00107         ColladaDocumentPtr mDocument;
00108 
00109         enum State { CANCELLED = -1, IDLE, STARTED, FINISHED };
00110         State mState;
00111 
00112         //returns false if everything specified was black in case all colors are black and a black rather than default material should be returned
00113         void makeTexture (Mesh::MaterialEffectInfo::Texture::Affecting type,
00114                           const COLLADAFW::MaterialBinding * binding,
00115                           const COLLADAFW::EffectCommon * effect,
00116                           const COLLADAFW::ColorOrTexture & color,
00117                           size_t geom_index,
00118                           size_t prim_index,
00119                           Mesh::MaterialEffectInfo::TextureList&output);
00120         size_t finishEffect(const COLLADAFW::MaterialBinding *binding, size_t geom_index, size_t prim_index);
00122     // interface from COLLADAFW::IWriter
00123     public:
00124         virtual void cancel ( COLLADAFW::String const& errorMessage );
00125         virtual void start ();
00126         virtual void finish ();
00127         virtual bool writeGlobalAsset ( COLLADAFW::FileInfo const* asset );
00128         virtual bool writeScene ( COLLADAFW::Scene const* scene );
00129         virtual bool writeVisualScene ( COLLADAFW::VisualScene const* visualScene );
00130         virtual bool writeLibraryNodes ( COLLADAFW::LibraryNodes const* libraryNodes );
00131         virtual bool writeGeometry ( COLLADAFW::Geometry const* geometry );
00132         virtual bool writeMaterial ( COLLADAFW::Material const* material );
00133         virtual bool writeEffect ( COLLADAFW::Effect const* effect );
00134         virtual bool writeCamera ( COLLADAFW::Camera const* camera );
00135         virtual bool writeImage ( COLLADAFW::Image const* image );
00136         virtual bool writeLight ( COLLADAFW::Light const* light );
00137         virtual bool writeAnimation ( COLLADAFW::Animation const* animation );
00138         virtual bool writeAnimationList ( COLLADAFW::AnimationList const* animationList );
00139         virtual bool writeSkinControllerData ( COLLADAFW::SkinControllerData const* skinControllerData );
00140         virtual bool writeController ( COLLADAFW::Controller const* controller );
00141         virtual bool writeFormulas ( COLLADAFW::Formulas const* formulas );
00142         virtual bool writeKinematicsScene ( COLLADAFW::KinematicsScene const* kinematicsScene );
00143 
00144     protected:
00145 
00146         Matrix4x4f mChangeUp;
00147         Matrix4x4f mUnitScale; // For adjusting units to meters
00148 
00149         // The following keep track of the components of the scene, as
00150         // identified by COLLADAFW::UniqueIds.  We use these to chase indirect
00151         // references within the file.
00152         COLLADAFW::UniqueId mVisualSceneId; // Currently support loading only a
00153                                             // single scene
00154 
00155         typedef std::map<COLLADAFW::UniqueId, const COLLADAFW::VisualScene*> VisualSceneMap;
00156         VisualSceneMap mVisualScenes;
00157 
00158         typedef std::map<COLLADAFW::UniqueId, const COLLADAFW::Node*> NodeMap;
00159         NodeMap mLibraryNodes;
00160         class UniqueIdHash{public:
00161                 size_t operator () (const COLLADAFW::UniqueId&id) const {
00162                     return std::tr1::hash<std::string>()(std::string(id.toAscii()));
00163                 }
00164         };
00165         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, size_t, UniqueIdHash> IndicesMap;
00166         typedef std::tr1::unordered_multimap<COLLADAFW::UniqueId, size_t, UniqueIdHash> IndicesMultimap;
00167         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, COLLADAFW::UniqueId, UniqueIdHash> IdMap;
00168 
00169         struct OCSkinControllerData {
00170             Matrix4x4f bindShapeMatrix;
00172             std::vector<unsigned int> weightStartIndices;
00173             std::vector<float> weights;
00174             std::vector<unsigned int>jointIndices;
00175             std::vector<Matrix4x4f> inverseBindMatrices;
00176         };
00177         struct OCSkinController {
00178             COLLADAFW::UniqueId source; // The mesh this skin applies to, should
00179                                         // be able to get SubMeshGeometry based
00180                                         // on this
00181             COLLADAFW::UniqueId skinControllerData;
00182             std::vector<COLLADAFW::UniqueId> joints;
00183         };
00184         typedef std::tr1::unordered_map<COLLADAFW::UniqueId,OCSkinControllerData, UniqueIdHash> OCSkinControllerDataMap;
00185         typedef std::tr1::unordered_map<COLLADAFW::UniqueId,OCSkinController, UniqueIdHash> OCSkinControllerMap;
00186         OCSkinControllerDataMap mSkinControllerData;
00187         OCSkinControllerMap mSkinControllers;
00188 
00190         struct AnimationCurve {
00191             String name;
00192             std::vector<float> inputs;
00193             std::vector<float> outputs;
00194         };
00195         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, AnimationCurve, UniqueIdHash> AnimationCurveMap;
00196         AnimationCurveMap mAnimationCurves;
00197         std::set<String> mAnimationNames;
00198         bool mOnlyHasDefaultAnimation;
00199 
00205         typedef std::vector<COLLADAFW::AnimationList::AnimationBinding> AnimationBindings;
00206         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, AnimationBindings, UniqueIdHash> AnimationBindingsMap;
00207         AnimationBindingsMap mAnimationBindings;
00208 
00209         std::vector<size_t> mAnimatedNodeIndices;
00210 
00211         Mesh::SubMeshGeometryList mGeometries;
00212 
00213         IndicesMultimap mGeometryMap;
00214         struct ExtraPrimitiveData {
00215             std::map<size_t, size_t> uvSetMap;
00216         };
00217         struct ExtraGeometryData {
00218             std::vector<ExtraPrimitiveData> primitives;
00219             // Reverse index from new vert index -> orig vert index, for
00220             // per-vertex weights since they are applied separately
00221             std::vector<uint32> inverseVertexIndexMap;
00222         };
00223         void setupPrim(Mesh::SubMeshGeometry::Primitive* outputPrim,
00224                        ExtraPrimitiveData&outputPrimExtra,
00225                        const COLLADAFW::MeshPrimitive*prim);
00226         //a list of:
00227         //  mappings from texture coordinate set to list indices
00228         //  mappings from new position indices to original (for mapping indices
00229         //     backward into animation weight data to make vertices that were
00230         //     expanded to multiple vertices get weights applied to both).
00231         std::vector<ExtraGeometryData> mExtraGeometryData;
00232         IndicesMap mLightMap;
00233         Mesh::LightInfoList mLights;
00234 
00235         IdMap mMaterialMap;
00236         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, COLLADAFW::Effect, UniqueIdHash> ColladaEffectMap;
00237         ColladaEffectMap mColladaEffects;
00238         IndicesMap mConvertedEffects; // Index of effects already converted
00239                                        // which we can reuse.
00240 
00241         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, std::string, UniqueIdHash> URIMap;
00242         URIMap mTextureMap;
00243 
00244         std::vector <COLLADAFW::EffectCommon*> mColladaClonedCommonEffects;
00245         //IndicesMap mEffectMap;
00246         Mesh::MaterialEffectInfoList mEffects;
00247 
00248 
00249         typedef std::tr1::unordered_map<COLLADAFW::UniqueId, size_t, UniqueIdHash> IndexMap;
00250         // Indices for the nodes by UniqueId. Used to find the right index after
00251         // the first pass has translated all nodes into the Meshdata data structure.
00252         IndexMap mNodeIndices;
00253 
00254         // Indices for joints by UniqueID. Used to find right joints
00255         // for node controllers. Note that these are *joint* indices,
00256         // not *node* indices, i.e. if we store the value x, then the
00257         // associate node is mesh.nodes[mesh.joints[x]].
00258         IndexMap mJointIndices;
00259 
00260         Mesh::MeshdataPtr mMesh;
00261 };
00262 
00263 
00264 } // namespace Models
00265 } // namespace Sirikata
00266 
00267 #endif // _SIRIKATA_COLLADA_DOCUMENT_IMPORTER_