vrshoot

view libs/assimp/OgreMaterial.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /**
42 This file contains material related code. This is
43 spilitted up from the main file OgreImporter.cpp
44 to make it shorter easier to maintain.
45 */
46 #include "AssimpPCH.h"
48 #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
50 #include <vector>
51 #include <sstream>
52 using namespace std;
54 #include "OgreImporter.hpp"
55 #include "irrXMLWrapper.h"
56 #include "TinyFormatter.h"
58 namespace Assimp
59 {
60 namespace Ogre
61 {
65 aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
66 {
67 /*For better understanding of the material parser, here is a material example file:
69 material Sarg
70 {
71 receive_shadows on
72 technique
73 {
74 pass
75 {
76 ambient 0.500000 0.500000 0.500000 1.000000
77 diffuse 0.640000 0.640000 0.640000 1.000000
78 specular 0.500000 0.500000 0.500000 1.000000 12.500000
79 emissive 0.000000 0.000000 0.000000 1.000000
80 texture_unit
81 {
82 texture SargTextur.tga
83 tex_address_mode wrap
84 filtering linear linear none
85 }
86 }
87 }
88 }
90 */
92 /*and here is another one:
94 import * from abstract_base_passes_depth.material
95 import * from abstract_base.material
96 import * from mat_shadow_caster.material
97 import * from mat_character_singlepass.material
99 material hero/hair/caster : mat_shadow_caster_skin_areject
100 {
101 set $diffuse_map "hero_hair_alpha_c.dds"
102 }
104 material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights
105 {
106 set $diffuse_map "hero_hair_alpha_c.dds"
107 set $specular_map "hero_hair_alpha_s.dds"
108 set $normal_map "hero_hair_alpha_n.dds"
109 set $light_map "black_lightmap.dds"
111 set $shadow_caster_material "hero/hair/caster"
112 }
113 */
115 //Read the file into memory and put it in a stringstream
116 stringstream ss;
117 {// after this block, the temporarly loaded data will be released
119 /*
120 We have 3 guesses for the Material filename:
121 - the Material Name
122 - the Name of the mesh file
123 - the DefaultMaterialLib (which you can set before importing)
124 */
126 IOStream* MatFilePtr=m_CurrentIOHandler->Open(MaterialName+".material");
127 if(NULL==MatFilePtr)
128 {
129 //the filename typically ends with .mesh or .mesh.xml
130 const string MaterialFileName=m_CurrentFilename.substr(0, m_CurrentFilename.rfind(".mesh"))+".material";
132 MatFilePtr=m_CurrentIOHandler->Open(MaterialFileName);
133 if(NULL==MatFilePtr)
134 {
135 //try the default mat Library
136 if(NULL==MatFilePtr)
137 {
139 MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
140 if(NULL==MatFilePtr)
141 {
142 DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
143 return new aiMaterial();
144 }
145 }
146 }
147 }
148 //Fill the stream
149 boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr);
150 if(MaterialFile->FileSize()>0)
151 {
152 vector<char> FileData(MaterialFile->FileSize());
153 MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
154 BaseImporter::ConvertToUTF8(FileData);
156 FileData.push_back('\0');//terminate the string with zero, so that the ss can parse it correctly
157 ss << &FileData[0];
158 }
159 else
160 {
161 DefaultLogger::get()->warn("Material " + MaterialName + " seams to be empty");
162 return NULL;
163 }
164 }
166 //create the material
167 aiMaterial *NewMaterial=new aiMaterial();
169 aiString ts(MaterialName.c_str());
170 NewMaterial->AddProperty(&ts, AI_MATKEY_NAME);
172 string Line;
173 ss >> Line;
174 // unsigned int Level=0;//Hierarchielevels in the material file, like { } blocks into another
175 while(!ss.eof())
176 {
177 if(Line=="material")
178 {
179 ss >> Line;
180 if(Line==MaterialName)//Load the next material
181 {
182 string RestOfLine;
183 getline(ss, RestOfLine);//ignore the rest of the line
184 ss >> Line;
186 if(Line!="{")
187 {
188 DefaultLogger::get()->warn("empyt material!");
189 return NULL;
190 }
192 while(Line!="}")//read until the end of the material
193 {
194 //Proceed to the first technique
195 ss >> Line;
196 if(Line=="technique")
197 {
198 ReadTechnique(ss, NewMaterial);
199 }
201 DefaultLogger::get()->info(Line);
202 //read informations from a custom material:
203 if(Line=="set")
204 {
205 ss >> Line;
206 if(Line=="$specular")//todo load this values:
207 {
208 }
209 if(Line=="$diffuse")
210 {
211 }
212 if(Line=="$ambient")
213 {
214 }
215 if(Line=="$colormap")
216 {
217 ss >> Line;
218 aiString ts(Line.c_str());
219 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
220 }
221 if(Line=="$normalmap")
222 {
223 ss >> Line;
224 aiString ts(Line.c_str());
225 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
226 }
228 if(Line=="$shininess_strength")
229 {
230 ss >> Line;
231 float Shininess=fast_atof(Line.c_str());
232 NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
233 }
235 if(Line=="$shininess_exponent")
236 {
237 ss >> Line;
238 float Shininess=fast_atof(Line.c_str());
239 NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS);
240 }
242 //Properties from Venetica:
243 if(Line=="$diffuse_map")
244 {
245 ss >> Line;
246 if(Line[0]=='"')// "file" -> file
247 Line=Line.substr(1, Line.size()-2);
248 aiString ts(Line.c_str());
249 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
250 }
251 if(Line=="$specular_map")
252 {
253 ss >> Line;
254 if(Line[0]=='"')// "file" -> file
255 Line=Line.substr(1, Line.size()-2);
256 aiString ts(Line.c_str());
257 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0));
258 }
259 if(Line=="$normal_map")
260 {
261 ss >> Line;
262 if(Line[0]=='"')// "file" -> file
263 Line=Line.substr(1, Line.size()-2);
264 aiString ts(Line.c_str());
265 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
266 }
267 if(Line=="$light_map")
268 {
269 ss >> Line;
270 if(Line[0]=='"')// "file" -> file
271 Line=Line.substr(1, Line.size()-2);
272 aiString ts(Line.c_str());
273 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0));
274 }
275 }
276 }//end of material
277 }
278 else {} //this is the wrong material, proceed the file until we reach the next material
279 }
280 ss >> Line;
281 }
283 return NewMaterial;
284 }
286 void OgreImporter::ReadTechnique(stringstream &ss, aiMaterial* NewMaterial) const
287 {
288 unsigned int CurrentDiffuseTextureId=0;
289 unsigned int CurrentSpecularTextureId=0;
290 unsigned int CurrentNormalTextureId=0;
291 unsigned int CurrentLightTextureId=0;
294 string RestOfLine;
295 getline(ss, RestOfLine);//ignore the rest of the line
297 string Line;
298 ss >> Line;
299 if(Line!="{")
300 {
301 DefaultLogger::get()->warn("empty technique!");
302 return;
303 }
304 while(Line!="}")//read until the end of the technique
305 {
306 ss >> Line;
307 if(Line=="pass")
308 {
309 getline(ss, RestOfLine);//ignore the rest of the line
311 ss >> Line;
312 if(Line!="{")
313 {
314 DefaultLogger::get()->warn("empty pass!");
315 return;
316 }
317 while(Line!="}")//read until the end of the pass
318 {
319 ss >> Line;
320 if(Line=="ambient")
321 {
322 float r,g,b;
323 ss >> r >> g >> b;
324 const aiColor3D Color(r,g,b);
325 NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_AMBIENT);
326 }
327 else if(Line=="diffuse")
328 {
329 float r,g,b;
330 ss >> r >> g >> b;
331 const aiColor3D Color(r,g,b);
332 NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE);
333 }
334 else if(Line=="specular")
335 {
336 float r,g,b;
337 ss >> r >> g >> b;
338 const aiColor3D Color(r,g,b);
339 NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_SPECULAR);
340 }
341 else if(Line=="emmisive")
342 {
343 float r,g,b;
344 ss >> r >> g >> b;
345 const aiColor3D Color(r,g,b);
346 NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE);
347 }
348 else if(Line=="texture_unit")
349 {
350 getline(ss, RestOfLine);//ignore the rest of the line
352 std::string TextureName;
353 int TextureType=-1;
354 int UvSet=0;
356 ss >> Line;
357 if(Line!="{")
358 throw DeadlyImportError("empty texture unit!");
359 while(Line!="}")//read until the end of the texture_unit
360 {
361 ss >> Line;
362 if(Line=="texture")
363 {
364 ss >> Line;
365 TextureName=Line;
367 if(m_TextureTypeFromFilename)
368 {
369 if(Line.find("_n.")!=string::npos)// Normalmap
370 {
371 TextureType=aiTextureType_NORMALS;
372 }
373 else if(Line.find("_s.")!=string::npos)// Specularmap
374 {
375 TextureType=aiTextureType_SPECULAR;
376 }
377 else if(Line.find("_l.")!=string::npos)// Lightmap
378 {
379 TextureType=aiTextureType_LIGHTMAP;
380 }
381 else// colormap
382 {
383 TextureType=aiTextureType_DIFFUSE;
384 }
385 }
386 else
387 {
388 TextureType=aiTextureType_DIFFUSE;
389 }
390 }
391 else if(Line=="tex_coord_set")
392 {
393 ss >> UvSet;
394 }
395 else if(Line=="colour_op")//TODO implement this
396 {
397 /*
398 ss >> Line;
399 if("replace"==Line)//I don't think, assimp has something for this...
400 {
401 }
402 else if("modulate"==Line)
403 {
404 //TODO: set value
405 //NewMaterial->AddProperty(aiTextureOp_Multiply)
406 }
407 */
408 }
410 }//end of texture unit
411 Line="";//clear the } that would end the outer loop
413 //give the texture to assimp:
415 aiString ts(TextureName.c_str());
416 switch(TextureType)
417 {
418 case aiTextureType_DIFFUSE:
419 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, CurrentDiffuseTextureId));
420 NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentDiffuseTextureId));
421 CurrentDiffuseTextureId++;
422 break;
423 case aiTextureType_NORMALS:
424 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, CurrentNormalTextureId));
425 NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentNormalTextureId));
426 CurrentNormalTextureId++;
427 break;
428 case aiTextureType_SPECULAR:
429 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, CurrentSpecularTextureId));
430 NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentSpecularTextureId));
431 CurrentSpecularTextureId++;
432 break;
433 case aiTextureType_LIGHTMAP:
434 NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, CurrentLightTextureId));
435 NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentLightTextureId));
436 CurrentLightTextureId++;
437 break;
438 default:
439 DefaultLogger::get()->warn("Invalid Texture Type!");
440 break;
441 }
442 }
443 }
444 Line="";//clear the } that would end the outer loop
445 }
446 }//end of technique
447 }
450 }//namespace Ogre
451 }//namespace Assimp
453 #endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER