vrshoot
diff libs/assimp/OgreImporter.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/OgreImporter.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,263 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 +/** @file OgreImporter.cpp 1.45 + * @brief Implementation of the Ogre XML (.mesh.xml) loader. 1.46 + */ 1.47 +#include "AssimpPCH.h" 1.48 +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER 1.49 + 1.50 +#include <vector> 1.51 +#include <sstream> 1.52 +using namespace std; 1.53 + 1.54 +#include "OgreImporter.hpp" 1.55 +#include "TinyFormatter.h" 1.56 +#include "irrXMLWrapper.h" 1.57 + 1.58 +static const aiImporterDesc desc = { 1.59 + "Ogre XML Mesh Importer", 1.60 + "", 1.61 + "", 1.62 + "", 1.63 + aiImporterFlags_SupportTextFlavour, 1.64 + 0, 1.65 + 0, 1.66 + 0, 1.67 + 0, 1.68 + "mesh.xml" 1.69 +}; 1.70 + 1.71 +namespace Assimp 1.72 +{ 1.73 +namespace Ogre 1.74 +{ 1.75 + 1.76 + 1.77 +bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const 1.78 +{ 1.79 + if(!checkSig)//Check File Extension 1.80 + { 1.81 + std::string extension("mesh.xml"); 1.82 + int l=extension.length(); 1.83 + return pFile.substr(pFile.length()-l, l)==extension; 1.84 + } 1.85 + else//Check file Header 1.86 + { 1.87 + const char* tokens[] = {"<mesh>"}; 1.88 + return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); 1.89 + } 1.90 +} 1.91 + 1.92 + 1.93 +void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler) 1.94 +{ 1.95 + m_CurrentFilename=pFile; 1.96 + m_CurrentIOHandler=pIOHandler; 1.97 + m_CurrentScene=pScene; 1.98 + 1.99 + //Open the File: 1.100 + boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile)); 1.101 + if( file.get() == NULL) 1.102 + throw DeadlyImportError("Failed to open file "+pFile+"."); 1.103 + 1.104 + //Read the Mesh File: 1.105 + boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get())); 1.106 + boost::scoped_ptr<XmlReader> MeshFile(irr::io::createIrrXMLReader(mIOWrapper.get())); 1.107 + if(!MeshFile)//parse the xml file 1.108 + throw DeadlyImportError("Failed to create XML Reader for "+pFile); 1.109 + 1.110 + 1.111 + DefaultLogger::get()->debug("Mesh File opened"); 1.112 + 1.113 + //Read root Node: 1.114 + if(!(XmlRead(MeshFile.get()) && string(MeshFile->getNodeName())=="mesh")) 1.115 + { 1.116 + throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName()); 1.117 + } 1.118 + 1.119 + //eventually load shared geometry 1.120 + XmlRead(MeshFile.get());//shared geometry is optional, so we need a reed for the next two if's 1.121 + if(MeshFile->getNodeName()==string("sharedgeometry")) 1.122 + { 1.123 + unsigned int NumVertices=GetAttribute<int>(MeshFile.get(), "vertexcount");; 1.124 + 1.125 + XmlRead(MeshFile.get()); 1.126 + while(MeshFile->getNodeName()==string("vertexbuffer")) 1.127 + { 1.128 + ReadVertexBuffer(m_SharedGeometry, MeshFile.get(), NumVertices); 1.129 + } 1.130 + } 1.131 + 1.132 + //Go to the submeshs: 1.133 + if(MeshFile->getNodeName()!=string("submeshes")) 1.134 + { 1.135 + throw DeadlyImportError("No <submeshes> node in <mesh> node! "+pFile); 1.136 + } 1.137 + 1.138 + 1.139 + //-------------------Read the submeshs and materials:----------------------- 1.140 + std::list<boost::shared_ptr<SubMesh> > SubMeshes; 1.141 + vector<aiMaterial*> Materials; 1.142 + XmlRead(MeshFile.get()); 1.143 + while(MeshFile->getNodeName()==string("submesh")) 1.144 + { 1.145 + SubMesh* theSubMesh=new SubMesh(); 1.146 + theSubMesh->MaterialName=GetAttribute<string>(MeshFile.get(), "material"); 1.147 + DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName); 1.148 + ReadSubMesh(*theSubMesh, MeshFile.get()); 1.149 + 1.150 + //just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n; 1.151 + //so it is important to do this before pushing the mesh in the vector! 1.152 + theSubMesh->MaterialIndex=SubMeshes.size(); 1.153 + 1.154 + SubMeshes.push_back(boost::shared_ptr<SubMesh>(theSubMesh)); 1.155 + 1.156 + //Load the Material: 1.157 + aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName); 1.158 + 1.159 + //Set the Material: 1.160 + Materials.push_back(MeshMat); 1.161 + } 1.162 + 1.163 + if(SubMeshes.empty()) 1.164 + throw DeadlyImportError("no submesh loaded!"); 1.165 + if(SubMeshes.size()!=Materials.size()) 1.166 + throw DeadlyImportError("materialcount doesn't match mesh count!"); 1.167 + 1.168 + //____________________________________________________________ 1.169 + 1.170 + 1.171 + //skip submeshnames (stupid irrxml) 1.172 + if(MeshFile->getNodeName()==string("submeshnames")) 1.173 + { 1.174 + XmlRead(MeshFile.get()); 1.175 + while(MeshFile->getNodeName()==string("submesh")) 1.176 + XmlRead(MeshFile.get()); 1.177 + } 1.178 + 1.179 + 1.180 + //----------------Load the skeleton: ------------------------------- 1.181 + vector<Bone> Bones; 1.182 + vector<Animation> Animations; 1.183 + if(MeshFile->getNodeName()==string("skeletonlink")) 1.184 + { 1.185 + string SkeletonFile=GetAttribute<string>(MeshFile.get(), "name"); 1.186 + LoadSkeleton(SkeletonFile, Bones, Animations); 1.187 + XmlRead(MeshFile.get()); 1.188 + } 1.189 + else 1.190 + { 1.191 + DefaultLogger::get()->debug("No skeleton file will be loaded"); 1.192 + DefaultLogger::get()->debug(MeshFile->getNodeName()); 1.193 + } 1.194 + //__________________________________________________________________ 1.195 + 1.196 + 1.197 + //now there might be boneassignments for the shared geometry: 1.198 + if(MeshFile->getNodeName()==string("boneassignments")) 1.199 + { 1.200 + ReadBoneWeights(m_SharedGeometry, MeshFile.get()); 1.201 + } 1.202 + 1.203 + 1.204 + //----------------- Process Meshs ----------------------- 1.205 + BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes) 1.206 + { 1.207 + ProcessSubMesh(*theSubMesh, m_SharedGeometry); 1.208 + } 1.209 + //_______________________________________________________ 1.210 + 1.211 + 1.212 + 1.213 + 1.214 + //----------------- Now fill the Assimp scene --------------------------- 1.215 + 1.216 + //put the aiMaterials in the scene: 1.217 + m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()]; 1.218 + m_CurrentScene->mNumMaterials=Materials.size(); 1.219 + for(unsigned int i=0; i<Materials.size(); ++i) 1.220 + m_CurrentScene->mMaterials[i]=Materials[i]; 1.221 + 1.222 + //create the aiMehs... 1.223 + vector<aiMesh*> aiMeshes; 1.224 + BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes) 1.225 + { 1.226 + aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones)); 1.227 + } 1.228 + //... and put them in the scene: 1.229 + m_CurrentScene->mNumMeshes=aiMeshes.size(); 1.230 + m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()]; 1.231 + memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size()); 1.232 + 1.233 + //Create the root node 1.234 + m_CurrentScene->mRootNode=new aiNode("root"); 1.235 + 1.236 + //link the meshs with the root node: 1.237 + m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()]; 1.238 + m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size(); 1.239 + for(unsigned int i=0; i<SubMeshes.size(); ++i) 1.240 + m_CurrentScene->mRootNode->mMeshes[i]=i; 1.241 + 1.242 + 1.243 + 1.244 + CreateAssimpSkeleton(Bones, Animations); 1.245 + PutAnimationsInScene(Bones, Animations); 1.246 + //___________________________________________________________ 1.247 +} 1.248 + 1.249 + 1.250 +const aiImporterDesc* OgreImporter::GetInfo () const 1.251 +{ 1.252 + return &desc; 1.253 +} 1.254 + 1.255 + 1.256 +void OgreImporter::SetupProperties(const Importer* pImp) 1.257 +{ 1.258 + m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material"); 1.259 + m_TextureTypeFromFilename=pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false); 1.260 +} 1.261 + 1.262 + 1.263 +}//namespace Ogre 1.264 +}//namespace Assimp 1.265 + 1.266 +#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER