SO3Engine
ALMaterial.cpp
Go to the documentation of this file.
4
6
11
13
14#include "OGRE/OgreImage.h"
15
16namespace SO3
17{
18 ALMaterial::ALMaterial(ALScene* alscene, aiMaterial* srcMaterial, bool useVertexColor)
19 {
20 mScene = alscene;
21 mMat = srcMaterial;
22 mUseVertexColor = useVertexColor;
23 mCutout = false;
24 mUseAlpha = false;
25 mHaveAlphaDetails = false;
26 }
27
31
32 void ALMaterial::manageTexturePath(ALTextureData* texData, boost::filesystem::path expPath)
33 {
34 boost::filesystem::path base(mScene->getRessourcePath());
35 boost::filesystem::path texPath(texData->path);
36
37 // We get the filename by getting the substring from the last slash to the end of the string.
38 std::string filename;
39 boost::filesystem::path filepath(texData->path);
40 filename = filepath.generic_string();
41
42 if (filename.find_last_of('/') != std::string::npos)
43 filename = filename.substr(filename.find_last_of('/'));
44
45 // We create the the export path.
46 expPath /= "textures";
47
48 if (!filename.empty() && filename.front() == '/')
49 filename.erase(0, 1);
50
51 // We create the full path where the texture will be saved.
52 expPath /= ALStringCleaner::cleanString(filename, true, true, true, false);
53
54 // Optimize texture
55 bool optimize = false;
56 unsigned int optSize = 1024;
57
58 if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures)
59 optimize = true;
60
61 if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures_VeryLow)
62 optSize = 256;
63 else if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures_Low)
64 optSize = 512;
65 else if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures_Medium)
66 optSize = 1024;
67 else if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures_High)
68 optSize = 2048;
69 else if (mScene->GetSceneLoader()->getFlags() & so3Converter_OptimizeTextures_VeryHigh)
70 optSize = 4096;
71
72 // Use embedded texture
73 if (texData->embedded)
74 {
75 if (const aiTexture* texture = mScene->getAiScene()->GetEmbeddedTexture(texData->embname.c_str()))
76 {
77 if (!texture->mHeight)
78 {
79 try
80 {
81 if (FILE* file = fopen(expPath.generic_string().c_str(), "wb"))
82 {
83 fwrite(texture->pcData, texture->mWidth, 1, file);
84 fclose(file);
85
86 if (optimize)
87 {
88 Ogre::Image image;
89 try
90 {
91 std::ifstream ifs(expPath.generic_string().c_str(), std::ios::binary | std::ios::in);
92 std::string ext = boost::filesystem::extension(expPath).substr(1);
93 if (ifs.is_open())
94 {
95 Ogre::DataStreamPtr data_stream(new Ogre::FileStreamDataStream(expPath.generic_string(), &ifs, false));
96 image.load(data_stream, ext);
97 }
98 ifs.close();
99
100 if (image.getWidth() > optSize || image.getHeight() > optSize)
101 {
102 expPath.replace_extension(ConversionTools::GetValidImageExtension(ext));
103 image.resize(optSize, optSize);
104 ConversionTools::SaveOgreImage(image, expPath);
105 }
106 }
107 catch (Ogre::Exception &e)
108 {
109 std::cerr << "Texture optimization failed! : " << e.what() << std::endl;
110 }
111 }
112 }
113 }
114 catch (std::exception &e)
115 {
116 std::cerr << "File format error : " << e.what() << std::endl;
117 }
118 }
119 else
120 {
121 try
122 {
123 std::string format(texture->achFormatHint);
124 Ogre::PixelFormat oformat = Ogre::PF_UNKNOWN;
125 if (format == "argb8888")
126 oformat = Ogre::PF_A8R8G8B8;
127 else if (format == "rgba8888")
128 oformat = Ogre::PF_R8G8B8A8;
129 else if (format == "rgb888")
130 oformat = Ogre::PF_R8G8B8;
131 else if (format == "bgr888")
132 oformat = Ogre::PF_B8G8R8;
133 else if (format == "rgba5650")
134 oformat = Ogre::PF_R5G6B5;
135
136 if (oformat != Ogre::PF_UNKNOWN)
137 {
138 Ogre::Image image;
139 image.loadDynamicImage((uchar*)texture->pcData, texture->mWidth, texture->mHeight, oformat);
140
141 if (optimize && (texture->mWidth > optSize || texture->mHeight > optSize))
142 image.resize(optSize, optSize);
143
144 std::string ext = boost::filesystem::extension(expPath).substr(1);
145 expPath.replace_extension(ConversionTools::GetValidImageExtension(ext));
146 ConversionTools::SaveOgreImage(image, expPath);
147 }
148 }
149 catch (Ogre::Exception &e)
150 {
151 std::cerr << "File format error : " << e.what() << std::endl;
152 }
153 }
154 }
155 }
156 else
157 {
158 // We now copy the file. Since we copy the texture on the current material, it can already be present in the directory
159 // if a precedent material had it. So, If the file already exist, we do nothing.
160 if (optimize)
161 {
162 Ogre::Image image;
163 try
164 {
165 std::ifstream ifs(texPath.generic_string().c_str(), std::ios::binary | std::ios::in);
166 std::string ext = boost::filesystem::extension(texPath).substr(1);
167 if (ifs.is_open())
168 {
169 Ogre::DataStreamPtr data_stream(new Ogre::FileStreamDataStream(texPath.generic_string(), &ifs, false));
170 image.load(data_stream, ext);
171 }
172 ifs.close();
173
174 if (image.getWidth() > optSize || image.getHeight() > optSize)
175 {
176 expPath.replace_extension(ConversionTools::GetValidImageExtension(ext));
177 image.resize(optSize, optSize);
178 ConversionTools::SaveOgreImage(image, expPath);
179 }
180 else
181 {
182 try
183 {
184 boost::filesystem::copy_file(texPath, expPath, boost::filesystem::copy_option::overwrite_if_exists);
185 }
186 catch (boost::filesystem::filesystem_error &e)
187 {
188 std::cerr << "File already exist : " << e.what() << std::endl;
189 }
190 }
191 }
192 catch (Ogre::Exception &e)
193 {
194 std::cerr << "Texture optimization failed! : " << e.what() << std::endl;
195 }
196 }
197 else
198 {
199 try
200 {
201 boost::filesystem::copy_file(texPath, expPath, boost::filesystem::copy_option::overwrite_if_exists);
202 }
203 catch (boost::filesystem::filesystem_error &e)
204 {
205 std::cerr << "File already exist : " << e.what() << std::endl;
206 }
207 }
208 }
209
210 // We change the texture path to it's new absolute path.
211 texData->path = expPath.generic_string();
212 }
213
214 void ALMaterial::buildData(int count, aiTextureType type, std::vector<ALTextureData>& datas)
215 {
216 for (int n = 0; n < count; ++n)
217 {
218 ALTextureData texData;
219 texData.type = type;
220 texData.embedded = false;
221 texData.useAlpha = false;
222 texData.mapmode[0] = aiTextureMapMode_Wrap;
223 texData.mapmode[1] = aiTextureMapMode_Wrap;
224 texData.mapmode[2] = aiTextureMapMode_Wrap;
225
226 aiString aipath;
227 texData.uvindex = 0;
228 mMat->GetTexture(type, n, &aipath, &texData.mapping, &texData.uvindex, &texData.blend, &texData.op, texData.mapmode);
229
230 int tFlags = 0;
231 if (AI_SUCCESS == mMat->Get(AI_MATKEY_TEXFLAGS(type, n), tFlags))
232 {
233 if ((tFlags &aiTextureFlags_UseAlpha) || !(tFlags &aiTextureFlags_IgnoreAlpha))
234 texData.useAlpha = true;
235 }
236 else // let determine by bitmap content
237 {
238 texData.useAlpha = true;
239 }
240
241 boost::filesystem::path tpath(aipath.C_Str());
242 boost::filesystem::path base(mScene->getRessourcePath());
243
244 if (const aiTexture* texture = mScene->getAiScene()->GetEmbeddedTexture(aipath.C_Str()))
245 {
246 tpath = boost::filesystem::path(texture->mFilename.C_Str());
247
248 //Compute a name
249 if (tpath.empty())
250 {
251 std::string format(texture->achFormatHint);
252 //force png for convertion
253 if (texture->mHeight)
254 format = "png";
255
256 std::string genname = std::string(aipath.C_Str());
257 genname = genname.substr(1);
258 genname = "texgen_" + genname + "." + format;
259 tpath = boost::filesystem::path(genname);
260 }
261 texData.embname = aipath.C_Str();
262 texData.embedded = true;
263 }
264 // If the path to the texture is not an absolute path, we build one using the base path ( the directory of the original file ).
265 else if (!tpath.is_absolute())
266 {
267 {
268 try
269 {
270 tpath = boost::filesystem::canonical(tpath, base);
271 }
272 catch (boost::filesystem::filesystem_error &e)
273 {
274 std::cerr << "File not found : " << e.what() << std::endl;
275 }
276 }
277
278 // test if the file exist otherwise try in the resource folder
279 bool exist = false;
280 try
281 {
282 exist = boost::filesystem::exists(tpath);
283 }
284 catch (boost::filesystem::filesystem_error &e)
285 {
286 std::cerr << "File not found : " << e.what() << std::endl;
287 }
288
289 // try in resource dir
290 if (!exist)
291 {
292 std::string filename;
293 boost::filesystem::path filepath(tpath);
294 filename = filepath.generic_string();
295
296 if (filename.find_last_of('/') != std::string::npos)
297 filename = filename.substr(filename.find_last_of('/'));
298
299 tpath = mScene->getRessourcePath();
300 tpath /= "texture";
301 tpath /= filename;
302
303 try
304 {
305 exist = boost::filesystem::exists(tpath);
306 }
307 catch (boost::filesystem::filesystem_error &)
308 {
309 }
310
311 // try with textures folder
312 if (!exist)
313 {
314 tpath = mScene->getRessourcePath();
315 tpath /= "textures";
316 tpath /= filename;
317
318 try
319 {
320 exist = boost::filesystem::exists(tpath);
321 }
322 catch (boost::filesystem::filesystem_error &)
323 {
324 }
325 }
326
327 // try with tex folder
328 if (!exist)
329 {
330 tpath = mScene->getRessourcePath();
331 tpath /= "tex";
332 tpath /= filename;
333
334 try
335 {
336 exist = boost::filesystem::exists(tpath);
337 }
338 catch (boost::filesystem::filesystem_error &)
339 {
340 }
341 }
342
343 // try with maps folder
344 if (!exist)
345 {
346 tpath = mScene->getRessourcePath();
347 tpath /= "maps";
348 tpath /= filename;
349
350 try
351 {
352 exist = boost::filesystem::exists(tpath);
353 }
354 catch (boost::filesystem::filesystem_error &)
355 {
356 }
357 }
358
359 // try with resource folder
360 if (!exist)
361 {
362 tpath = mScene->getRessourcePath();
363 tpath /= filename;
364 }
365 }
366 }
367 texData.path = tpath.generic_string();
368
369 //avoid ORM texture to be added twice
370 if (texCount.metalCount && ((type == aiTextureType_LIGHTMAP) || (type == aiTextureType_AMBIENT_OCCLUSION)))
371 {
372 bool addTex = true;
373 for (size_t j = 0; j < datas.size(); ++j)
374 {
375 ALTextureData cd = datas[j];
376 if (((cd.type == aiTextureType_METALNESS) || (cd.type == aiTextureType_DIFFUSE_ROUGHNESS)) && (cd.path == texData.path))
377 {
378 addTex = false;
379 break;
380 }
381 }
382
383 if (addTex)
384 datas.push_back(texData);
385 }
386 else
387 datas.push_back(texData);
388 }
389 }
390
391 void ALMaterial::getTexturesCount()
392 {
393 // Get all the textures count.
394 texCount.metalCount = mMat->GetTextureCount(aiTextureType_METALNESS);
395 texCount.roughCount = mMat->GetTextureCount(aiTextureType_DIFFUSE_ROUGHNESS);
396
397 // Colors textures;
398 texCount.difCount = mMat->GetTextureCount(aiTextureType_DIFFUSE);
399 texCount.specCount = mMat->GetTextureCount(aiTextureType_SPECULAR);
400 texCount.ambCount = mMat->GetTextureCount(aiTextureType_AMBIENT);
401 texCount.ambOccCount = mMat->GetTextureCount(aiTextureType_AMBIENT_OCCLUSION);
402 texCount.emiCount = mMat->GetTextureCount(aiTextureType_EMISSIVE);
403
404 // Relief related textures.
405 texCount.hmapCount = mMat->GetTextureCount(aiTextureType_HEIGHT);
406 texCount.normCount = mMat->GetTextureCount(aiTextureType_NORMALS);
407 texCount.dmapCount = mMat->GetTextureCount(aiTextureType_DISPLACEMENT);
408
409 // Light related textures.
410 texCount.shineCount = mMat->GetTextureCount(aiTextureType_SHININESS);
411 texCount.opacityCount = mMat->GetTextureCount(aiTextureType_OPACITY);
412 texCount.lightmapCount = mMat->GetTextureCount(aiTextureType_LIGHTMAP);
413 texCount.reflectionCount = mMat->GetTextureCount(aiTextureType_REFLECTION);
414 }
415
416 void ALMaterial::getTexturesInfo()
417 {
418 //overwrite material color when we got a texture
419 if (texCount.difCount > 0 || texCount.ambCount > 0)
420 {
421 mColors.diffuse = aiColor4D(1.f, 1.f, 1.f, 1.f);
422 mColors.ambient = aiColor4D(1.f, 1.f, 1.f, 1.f);
423 }
424
425 if (texCount.emiCount > 0)
426 mColors.emissive = aiColor4D(0.f, 0.f, 0.f, 1.f);
427
428 buildData(texCount.ambCount, aiTextureType_AMBIENT, texInfo);
429 buildData(texCount.difCount, aiTextureType_DIFFUSE, texInfo);
430 buildData(texCount.specCount, aiTextureType_SPECULAR, texInfo);
431 buildData(texCount.hmapCount, aiTextureType_HEIGHT, texInfo);
432 buildData(texCount.normCount, aiTextureType_NORMALS, texInfo);
433 buildData(texCount.dmapCount, aiTextureType_DISPLACEMENT, texInfo);
434 buildData(texCount.shineCount, aiTextureType_SHININESS, texInfo);
435 buildData(texCount.reflectionCount, aiTextureType_REFLECTION, texInfo);
436 buildData(texCount.emiCount, aiTextureType_EMISSIVE, texInfo);
437
438 // Build the textures datas for each textures types.
439 buildData(texCount.roughCount, aiTextureType_DIFFUSE_ROUGHNESS, texInfo);
440 if (!texCount.roughCount)
441 buildData(texCount.metalCount, aiTextureType_METALNESS, texInfo);
442
443 buildData(texCount.ambOccCount, aiTextureType_AMBIENT_OCCLUSION, texInfo);
444 buildData(texCount.lightmapCount, aiTextureType_LIGHTMAP, texInfo);
445
446 buildData(texCount.opacityCount, aiTextureType_OPACITY, texInfo);
447 }
448
449 void ALMaterial::getColorInfo()
450 {
451 // Getting the different color in the material.
452
453 // NOTE: Assimp automaticly set the colors to (0,0,0,0) if it not exist.
454 // We just have to send a warning.
455
456 mColors.diffuse = aiColor4D(1.f, 1.f, 1.f, 1.f);
457 if (AI_SUCCESS != mMat->Get(AI_MATKEY_COLOR_DIFFUSE, mColors.diffuse))
458 {
459 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Warning: No diffuse in " + matInfo.name + " Material.");
460 }
461
462 //prevent black diffuse / ambient
463 if (mColors.diffuse.r < 0.01f && mColors.diffuse.g < 0.01f && mColors.diffuse.b < 0.01f)
464 mColors.diffuse = aiColor4D(1.f, 1.f, 1.f, 1.f);
465
466 mColors.specular = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
467 if (AI_SUCCESS != mMat->Get(AI_MATKEY_COLOR_SPECULAR, mColors.specular))
468 {
469 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Warning: No specular in " + matInfo.name + " Material.");
470 }
471
472 mColors.ambient = aiColor4D(1.f, 1.f, 1.f, 1.f);
473 if (AI_SUCCESS != mMat->Get(AI_MATKEY_COLOR_AMBIENT, mColors.ambient))
474 {
475 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Warning: No ambient in " + matInfo.name + " Material.");
476 }
477
478 //prevent black diffuse / ambient
479 if (mColors.ambient.r < 0.1f && mColors.ambient.g < 0.1f && mColors.ambient.b < 0.1f)
480 mColors.ambient = aiColor4D(1.f, 1.f, 1.f, 1.f);
481
482 mColors.emissive = aiColor4D(0.f, 0.f, 0.f, 1.f);
483 if (AI_SUCCESS != mMat->Get(AI_MATKEY_COLOR_EMISSIVE, mColors.emissive))
484 {
485 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Warning: No emissive in " + matInfo.name + " Material.");
486 }
487
488 mColors.transparence = aiColor4D(0.f, 0.f, 0.f, 1.f);
489 if (AI_SUCCESS != mMat->Get(AI_MATKEY_COLOR_TRANSPARENT, mColors.transparence))
490 {
491 Ogre::LogManager::getSingleton().getDefaultLog()->logMessage("Warning: No transparent in " + matInfo.name + " Material.");
492 }
493
494 aiString amode;
495 if (AI_SUCCESS == mMat->Get("$mat.gltf.alphaMode", 0, 0, amode))
496 {
497 if (std::string(amode.C_Str()) == "BLEND")
498 {
499 mUseAlpha = true;
500 }
501 else if (std::string(amode.C_Str()) == "MASK")
502 {
503 mUseAlpha = true;
504 mCutout = true;
505 }
506 mHaveAlphaDetails = true;
507 }
508 }
509
510 void ALMaterial::getMatInfo()
511 {
512 aiString aiMatName("");
513 if ((AI_SUCCESS != mMat->Get(AI_MATKEY_NAME, aiMatName)) || (aiMatName.length == 0))
514 {
515 // Material has no name, we generate one.
517 }
518 else
519 {
520 matInfo.name = ALStringCleaner::cleanString(mScene->getSceneName() + "_" + std::string(aiMatName.C_Str()));
521 }
522
523 int twosided = 0;
524 if (AI_SUCCESS != mMat->Get(AI_MATKEY_TWOSIDED, twosided))
525 {
526 // No Info on Two-Sided. We use the default value (false).
527 twosided = 0;
528 }
529 matInfo.isTwoSided = (twosided == 0) ? false : true;
530
531 int wireframe = 0;
532 if (AI_SUCCESS != mMat->Get(AI_MATKEY_ENABLE_WIREFRAME, wireframe))
533 {
534 // No info on wireframe. We use the default value (false).
535 wireframe = 0;
536 }
537 matInfo.isWire = (wireframe == 0) ? false : true;
538
539 if (AI_SUCCESS != mMat->Get(AI_MATKEY_SHININESS, matInfo.shininess))
540 matInfo.shininess = -1.f; // Failure, set default value.
541 else
542 matInfo.shininess = (matInfo.shininess / 1024.0f) * 256.0f;
543
544 if (AI_SUCCESS != mMat->Get(AI_MATKEY_OPACITY, matInfo.opacity))
545 matInfo.opacity = 1.f;
546
547 // prevent collada inverted opacity
548 if (matInfo.opacity == 0.0f)
549 matInfo.opacity = 1.f;
550
551 if (AI_SUCCESS != mMat->Get(AI_MATKEY_REFLECTIVITY, matInfo.reflectivity))
552 matInfo.reflectivity = 0.f;
553
554 matInfo.isVertexColor = (mUseVertexColor) ? 1 : 0;
555 }
556
557 void ALMaterial::writeOgreScript(std::ostream& script, boost::filesystem::path expPath)
558 {
559 script << "material \"" << matInfo.name << "\"\n";
560 script << "{\n";
561
562 bool needBasicScheme = false;
563
564 // full material definition
565 /*
566 if (texCount.normCount > 0 || texCount.dmapCount > 0 || texCount.specCount > 0)
567 {
568 writeTechnique(script, expPath, true);
569 needBasicScheme = true;
570 }
571 writeTechnique(script, expPath, false, needBasicScheme);
572 */
573
574 writeTechnique(script, expPath, true);
575
576 script << "}\n";
577 }
578
579 void ALMaterial::writeTechnique(std::ostream& script, boost::filesystem::path expPath, bool extended, bool basicscheme)
580 {
581 // Start technique description
582 script << "\ttechnique ";
583 script << matInfo.name;
584
585 if (basicscheme)
586 script << "_basic";
587
588 script << "_technique" << "\n";
589 script << "\t{\n";
590
591 if (basicscheme)
592 script << "\t\tscheme basic\n";
593
594 writePass(script, expPath, extended);
595
596 script << "\t}" << "\n";
597 }
598
599 void ALMaterial::writePass(std::ostream& script, boost::filesystem::path expPath, bool extended)
600 {
601 bool hasAlphaBitmap = false;
602 if (mHaveAlphaDetails)
603 {
604 hasAlphaBitmap = mUseAlpha;
605 }
606 else
607 {
608 for (size_t n = 0; n < texInfo.size(); ++n)
609 {
610 //bmp files return an alpha value ?! but they dont have one...
611 boost::filesystem::path fpath(texInfo[n].path);
612 bool isBmp = (fpath.extension() == ".bmp") || (fpath.extension() == ".BMP");
613
614 if (!isBmp)
615 {
616 if (texInfo[n].type == aiTextureType_DIFFUSE)
617 {
618 try
619 {
620 Ogre::Image img;
621 std::string texPath = texInfo[n].path;
622 if (fpath.is_absolute())
623 {
624 try
625 {
626 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(fpath.parent_path().generic_string(), "FileSystem", mScene->getRessourceGroup());
627 texPath = fpath.filename().generic_string();
628 }
629 catch (Ogre::Exception&)
630 {
631 //not found
632 }
633 }
634 img.load(texPath, mScene->getRessourceGroup());
635 hasAlphaBitmap = img.getHasAlpha() && texInfo[n].useAlpha;
636 }
637 catch (Ogre::Exception &)
638 {
639 //image error
640 }
641 }
642 else if (texInfo[n].type == aiTextureType_OPACITY)
643 {
644 hasAlphaBitmap = true;
645 }
646 }
647 }
648 }
649
650 //Start render pass description
651 script << "\t\tpass ";
652 script << matInfo.name << "_";
653
654 script << "standard\n";
655
656 script << "\t\t{\n";
657
658 if (matInfo.isTwoSided)
659 {
660 script << "\t\t\tcull_hardware none\n";
661 }
662
663 //hack for points cloud
664 if (matInfo.isWire)
665 {
666 script << "\t\t\tpolygon_mode points\n";
667 script << "\t\t\tpolygon_mode_overrideable false\n";
668 script << "\t\t\tpoint_size 1.5\n";
669 }
670
674 //script << "\t\t\tshading phong\n";
675
676 if (matInfo.isVertexColor) //use vertex color for points cloud
677 script << "\t\t\tambient vertexcolour\n";
678 else if ((texCount.ambCount > 0) || (texCount.ambOccCount > 0)) // NOTE : If material has a ambient, diffuse, specular map, value should be (1,1,1,1);
679 script << "\t\t\tambient " << 1.0f << " " << 1.0f << " " << 1.0f << " " << matInfo.opacity << "\n";
680 else
681 script << "\t\t\tambient " << mColors.ambient.r << " " << mColors.ambient.g << " " << mColors.ambient.b << " " << mColors.ambient.a * matInfo.opacity << "\n";
682
683 //diffuse colour
684 if (matInfo.isVertexColor) //use vertex color for points cloud
685 script << "\t\t\tdiffuse vertexcolour\n";
686 else if (texCount.difCount > 0)
687 script << "\t\t\tdiffuse " << 1.0f << " " << 1.0f << " " << 1.0f << " " << matInfo.opacity << "\n";
688 else
689 script << "\t\t\tdiffuse " << mColors.diffuse.r << " " << mColors.diffuse.g << " " << mColors.diffuse.b << " " << mColors.diffuse.a * matInfo.opacity << "\n";
690
691 //specular colour and shininess
692 if (matInfo.shininess >= 0.f)
693 script << "\t\t\tspecular " << mColors.specular.r << " " << mColors.specular.g << " " << mColors.specular.b << " " << mColors.specular.a * matInfo.opacity << " " << matInfo.shininess << "\n";
694
695 //emissive colour
696 script << "\t\t\temissive " << mColors.emissive.r << " " << mColors.emissive.g << " " << mColors.emissive.b << " " << mColors.emissive.a * matInfo.opacity << "\n";
697
698 if (matInfo.opacity < 1.0f || (hasAlphaBitmap && !mCutout))
699 {
700 script << "\n\t\t\tscene_blend alpha_blend\n";
701 script << "\t\t\tdepth_write off\n";
702 }
703
704 if (mCutout)
705 script << "\n\t\t\talpha_rejection greater 128\n";
706
707 //write texture units
708 writeTextureUnit(script, expPath, extended);
709
710 script << "\t\t}" << "\n";
711 }
712
713 std::string ALMaterial::getTextureName(ALTextureData texData, bool full, bool& createTex)
714 {
715 std::string path(texData.path);
716 std::string tname = mScene->getTextureRef(path);
717 if (tname.empty())
718 {
719 tname = ALStringCleaner::cleanString(matInfo.name);
720
721 mScene->addTextureRef(tname, path);
722 createTex = true;
723 }
724
725 switch (texData.type)
726 {
727 case aiTextureType_AMBIENT:
728 tname = full ? "Ambient_" + tname : "Ambient";
729 break;
730 case aiTextureType_AMBIENT_OCCLUSION:
731 tname = full ? "Ambient_" + tname : "Ambient";
732 break;
733 case aiTextureType_LIGHTMAP:
734 tname = full ? "Lightmap_" + tname : "Lightmap";
735 break;
736 case aiTextureType_DIFFUSE:
737 tname = full ? "Diffuse_" + tname : "Diffuse";
738 break;
739 case aiTextureType_EMISSIVE:
740 tname = full ? "Emissive_" + tname : "Emissive";
741 break;
742 case aiTextureType_NORMALS:
743 tname = full ? "Normal_" + tname : "Normal";
744 break;
745 case aiTextureType_DISPLACEMENT:
746 tname = full ? "Displacement_" + tname : "Displacement";
747 break;
748 case aiTextureType_OPACITY:
749 tname = full ? "Opacity_" + tname : "Opacity";
750 break;
751 case aiTextureType_REFLECTION:
752 tname = full ? "Reflection_" + tname : "Reflection";
753 break;
754 case aiTextureType_SPECULAR:
755 tname = full ? "Specular_" + tname : "Specular";
756 break;
757 case aiTextureType_SHININESS:
758 tname = full ? "Shininess_" + tname : "Shininess";
759 break;
760 case aiTextureType_METALNESS:
761 tname = full ? "Metallic_" + tname : "Metallic";
762 break;
763 case aiTextureType_DIFFUSE_ROUGHNESS:
764 tname = full ? "Roughness_" + tname : "Roughness";
765 break;
766 }
767
768 return tname;
769 }
770
771 void ALMaterial::writeTextureUnit(std::ostream& script, boost::filesystem::path expPath, bool extended)
772 {
773 packdir mypack = (packdir)SCgetExtra("FirstPack");
774 boost::filesystem::path partitionPath(mypack->path);
775 partitionPath = partitionPath.generic_string();
776
777 for (size_t n = 0; n < texInfo.size(); ++n)
778 {
779 std::string filepath(texInfo[n].path);
780 filepath = filepath.substr(partitionPath.generic_string().length());
781
782 bool createTex = false;
783 std::string tname = getTextureName(texInfo[n], false, createTex);
784
785 switch (texInfo[n].type)
786 {
787 case aiTextureType_NORMALS:
788 case aiTextureType_DISPLACEMENT:
789 case aiTextureType_SPECULAR:
790 {
791 if (extended)
792 {
793 script << "\n\t\t\ttexture_unit ";
794 script << tname << "\n";
795 script << "\t\t\t{\n";
796 script << "\t\t\t\ttexture ";
797
798 script << filepath;
799
800 script << "\n";
801
802 // write texture coordinate set
803 script << "\t\t\t\ttex_coord_set " << texInfo[n].uvindex << "\n";
804
805 std::string oguv[3];
806 for (unsigned int iv = 0; iv < 3; ++iv)
807 {
808 switch (texInfo[n].mapmode[0])
809 {
810 case aiTextureMapMode_Wrap:
811 oguv[iv] = "wrap";
812 break;
813
814 case aiTextureMapMode_Clamp:
815 oguv[iv] = "clamp";
816 break;
817
818 case aiTextureMapMode_Mirror:
819 oguv[iv] = "mirror";
820 break;
821
822 case aiTextureMapMode_Decal:
823 oguv[iv] = "border";
824 break;
825
826 default:
827 oguv[iv] = "wrap";
828 }
829 }
830
831 script << "\t\t\t\ttex_address_mode " << oguv[0] << " " << oguv[1] << " " << oguv[2] << "\n";
832
833 script << "\t\t\t\tcolour_op ";
834 if (texInfo[n].op == aiTextureOp_Multiply)
835 script << "modulate";
836 else if (texInfo[n].op == aiTextureOp_Add)
837 script << "add";
838 else
839 script << "modulate"; //Ogre default
840
841 script << "\n";
842
843 // end texture unit desription
844 script << "\t\t\t}" << "\n";
845 }
846 break;
847 }
848
849 case aiTextureType_DIFFUSE:
850 case aiTextureType_AMBIENT:
851 case aiTextureType_AMBIENT_OCCLUSION:
852 case aiTextureType_LIGHTMAP:
853 case aiTextureType_EMISSIVE:
854 {
855 script << "\n\t\t\ttexture_unit ";
856 script << tname << "\n";
857 script << "\t\t\t{\n";
858 script << "\t\t\t\ttexture ";
859
860 script << filepath;
861
862 script << "\n";
863
864 // write texture coordinate set
865 script << "\t\t\t\ttex_coord_set " << texInfo[n].uvindex << "\n";
866
867 std::string oguv[3];
868 for (unsigned int iv = 0; iv < 3; ++iv)
869 {
870 switch (texInfo[n].mapmode[0])
871 {
872 case aiTextureMapMode_Wrap:
873 oguv[iv] = "wrap";
874 break;
875
876 case aiTextureMapMode_Clamp:
877 oguv[iv] = "clamp";
878 break;
879
880 case aiTextureMapMode_Mirror:
881 oguv[iv] = "mirror";
882 break;
883
884 case aiTextureMapMode_Decal:
885 oguv[iv] = "border";
886 break;
887
888 default:
889 oguv[iv] = "wrap";
890 }
891 }
892
893 script << "\t\t\t\ttex_address_mode " << oguv[0] << " " << oguv[1] << " " << oguv[2] << "\n";
894
895 script << "\t\t\t\tcolour_op ";
896 if (texInfo[n].op == aiTextureOp_Add || texInfo[n].type == aiTextureType_EMISSIVE)
897 script << "add";
898 else if (texInfo[n].op == aiTextureOp_Multiply)
899 script << "modulate";
900 else
901 script << "modulate"; //Ogre default
902
903 script << "\n";
904
905 // end texture unit desription
906 script << "\t\t\t}" << "\n";
907 break;
908 }
909
910 case aiTextureType_REFLECTION:
911 {
912 bool hasCubicReflection = false;
913 try
914 {
915 Ogre::Image img;
916 img.load(texInfo[n].path, mScene->getRessourceGroup());
917 if (img.getNumFaces() == 6)
918 hasCubicReflection = true;
919 }
920 catch (Ogre::Exception &)
921 {
922 //image error
923 }
924
925 script << "\n\t\t\ttexture_unit ";
926 script << tname << (hasCubicReflection ? " cubic\n" : "\n");
927 script << "\t\t\t{\n";
928 script << "\t\t\t\ttexture ";
929
930 script << filepath;
931
932 if (hasCubicReflection)
933 script << " cubic";
934
935 script << "\n";
936
937 // write texture coordinate set
938 script << "\t\t\t\ttex_coord_set " << texInfo[n].uvindex << "\n";
939
940 std::string oguv[3];
941 for (unsigned int iv = 0; iv < 3; ++iv)
942 {
943 switch (texInfo[n].mapmode[0])
944 {
945 case aiTextureMapMode_Wrap:
946 oguv[iv] = "wrap";
947 break;
948
949 case aiTextureMapMode_Clamp:
950 oguv[iv] = "clamp";
951 break;
952
953 case aiTextureMapMode_Mirror:
954 oguv[iv] = "mirror";
955 break;
956
957 case aiTextureMapMode_Decal:
958 oguv[iv] = "border";
959 break;
960
961 default:
962 oguv[iv] = "wrap";
963 }
964 }
965
966 script << "\t\t\t\ttex_address_mode " << oguv[0] << " " << oguv[1] << " " << oguv[2] << "\n";
967
968 script << "\t\t\t\tcolour_op ";
969 if (texInfo[n].op == aiTextureOp_Multiply)
970 script << "modulate";
971 else if (texInfo[n].op == aiTextureOp_Add)
972 script << "add";
973 else
974 script << "modulate"; //Ogre default
975
976 script << "\n";
977
978 if (hasCubicReflection)
979 script << "\t\t\t\tenv_map cubic_reflection\n";
980 else
981 {
982 switch (texInfo[n].mapping)
983 {
984 case aiTextureMapping_PLANE:
985 script << "\t\t\t\tenv_map planar\n";
986 break;
987
988 case aiTextureMapping_SPHERE:
989 script << "\t\t\t\tenv_map spherical\n";
990 break;
991
992 case aiTextureMapping_CYLINDER:
993 script << "\t\t\t\tenv_map spherical\n";
994 break;
995
996 default:
997 script << "\t\t\t\tenv_map planar\n";
998 break;
999 }
1000 }
1001 // end texture unit desription
1002 script << "\t\t\t}" << "\n";
1003 break;
1004 }
1005
1006 case aiTextureType_DIFFUSE_ROUGHNESS:
1007 case aiTextureType_METALNESS:
1008 {
1009 if (extended)
1010 {
1011 script << "\n\t\t\ttexture_unit ";
1012 script << tname << "\n";
1013 script << "\t\t\t{\n";
1014 script << "\t\t\t\ttexture ";
1015
1016 script << filepath;
1017
1018 script << "\n";
1019
1020 // write texture coordinate set
1021 script << "\t\t\t\ttex_coord_set " << texInfo[n].uvindex << "\n";
1022
1023 std::string oguv[3];
1024 for (unsigned int iv = 0; iv < 3; ++iv)
1025 {
1026 switch (texInfo[n].mapmode[0])
1027 {
1028 case aiTextureMapMode_Wrap:
1029 oguv[iv] = "wrap";
1030 break;
1031
1032 case aiTextureMapMode_Clamp:
1033 oguv[iv] = "clamp";
1034 break;
1035
1036 case aiTextureMapMode_Mirror:
1037 oguv[iv] = "mirror";
1038 break;
1039
1040 case aiTextureMapMode_Decal:
1041 oguv[iv] = "border";
1042 break;
1043
1044 default:
1045 oguv[iv] = "wrap";
1046 }
1047 }
1048
1049 script << "\t\t\t\ttex_address_mode " << oguv[0] << " " << oguv[1] << " " << oguv[2] << "\n";
1050
1051 script << "\t\t\t\tcolour_op ";
1052 if (texInfo[n].op == aiTextureOp_Multiply)
1053 script << "modulate";
1054 else if (texInfo[n].op == aiTextureOp_Add)
1055 script << "add";
1056 else
1057 script << "add"; // PBS default
1058
1059 script << "\n";
1060
1061 // end texture unit desription
1062 script << "\t\t\t}" << "\n";
1063 }
1064 break;
1065 }
1066
1067 case aiTextureType_OPACITY:
1068 {
1069 script << "\n\t\t\ttexture_unit ";
1070 script << tname << "\n";
1071 script << "\t\t\t{\n";
1072 script << "\t\t\t\ttexture ";
1073
1074 script << filepath;
1075
1076 script << "\n";
1077
1078 // write texture coordinate set
1079 script << "\t\t\t\ttex_coord_set " << texInfo[n].uvindex << "\n";
1080
1081 std::string oguv[3];
1082 for (unsigned int iv = 0; iv < 3; ++iv)
1083 {
1084 switch (texInfo[n].mapmode[0])
1085 {
1086 case aiTextureMapMode_Wrap:
1087 oguv[iv] = "wrap";
1088 break;
1089
1090 case aiTextureMapMode_Clamp:
1091 oguv[iv] = "clamp";
1092 break;
1093
1094 case aiTextureMapMode_Mirror:
1095 oguv[iv] = "mirror";
1096 break;
1097
1098 case aiTextureMapMode_Decal:
1099 oguv[iv] = "border";
1100 break;
1101
1102 default:
1103 oguv[iv] = "wrap";
1104 }
1105 }
1106
1107 script << "\t\t\t\ttex_address_mode " << oguv[0] << " " << oguv[1] << " " << oguv[2] << "\n";
1108
1109 script << "\t\t\t\tcolour_op ";
1110 if (texInfo[n].op == aiTextureOp_Multiply)
1111 script << "modulate";
1112 else if (texInfo[n].op == aiTextureOp_Add)
1113 script << "add";
1114 else
1115 script << "alpha_blend"; //Ogre default
1116
1117 script << "\n";
1118
1119 // end texture unit desription
1120 script << "\t\t\t}" << "\n";
1121 break;
1122 }
1123 default:
1124 break;
1125 }
1126 }
1127 }
1128
1129 std::string ALMaterial::convert(boost::filesystem::path expPath, bool clearFile)
1130 {
1131 // Get & build all the data related to this material.
1132 getMatInfo();
1133 getColorInfo();
1134
1135 // Build the textures data.
1136 getTexturesCount();
1137 getTexturesInfo();
1138
1139 // If we want to export them, copy & change their path.
1140 for (size_t n = 0; n < texInfo.size(); ++n)
1141 manageTexturePath(&texInfo[n], expPath);
1142
1143 // The path pointing to where to write the material file.
1144 std::string outPath;
1145 outPath = expPath.generic_string();
1146 if (outPath.back() != '/')
1147 outPath.push_back('/');
1148 outPath += "materials/";
1149 outPath += mScene->getSceneName() + ".material";
1150
1151 // The material script.
1152 std::ofstream script;
1153 if (clearFile)
1154 script.open(outPath, std::ofstream::out | std::ofstream::trunc);
1155 else
1156 script.open(outPath, std::ofstream::out | std::ofstream::app | std::ofstream::ate);
1157
1158 script.precision(8);
1159 script.setf(std::ios::fixed, std::ios::floatfield);
1160 writeOgreScript(script, expPath);
1161 script.close();
1162
1163 return matInfo.name;
1164 }
1165
1166 STexture* ALMaterial::createOrRetrieveTexture(std::string name, std::string path, bool create)
1167 {
1168 STexture *texture = 0;
1169 if (create)
1170 {
1171 try
1172 {
1173 texture = mScene->getSScene()->CreateTexture(mScene->getRessourceGroup(), name, path);
1174 }
1175 catch (SO3::SException&)
1176 {
1177 }
1178 }
1179
1180 //not found try to get an existed one
1181 if (!texture)
1182 texture = mScene->getSScene()->GetTexture(mScene->getRessourceGroup(), name);
1183
1184 // still not found, try to create it, the name must differ or it has not be used yet
1185 if (!texture && !create)
1186 {
1187 try
1188 {
1189 texture = mScene->getSScene()->CreateTexture(mScene->getRessourceGroup(), name, path);
1190 }
1191 catch (SO3::SException&)
1192 {
1193 }
1194 }
1195
1196 return texture;
1197 }
1198
1199 STexture* ALMaterial::createOrRetrieveTexture(std::string name, Ogre::Image image, bool create)
1200 {
1201 STexture *texture = 0;
1202 if (create)
1203 {
1204 try
1205 {
1206 texture = mScene->getSScene()->CreateTexture(mScene->getRessourceGroup(), name, image);
1207 }
1208 catch (SO3::SException&)
1209 {
1210 }
1211 }
1212
1213 //not found try to get an existed one
1214 if (!texture)
1215 texture = mScene->getSScene()->GetTexture(mScene->getRessourceGroup(), name);
1216
1217 // still not found, try to create it, the name must differ or it has not be used yet
1218 if (!texture && !create)
1219 {
1220 try
1221 {
1222 texture = mScene->getSScene()->CreateTexture(mScene->getRessourceGroup(), name, image);
1223 }
1224 catch (SO3::SException&)
1225 {
1226 }
1227 }
1228
1229 return texture;
1230 }
1231
1232 STexture* ALMaterial::loadTexture(ALTextureData* texData, std::string tname, bool createTex, bool &isCubic)
1233 {
1234 STexture* texture = 0;
1235
1236 if (texData->embedded)
1237 {
1238 if (const aiTexture* aitexture = mScene->getAiScene()->GetEmbeddedTexture(texData->embname.c_str()))
1239 {
1240 if (!aitexture->mHeight)
1241 {
1242 Ogre::Image image;
1243 try
1244 {
1245 std::string ext = boost::filesystem::extension(texData->path).substr(1);
1246 Ogre::DataStreamPtr data_stream(new Ogre::MemoryDataStream(texData->path, aitexture->pcData, aitexture->mWidth, false, true));
1247 image.load(data_stream, ext);
1248 if (image.getNumFaces() == 6)
1249 isCubic = true;
1250 texture = createOrRetrieveTexture(tname, image, createTex);
1251 }
1252 catch (Ogre::Exception &e)
1253 {
1254 std::cerr << "Texture loading failed! : " << e.what() << std::endl;
1255 }
1256 }
1257 }
1258 else
1259 {
1260 try
1261 {
1262 std::string format(aitexture->achFormatHint);
1263 Ogre::PixelFormat oformat = Ogre::PF_UNKNOWN;
1264 if (format == "argb8888")
1265 oformat = Ogre::PF_A8R8G8B8;
1266 else if (format == "rgba8888")
1267 oformat = Ogre::PF_R8G8B8A8;
1268 else if (format == "rgb888")
1269 oformat = Ogre::PF_R8G8B8;
1270 else if (format == "bgr888")
1271 oformat = Ogre::PF_B8G8R8;
1272 else if (format == "rgba5650")
1273 oformat = Ogre::PF_R5G6B5;
1274
1275 if (oformat != Ogre::PF_UNKNOWN)
1276 {
1277 Ogre::Image image;
1278 image.loadDynamicImage((uchar*)aitexture->pcData, aitexture->mWidth, aitexture->mHeight, oformat);
1279 if (image.getNumFaces() == 6)
1280 isCubic = true;
1281 texture = createOrRetrieveTexture(tname, image, createTex);
1282 }
1283 }
1284 catch (Ogre::Exception &e)
1285 {
1286 std::cerr << "Texture loading failed! : " << e.what() << std::endl;
1287 }
1288 }
1289 }
1290 else
1291 {
1292 try
1293 {
1294 Ogre::Image img;
1295 img.load(texData->path, mScene->getRessourceGroup());
1296 if (img.getNumFaces() == 6)
1297 isCubic = true;
1298 }
1299 catch (Ogre::Exception &)
1300 {
1301 //image error
1302 }
1303
1304 texture = createOrRetrieveTexture(tname, texData->path, createTex);
1305 }
1306
1307 return texture;
1308 }
1309
1311 {
1312 // Get & build all the data related to this material.
1313 getMatInfo();
1314 getColorInfo();
1315
1316 // Build the textures data.
1317 getTexturesCount();
1318 getTexturesInfo();
1319
1320 SMaterial* mat = mScene->getSScene()->GetMaterial(mScene->getRessourceGroup(), matInfo.name);
1321
1322 // already exist use it
1323 if (mat != 0)
1324 return mat;
1325
1326 // try to create the material
1327 try
1328 {
1329 mat = mScene->getSScene()->CreateMaterial(mScene->getRessourceGroup(), matInfo.name);
1330 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(mScene->getRessourcePath(), "FileSystem", mScene->getRessourceGroup());
1331 }
1332 catch (SException &)
1333 {
1334 //std::cerr << "Name already in system or group not existing : " << e.GetFullDescription() << std::endl;
1335 return 0;
1336 }
1337
1338 unsigned int nbTech = mat->GetNumTechniques();
1339 for (unsigned int n = 0; n < nbTech; ++n)
1340 {
1341 STechnique* tech = mat->GetTechnique(n);
1342
1343 unsigned int nbPass = tech->GetNumPasses();
1344 for (unsigned int n = 0; n < nbPass; ++n)
1345 {
1346 SPass* pass = tech->GetPass(n);
1347 if (!pass)
1348 continue;
1349
1350 //hack for points cloud
1351 if (matInfo.isWire)
1352 {
1354 pass->SetPointSize(1.5f);
1355 }
1356
1357 if (matInfo.isVertexColor)
1358 {
1359 pass->SetUseVertexColor(true);
1360 }
1361 else
1362 {
1363 Ogre::ColourValue ambcolor(mColors.ambient.r, mColors.ambient.g, mColors.ambient.b, mColors.ambient.a * matInfo.opacity);
1364 Ogre::ColourValue diffcolor(mColors.diffuse.r, mColors.diffuse.g, mColors.diffuse.b, mColors.diffuse.a * matInfo.opacity);
1365
1366 if (texCount.ambCount > 0)
1367 ambcolor = Ogre::ColourValue(1.0f, 1.0f, 1.0f, matInfo.opacity);
1368
1369 if (texCount.difCount > 0)
1370 diffcolor = Ogre::ColourValue(1.0f, 1.0f, 1.0f, matInfo.opacity);
1371
1372 pass->SetAmbientColor(ambcolor);
1373 pass->SetDiffuseColor(diffcolor);
1374 }
1375
1376 pass->SetSelfIlluminationColor(Ogre::ColourValue(mColors.emissive.r, mColors.emissive.g, mColors.emissive.b, mColors.emissive.a * matInfo.opacity));
1377
1378 if (matInfo.shininess >= 0.f)
1379 {
1380 pass->SetShininess(matInfo.shininess);
1381 pass->SetSpecularColor(Ogre::ColourValue(mColors.specular.r, mColors.specular.g, mColors.specular.b, mColors.specular.a * matInfo.opacity));
1382 }
1383 else
1384 pass->SetShininess(2.f);
1385
1386 bool hasAlphaBitmap = false;
1387 if (mHaveAlphaDetails)
1388 {
1389 hasAlphaBitmap = mUseAlpha;
1390 }
1391 else
1392 {
1393 for (size_t n = 0; n < texInfo.size(); ++n)
1394 {
1395 if (texInfo[n].type == aiTextureType_DIFFUSE)
1396 {
1397 try
1398 {
1399 Ogre::Image img;
1400 boost::filesystem::path fpath(texInfo[n].path);
1401 std::string texPath = texInfo[n].path;
1402 if (fpath.is_absolute())
1403 {
1404 try
1405 {
1406 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(fpath.parent_path().generic_string(), "FileSystem", mScene->getRessourceGroup());
1407 texPath = fpath.filename().generic_string();
1408 }
1409 catch (Ogre::Exception&)
1410 {
1411 //not found
1412 }
1413 }
1414 img.load(texPath, mScene->getRessourceGroup());
1415 hasAlphaBitmap = img.getHasAlpha() && texInfo[n].useAlpha;
1416 }
1417 catch (Ogre::Exception &)
1418 {
1419 //image error
1420 }
1421
1422 }
1423 else if (texInfo[n].type == aiTextureType_OPACITY)
1424 {
1425 hasAlphaBitmap = true;
1426 }
1427 }
1428 }
1429
1430 if (matInfo.opacity < 1.0f || (hasAlphaBitmap && !mCutout))
1431 {
1433 pass->SetDepthWriteEnabled(false);
1434 }
1435
1436 if (mCutout)
1438
1439 unsigned int texIndex = 0;
1440 bool createTex = false;
1441 bool ignore = false;
1442 for (size_t n = 0; n < texInfo.size(); ++n)
1443 {
1444 std::string tname = getTextureName(texInfo[n], true, createTex);
1445 std::string unitname = getTextureName(texInfo[n], false, ignore);
1446 ALTextureData* texData = &texInfo[n];
1447
1448 std::string path(texData->path);
1449 boost::filesystem::path fpath(path);
1450 if (fpath.is_absolute())
1451 {
1452 try
1453 {
1454 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(fpath.parent_path().generic_string(), "FileSystem", mScene->getRessourceGroup());
1455 path = fpath.filename().generic_string();
1456 }
1457 catch (Ogre::Exception&)
1458 {
1459 //not found
1460 }
1461 }
1462
1463 switch (texData->type)
1464 {
1465 case aiTextureType_NORMALS:
1466 case aiTextureType_DISPLACEMENT:
1467 case aiTextureType_SPECULAR:
1468 case aiTextureType_DIFFUSE:
1469 case aiTextureType_DIFFUSE_ROUGHNESS:
1470 case aiTextureType_AMBIENT:
1471 case aiTextureType_AMBIENT_OCCLUSION:
1472 case aiTextureType_LIGHTMAP:
1473 case aiTextureType_EMISSIVE:
1474 case aiTextureType_METALNESS:
1475 {
1476 bool isCubic = false;
1477 STexture* texture = loadTexture(texData, tname, createTex, isCubic);
1478
1479 //not found
1480 if (!texture)
1481 break;
1482
1483 try
1484 {
1485 pass->SetTexture(texIndex, texture, unitname);
1486 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureCoordSet(texData->uvindex);
1487
1488 Ogre::TextureAddressingMode oguv[3];
1489 for (unsigned int iv = 0; iv < 3; ++iv)
1490 {
1491 switch (texData->mapmode[0])
1492 {
1493 case aiTextureMapMode_Wrap:
1494 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1495 break;
1496
1497 case aiTextureMapMode_Clamp:
1498 oguv[iv] = Ogre::TextureUnitState::TAM_CLAMP;
1499 break;
1500
1501 case aiTextureMapMode_Mirror:
1502 oguv[iv] = Ogre::TextureUnitState::TAM_MIRROR;
1503 break;
1504
1505 case aiTextureMapMode_Decal:
1506 oguv[iv] = Ogre::TextureUnitState::TAM_BORDER;
1507 break;
1508
1509 default:
1510 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1511 }
1512 }
1513
1514 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureAddressingMode(oguv[0], oguv[1], oguv[2]);
1515
1516 if (texData->op == aiTextureOp_Multiply)
1517 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_MODULATE);
1518 else if (texData->op == aiTextureOp_Add || texData->type == aiTextureType_METALNESS || texData->type == aiTextureType_DIFFUSE_ROUGHNESS || texData->type == aiTextureType_EMISSIVE)
1519 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_ADD);
1520 else
1521 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_MODULATE);
1522
1523 texIndex++;
1524 }
1525 catch (Ogre::Exception&)
1526 {
1527 // file not found
1528 }
1529 break;
1530 }
1531
1532 case aiTextureType_REFLECTION:
1533 {
1534 bool isCubic = false;
1535 STexture* texture = loadTexture(texData, tname, createTex, isCubic);
1536
1537 //not found
1538 if (!texture)
1539 break;
1540
1541 try
1542 {
1543 pass->SetTexture(texIndex, texture, unitname);
1544 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureCoordSet(texData->uvindex);
1545
1546 if (isCubic)
1547 texture->getOgreTexturePointer()->setTextureType(Ogre::TEX_TYPE_CUBE_MAP);
1548
1549 Ogre::TextureAddressingMode oguv[3];
1550 for (unsigned int iv = 0; iv < 3; ++iv)
1551 {
1552 switch (texData->mapmode[0])
1553 {
1554 case aiTextureMapMode_Wrap:
1555 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1556 break;
1557
1558 case aiTextureMapMode_Clamp:
1559 oguv[iv] = Ogre::TextureUnitState::TAM_CLAMP;
1560 break;
1561
1562 case aiTextureMapMode_Mirror:
1563 oguv[iv] = Ogre::TextureUnitState::TAM_MIRROR;
1564 break;
1565
1566 case aiTextureMapMode_Decal:
1567 oguv[iv] = Ogre::TextureUnitState::TAM_BORDER;
1568 break;
1569
1570 default:
1571 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1572 }
1573 }
1574
1575 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureAddressingMode(oguv[0], oguv[1], oguv[2]);
1576
1577 if (texData->op == aiTextureOp_Multiply)
1578 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_MODULATE);
1579 else if (texData->op == aiTextureOp_Add)
1580 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_ADD);
1581 else
1582 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_MODULATE);
1583
1584 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setEnvironmentMap(true, isCubic ? Ogre::TextureUnitState::ENV_REFLECTION : Ogre::TextureUnitState::ENV_PLANAR);
1585
1586 texIndex++;
1587 }
1588 catch (Ogre::Exception&)
1589 {
1590 //texture not found
1591 }
1592 break;
1593 }
1594
1595 case aiTextureType_OPACITY:
1596 {
1597 bool isCubic = false;
1598 STexture* texture = loadTexture(texData, tname, createTex, isCubic);
1599
1600 //not found
1601 if (!texture)
1602 break;
1603
1604 try
1605 {
1606 pass->SetTexture(texIndex, texture, unitname);
1607 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureCoordSet(texData->uvindex);
1608
1609 Ogre::TextureAddressingMode oguv[3];
1610 for (unsigned int iv = 0; iv < 3; ++iv)
1611 {
1612 switch (texData->mapmode[0])
1613 {
1614 case aiTextureMapMode_Wrap:
1615 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1616 break;
1617
1618 case aiTextureMapMode_Clamp:
1619 oguv[iv] = Ogre::TextureUnitState::TAM_CLAMP;
1620 break;
1621
1622 case aiTextureMapMode_Mirror:
1623 oguv[iv] = Ogre::TextureUnitState::TAM_MIRROR;
1624 break;
1625
1626 case aiTextureMapMode_Decal:
1627 oguv[iv] = Ogre::TextureUnitState::TAM_BORDER;
1628 break;
1629
1630 default:
1631 oguv[iv] = Ogre::TextureUnitState::TAM_WRAP;
1632 }
1633 }
1634
1635 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setTextureAddressingMode(oguv[0], oguv[1], oguv[2]);
1636
1637 if (texData->op == aiTextureOp_Multiply)
1638 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_MODULATE);
1639 else if (texData->op == aiTextureOp_Add)
1640 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_ADD);
1641 else
1642 pass->GetOgrePassPointer()->getTextureUnitState(texIndex)->setColourOperation(Ogre::LBO_ALPHA_BLEND);
1643
1644 texIndex++;
1645 }
1646 catch (Ogre::Exception&)
1647 {
1648 //file not found
1649 }
1650 break;
1651 }
1652
1653 default:
1654 break;
1655 }
1656 }
1657
1659 pass->BuildShader(true);
1660 }
1661 }
1662
1663 return mat;
1664 }
1665}
static std::string cleanString(std::string str, bool toLower=true, bool clASCII=true, bool clSpaces=true, bool bUID=true)
Clean a string.
SMaterial * load()
std::string convert(boost::filesystem::path expPath, bool clearFile=false)
ALMaterial(ALScene *alscene, aiMaterial *srcMaterial, bool useVertexColor=false)
std::string getRessourceGroup()
Definition ALScene.cpp:497
SScene * getSScene()
Definition ALScene.cpp:487
ALSceneLoader * GetSceneLoader()
Definition ALScene.h:98
const aiScene * getAiScene()
Definition ALScene.cpp:492
bool addTextureRef(std::string name, std::string path)
Definition ALScene.cpp:468
std::string getSceneName()
Definition ALScene.cpp:507
std::string getTextureRef(std::string path)
Definition ALScene.cpp:478
std::string getRessourcePath()
Definition ALScene.cpp:502
unsigned int getFlags()
static std::string GetValidImageExtension(std::string ext)
static bool SaveOgreImage(Ogre::Image &image, boost::filesystem::path &path)
Base class for SO3 custom exception.
STechnique * GetTechnique(const unsigned int &technique)
void SetPolygonMode(PolygonMode mode)
Definition SO3Pass.cpp:1056
void SetPointSize(Ogre::Real size)
Definition SO3Pass.cpp:1031
@ SO3_COMPARE_FUNCTION_GREATER
Definition SO3Pass.h:81
void SetSelfIlluminationColor(const int &color)
Definition SO3Pass.cpp:536
void SetShininess(const float &value)
Definition SO3Pass.cpp:555
void BuildShader(bool force=false)
Definition SO3Pass.cpp:165
void SetAmbientColor(const int &color)
Definition SO3Pass.cpp:479
@ SO3_POLYGONMODE_POINTS
Definition SO3Pass.h:47
void SetSpecularColor(const int &color)
Definition SO3Pass.cpp:517
void SetAlphaRejection(CompareFunction func, unsigned char value, bool alphaToCoverageEnabled=false)
Definition SO3Pass.cpp:979
void SetSceneBlending(const SPass::SceneBlendFactor sourceFactor, const SPass::SceneBlendFactor destFactor)
Definition SO3Pass.cpp:906
void SetDepthWriteEnabled(bool enabled)
Definition SO3Pass.cpp:954
void SetUseVertexColor(bool state)
Definition SO3Pass.cpp:570
void OrderTexturesUnitsByType()
Definition SO3Pass.cpp:1130
void SetTexture(const unsigned int &textureUnit, STexture *texture, std::string name="")
Definition SO3Pass.cpp:585
void SetDiffuseColor(const int &color)
Definition SO3Pass.cpp:498
Ogre::Pass * GetOgrePassPointer()
Definition SO3Pass.cpp:272
@ SO3_SCENE_BLEND_FACTOR_SOURCE_ALPHA
Definition SO3Pass.h:68
@ SO3_SCENE_BLEND_FACTOR_ONE_MINUS_SOURCE_ALPHA
Definition SO3Pass.h:70
STexture * CreateTexture(const std::string &groupname, const std::string &texname, const std::string &path, const int &w=0, const int &h=0)
SMaterial * GetMaterial(const std::string &groupName, const std::string &materialName, bool searchOtherGroups=true)
STexture * GetTexture(const std::string &groupName, const std::string &texName)
SMaterial * CreateMaterial(const std::string &groupname, const std::string &matname, const bool &loadedFromScript=false)
SPass * GetPass(const unsigned int &pass)
Ogre::TexturePtr getOgreTexturePointer()
aiColor4D specular
Definition ALMaterial.h:17
aiColor4D emissive
Definition ALMaterial.h:19
aiColor4D transparence
Definition ALMaterial.h:20
aiColor4D ambient
Definition ALMaterial.h:18
aiColor4D diffuse
Definition ALMaterial.h:16
std::string name
Definition ALMaterial.h:26
float reflectivity
Definition ALMaterial.h:30
Contain the texture's meta-data.
Definition ALMaterial.h:39
std::string embname
Definition ALMaterial.h:41
aiTextureType type
Definition ALMaterial.h:43
aiTextureMapMode mapmode[3]
Definition ALMaterial.h:49
aiTextureOp op
Definition ALMaterial.h:48
std::string path
Definition ALMaterial.h:40
unsigned int uvindex
Definition ALMaterial.h:45