rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /** @file OgreImporter.cpp
|
nuclear@0
|
42 * @brief Implementation of the Ogre XML (.mesh.xml) loader.
|
nuclear@0
|
43 */
|
nuclear@0
|
44 #include "AssimpPCH.h"
|
nuclear@0
|
45 #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
nuclear@0
|
46
|
nuclear@0
|
47 #include <vector>
|
nuclear@0
|
48 #include <sstream>
|
nuclear@0
|
49 using namespace std;
|
nuclear@0
|
50
|
nuclear@0
|
51 #include "OgreImporter.hpp"
|
nuclear@0
|
52 #include "TinyFormatter.h"
|
nuclear@0
|
53 #include "irrXMLWrapper.h"
|
nuclear@0
|
54
|
nuclear@0
|
55 static const aiImporterDesc desc = {
|
nuclear@0
|
56 "Ogre XML Mesh Importer",
|
nuclear@0
|
57 "",
|
nuclear@0
|
58 "",
|
nuclear@0
|
59 "",
|
nuclear@0
|
60 aiImporterFlags_SupportTextFlavour,
|
nuclear@0
|
61 0,
|
nuclear@0
|
62 0,
|
nuclear@0
|
63 0,
|
nuclear@0
|
64 0,
|
nuclear@0
|
65 "mesh.xml"
|
nuclear@0
|
66 };
|
nuclear@0
|
67
|
nuclear@0
|
68 namespace Assimp
|
nuclear@0
|
69 {
|
nuclear@0
|
70 namespace Ogre
|
nuclear@0
|
71 {
|
nuclear@0
|
72
|
nuclear@0
|
73
|
nuclear@0
|
74 bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const
|
nuclear@0
|
75 {
|
nuclear@0
|
76 if(!checkSig)//Check File Extension
|
nuclear@0
|
77 {
|
nuclear@0
|
78 std::string extension("mesh.xml");
|
nuclear@0
|
79 int l=extension.length();
|
nuclear@0
|
80 return pFile.substr(pFile.length()-l, l)==extension;
|
nuclear@0
|
81 }
|
nuclear@0
|
82 else//Check file Header
|
nuclear@0
|
83 {
|
nuclear@0
|
84 const char* tokens[] = {"<mesh>"};
|
nuclear@0
|
85 return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
|
nuclear@0
|
86 }
|
nuclear@0
|
87 }
|
nuclear@0
|
88
|
nuclear@0
|
89
|
nuclear@0
|
90 void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler)
|
nuclear@0
|
91 {
|
nuclear@0
|
92 m_CurrentFilename=pFile;
|
nuclear@0
|
93 m_CurrentIOHandler=pIOHandler;
|
nuclear@0
|
94 m_CurrentScene=pScene;
|
nuclear@0
|
95
|
nuclear@0
|
96 //Open the File:
|
nuclear@0
|
97 boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile));
|
nuclear@0
|
98 if( file.get() == NULL)
|
nuclear@0
|
99 throw DeadlyImportError("Failed to open file "+pFile+".");
|
nuclear@0
|
100
|
nuclear@0
|
101 //Read the Mesh File:
|
nuclear@0
|
102 boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
|
nuclear@0
|
103 boost::scoped_ptr<XmlReader> MeshFile(irr::io::createIrrXMLReader(mIOWrapper.get()));
|
nuclear@0
|
104 if(!MeshFile)//parse the xml file
|
nuclear@0
|
105 throw DeadlyImportError("Failed to create XML Reader for "+pFile);
|
nuclear@0
|
106
|
nuclear@0
|
107
|
nuclear@0
|
108 DefaultLogger::get()->debug("Mesh File opened");
|
nuclear@0
|
109
|
nuclear@0
|
110 //Read root Node:
|
nuclear@0
|
111 if(!(XmlRead(MeshFile.get()) && string(MeshFile->getNodeName())=="mesh"))
|
nuclear@0
|
112 {
|
nuclear@0
|
113 throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName());
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 //eventually load shared geometry
|
nuclear@0
|
117 XmlRead(MeshFile.get());//shared geometry is optional, so we need a reed for the next two if's
|
nuclear@0
|
118 if(MeshFile->getNodeName()==string("sharedgeometry"))
|
nuclear@0
|
119 {
|
nuclear@0
|
120 unsigned int NumVertices=GetAttribute<int>(MeshFile.get(), "vertexcount");;
|
nuclear@0
|
121
|
nuclear@0
|
122 XmlRead(MeshFile.get());
|
nuclear@0
|
123 while(MeshFile->getNodeName()==string("vertexbuffer"))
|
nuclear@0
|
124 {
|
nuclear@0
|
125 ReadVertexBuffer(m_SharedGeometry, MeshFile.get(), NumVertices);
|
nuclear@0
|
126 }
|
nuclear@0
|
127 }
|
nuclear@0
|
128
|
nuclear@0
|
129 //Go to the submeshs:
|
nuclear@0
|
130 if(MeshFile->getNodeName()!=string("submeshes"))
|
nuclear@0
|
131 {
|
nuclear@0
|
132 throw DeadlyImportError("No <submeshes> node in <mesh> node! "+pFile);
|
nuclear@0
|
133 }
|
nuclear@0
|
134
|
nuclear@0
|
135
|
nuclear@0
|
136 //-------------------Read the submeshs and materials:-----------------------
|
nuclear@0
|
137 std::list<boost::shared_ptr<SubMesh> > SubMeshes;
|
nuclear@0
|
138 vector<aiMaterial*> Materials;
|
nuclear@0
|
139 XmlRead(MeshFile.get());
|
nuclear@0
|
140 while(MeshFile->getNodeName()==string("submesh"))
|
nuclear@0
|
141 {
|
nuclear@0
|
142 SubMesh* theSubMesh=new SubMesh();
|
nuclear@0
|
143 theSubMesh->MaterialName=GetAttribute<string>(MeshFile.get(), "material");
|
nuclear@0
|
144 DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
|
nuclear@0
|
145 ReadSubMesh(*theSubMesh, MeshFile.get());
|
nuclear@0
|
146
|
nuclear@0
|
147 //just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
|
nuclear@0
|
148 //so it is important to do this before pushing the mesh in the vector!
|
nuclear@0
|
149 theSubMesh->MaterialIndex=SubMeshes.size();
|
nuclear@0
|
150
|
nuclear@0
|
151 SubMeshes.push_back(boost::shared_ptr<SubMesh>(theSubMesh));
|
nuclear@0
|
152
|
nuclear@0
|
153 //Load the Material:
|
nuclear@0
|
154 aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName);
|
nuclear@0
|
155
|
nuclear@0
|
156 //Set the Material:
|
nuclear@0
|
157 Materials.push_back(MeshMat);
|
nuclear@0
|
158 }
|
nuclear@0
|
159
|
nuclear@0
|
160 if(SubMeshes.empty())
|
nuclear@0
|
161 throw DeadlyImportError("no submesh loaded!");
|
nuclear@0
|
162 if(SubMeshes.size()!=Materials.size())
|
nuclear@0
|
163 throw DeadlyImportError("materialcount doesn't match mesh count!");
|
nuclear@0
|
164
|
nuclear@0
|
165 //____________________________________________________________
|
nuclear@0
|
166
|
nuclear@0
|
167
|
nuclear@0
|
168 //skip submeshnames (stupid irrxml)
|
nuclear@0
|
169 if(MeshFile->getNodeName()==string("submeshnames"))
|
nuclear@0
|
170 {
|
nuclear@0
|
171 XmlRead(MeshFile.get());
|
nuclear@0
|
172 while(MeshFile->getNodeName()==string("submesh"))
|
nuclear@0
|
173 XmlRead(MeshFile.get());
|
nuclear@0
|
174 }
|
nuclear@0
|
175
|
nuclear@0
|
176
|
nuclear@0
|
177 //----------------Load the skeleton: -------------------------------
|
nuclear@0
|
178 vector<Bone> Bones;
|
nuclear@0
|
179 vector<Animation> Animations;
|
nuclear@0
|
180 if(MeshFile->getNodeName()==string("skeletonlink"))
|
nuclear@0
|
181 {
|
nuclear@0
|
182 string SkeletonFile=GetAttribute<string>(MeshFile.get(), "name");
|
nuclear@0
|
183 LoadSkeleton(SkeletonFile, Bones, Animations);
|
nuclear@0
|
184 XmlRead(MeshFile.get());
|
nuclear@0
|
185 }
|
nuclear@0
|
186 else
|
nuclear@0
|
187 {
|
nuclear@0
|
188 DefaultLogger::get()->debug("No skeleton file will be loaded");
|
nuclear@0
|
189 DefaultLogger::get()->debug(MeshFile->getNodeName());
|
nuclear@0
|
190 }
|
nuclear@0
|
191 //__________________________________________________________________
|
nuclear@0
|
192
|
nuclear@0
|
193
|
nuclear@0
|
194 //now there might be boneassignments for the shared geometry:
|
nuclear@0
|
195 if(MeshFile->getNodeName()==string("boneassignments"))
|
nuclear@0
|
196 {
|
nuclear@0
|
197 ReadBoneWeights(m_SharedGeometry, MeshFile.get());
|
nuclear@0
|
198 }
|
nuclear@0
|
199
|
nuclear@0
|
200
|
nuclear@0
|
201 //----------------- Process Meshs -----------------------
|
nuclear@0
|
202 BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes)
|
nuclear@0
|
203 {
|
nuclear@0
|
204 ProcessSubMesh(*theSubMesh, m_SharedGeometry);
|
nuclear@0
|
205 }
|
nuclear@0
|
206 //_______________________________________________________
|
nuclear@0
|
207
|
nuclear@0
|
208
|
nuclear@0
|
209
|
nuclear@0
|
210
|
nuclear@0
|
211 //----------------- Now fill the Assimp scene ---------------------------
|
nuclear@0
|
212
|
nuclear@0
|
213 //put the aiMaterials in the scene:
|
nuclear@0
|
214 m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()];
|
nuclear@0
|
215 m_CurrentScene->mNumMaterials=Materials.size();
|
nuclear@0
|
216 for(unsigned int i=0; i<Materials.size(); ++i)
|
nuclear@0
|
217 m_CurrentScene->mMaterials[i]=Materials[i];
|
nuclear@0
|
218
|
nuclear@0
|
219 //create the aiMehs...
|
nuclear@0
|
220 vector<aiMesh*> aiMeshes;
|
nuclear@0
|
221 BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes)
|
nuclear@0
|
222 {
|
nuclear@0
|
223 aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones));
|
nuclear@0
|
224 }
|
nuclear@0
|
225 //... and put them in the scene:
|
nuclear@0
|
226 m_CurrentScene->mNumMeshes=aiMeshes.size();
|
nuclear@0
|
227 m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()];
|
nuclear@0
|
228 memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size());
|
nuclear@0
|
229
|
nuclear@0
|
230 //Create the root node
|
nuclear@0
|
231 m_CurrentScene->mRootNode=new aiNode("root");
|
nuclear@0
|
232
|
nuclear@0
|
233 //link the meshs with the root node:
|
nuclear@0
|
234 m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()];
|
nuclear@0
|
235 m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size();
|
nuclear@0
|
236 for(unsigned int i=0; i<SubMeshes.size(); ++i)
|
nuclear@0
|
237 m_CurrentScene->mRootNode->mMeshes[i]=i;
|
nuclear@0
|
238
|
nuclear@0
|
239
|
nuclear@0
|
240
|
nuclear@0
|
241 CreateAssimpSkeleton(Bones, Animations);
|
nuclear@0
|
242 PutAnimationsInScene(Bones, Animations);
|
nuclear@0
|
243 //___________________________________________________________
|
nuclear@0
|
244 }
|
nuclear@0
|
245
|
nuclear@0
|
246
|
nuclear@0
|
247 const aiImporterDesc* OgreImporter::GetInfo () const
|
nuclear@0
|
248 {
|
nuclear@0
|
249 return &desc;
|
nuclear@0
|
250 }
|
nuclear@0
|
251
|
nuclear@0
|
252
|
nuclear@0
|
253 void OgreImporter::SetupProperties(const Importer* pImp)
|
nuclear@0
|
254 {
|
nuclear@0
|
255 m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material");
|
nuclear@0
|
256 m_TextureTypeFromFilename=pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false);
|
nuclear@0
|
257 }
|
nuclear@0
|
258
|
nuclear@0
|
259
|
nuclear@0
|
260 }//namespace Ogre
|
nuclear@0
|
261 }//namespace Assimp
|
nuclear@0
|
262
|
nuclear@0
|
263 #endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER
|