Sirikata
|
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_