source: OGRE/trunk/ogrenew/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp @ 692

Revision 692, 26.7 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreXSIMaterialExporter.h"
26#include "OgreMaterialManager.h"
27#include "OgreMaterial.h"
28#include "OgreTechnique.h"
29#include "OgrePass.h"
30#include "OgreTextureUnitState.h"
31
32#include <xsi_shader.h>
33#include <xsi_imageclip.h>
34#include <xsi_image.h>
35
36
37namespace Ogre {
38
39        //-------------------------------------------------------------------------
40        XsiMaterialExporter::XsiMaterialExporter()
41        {
42
43        }
44        //-------------------------------------------------------------------------
45        XsiMaterialExporter::~XsiMaterialExporter()
46        {
47                clearPassQueue();
48        }
49        //-------------------------------------------------------------------------
50        void XsiMaterialExporter::exportMaterials(MaterialMap& materials,
51                TextureProjectionMap& texProjMap, const String& filename,
52                bool copyTextures)
53        {
54                LogOgreAndXSI("** Begin OGRE Material Export **");
55               
56                mTextureProjectionMap = texProjMap;
57
58                String texturePath;
59                if (copyTextures)
60                {
61                        // derive the texture path
62                        String::size_type pos = filename.find_last_of("\\");
63                        if (pos == String::npos)
64                        {
65                                pos = filename.find_last_of("/");                       
66                        }
67                        if (pos != String::npos)
68                        {
69                                texturePath = filename.substr(0, pos + 1);
70                        }
71                }
72               
73                mMatSerializer.clearQueue();
74
75                for (MaterialMap::iterator m = materials.begin(); m != materials.end(); ++m)
76                {
77                        exportMaterial(m->second, copyTextures, texturePath);
78                }
79
80                mMatSerializer.exportQueued(filename);
81
82                LogOgreAndXSI("** OGRE Material Export Complete **");
83        }
84        //-------------------------------------------------------------------------
85        void XsiMaterialExporter::exportMaterial(MaterialEntry* matEntry,
86                bool copyTextures, const String& texturePath)
87        {
88                LogOgreAndXSI("Exporting " + matEntry->name);
89
90                MaterialPtr mat = MaterialManager::getSingleton().create(
91                        matEntry->name,
92                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
93                Technique* t = mat->createTechnique();
94
95                // collect the passes into our queue
96                // XSI stores passes in reverse order, so invert them
97                clearPassQueue();
98                XSI::Shader shader(matEntry->xsiShader);
99                PassEntry* passEntry = new PassEntry();
100                mPassQueue.push_front(passEntry);
101                while (1)
102                {
103                        passEntry->shaders.Add(shader);
104
105                        XSI::CRef source = shader.GetParameter(L"previous").GetSource();
106                        if(!source.IsValid() || !source.IsA(XSI::siShaderID))
107                        {
108                                // finish
109                                break;
110                        }
111
112                        shader = XSI::Shader(source);
113                        // If we find a 'blending' parameter, we're on a new pass
114                        if (shader.GetParameter(L"blending").IsValid())
115                        {
116                                passEntry = new PassEntry();
117                                mPassQueue.push_front(passEntry); // push front to invert order
118                        }
119                }
120
121
122                // Now go through each pass and create OGRE version
123                for (PassQueue::iterator p = mPassQueue.begin(); p != mPassQueue.end(); ++p)
124                {
125                        PassEntry* passEntry = *p;
126                        Pass* pass = t->createPass();
127                        LogOgreAndXSI("Added Pass");
128
129                        // Need to pre-populate pass textures to match up transforms
130                        populatePassTextures(pass, passEntry, copyTextures, texturePath);
131                        // Do the rest
132                        for (int s = 0; s < passEntry->shaders.GetCount(); ++s)
133                        {
134                                XSI::Shader shader(passEntry->shaders[s]);
135                                populatePass(pass, shader);
136                        }
137
138                }
139
140
141                mMatSerializer.queueForExport(mat);
142               
143
144        }
145        //-------------------------------------------------------------------------
146        void XsiMaterialExporter::clearPassQueue(void)
147        {
148                for (PassQueue::iterator i = mPassQueue.begin(); i != mPassQueue.end(); ++i)
149                {
150                        delete *i;
151                }
152                mPassQueue.clear();
153
154        }
155        //-------------------------------------------------------------------------
156        void XsiMaterialExporter::populatePass(Pass* pass, XSI::Shader& xsishader)
157        {
158                populatePassDepthCull(pass, xsishader);
159                populatePassSceneBlend(pass, xsishader);
160                populatePassLighting(pass, xsishader);
161                populatePassTextureTransforms(pass, xsishader);
162                populatePassCgPrograms(pass, xsishader);
163                populatePassHLSLPrograms(pass, xsishader);
164                populatePassD3DAssemblerPrograms(pass, xsishader);
165        }
166        //-------------------------------------------------------------------------
167        void XsiMaterialExporter::populatePassCgPrograms(Pass* pass,
168                XSI::Shader& xsishader)
169        {
170                XSI::Parameter param = xsishader.GetParameter(L"Cg_Program");
171                if (param.IsValid())
172                {
173                        // TODO
174                        // XSI can't reference external files which makes it v.difficult to
175                        // re-use shaders - mod XSI plugin?
176                }
177        }
178        //-------------------------------------------------------------------------
179        void XsiMaterialExporter::populatePassHLSLPrograms(Pass* pass,
180                XSI::Shader& xsishader)
181        {
182                XSI::Parameter param = xsishader.GetParameter(L"HLSL_Program");
183                if (param.IsValid())
184                {
185                        // TODO
186                        // XSI can't reference external files which makes it v.difficult to
187                        // re-use shaders - mod XSI plugin?
188                }
189        }
190        //-------------------------------------------------------------------------
191        void XsiMaterialExporter::populatePassD3DAssemblerPrograms(Pass* pass,
192                XSI::Shader& xsishader)
193        {
194                XSI::Parameter param = xsishader.GetParameter(L"Vertex_Shader");
195                if (param.IsValid())
196                {
197                        // TODO
198                        // XSI can't reference external files which makes it v.difficult to
199                        // re-use shaders - mod XSI plugin?
200                }
201                param = xsishader.GetParameter(L"Pixel_Shader");
202                if (param.IsValid())
203                {
204                        // TODO
205                        // XSI can't reference external files which makes it v.difficult to
206                        // re-use shaders - mod XSI plugin?
207                }
208        }
209        //-------------------------------------------------------------------------
210        void XsiMaterialExporter::populatePassDepthCull(Pass* pass,
211                XSI::Shader& xsishader)
212        {
213                XSI::Parameter param = xsishader.GetParameter(L"cullingmode");
214                if (param.IsValid())
215                {
216                        short xsiCull = param.GetValue();
217                        switch (xsiCull)
218                        {
219                        case 0:
220                                pass->setCullingMode(CULL_NONE);
221                                pass->setManualCullingMode(MANUAL_CULL_NONE);
222                                break;
223                        case 1:
224                                pass->setCullingMode(CULL_CLOCKWISE);
225                                pass->setManualCullingMode(MANUAL_CULL_BACK);
226                                break;
227                        case 2:
228                                pass->setCullingMode(CULL_ANTICLOCKWISE);
229                                pass->setManualCullingMode(MANUAL_CULL_FRONT);
230                                break;
231                                       
232                        };
233                }       
234
235                param = xsishader.GetParameter(L"depthtest");
236                if (param.IsValid())
237                {
238                        bool depthTest = param.GetValue();
239                        pass->setDepthCheckEnabled(depthTest);
240                }
241                param = xsishader.GetParameter(L"depthwrite");
242                if (param.IsValid())
243                {
244                        bool depthWrite = param.GetValue();
245                        pass->setDepthWriteEnabled(depthWrite);
246                }
247        }
248        //-------------------------------------------------------------------------
249        void XsiMaterialExporter::populatePassSceneBlend(Pass* pass,
250                XSI::Shader& xsishader)
251        {
252                XSI::Parameter param = xsishader.GetParameter(L"blending");
253                if (param.IsValid() && (bool)param.GetValue())
254                {
255                        SceneBlendFactor src = SBF_ONE;
256                        SceneBlendFactor dst = SBF_ONE;
257                       
258                        param = xsishader.GetParameter(L"srcblendingfunction");
259                        if (param.IsValid())
260                        {
261                                src = convertSceneBlend(param.GetValue());
262                        }
263                        param = xsishader.GetParameter(L"dstblendingfunction");
264                        if (param.IsValid())
265                        {
266                                dst = convertSceneBlend(param.GetValue());
267                        }
268
269                        pass->setSceneBlending(src, dst);
270                }
271        }
272        //-------------------------------------------------------------------------
273        void XsiMaterialExporter::populatePassLighting(Pass* pass,
274                XSI::Shader& xsishader)
275        {
276                XSI::Parameter param = xsishader.GetParameter(L"Enable_Lighting");
277                if (param.IsValid())
278                {
279                        pass->setLightingEnabled(param.GetValue());
280
281                        ColourValue tmpColour;
282                        xsishader.GetColorParameterValue(L"Ambient", tmpColour.r, tmpColour.g,
283                                tmpColour.b, tmpColour.a);
284                        pass->setAmbient(tmpColour);
285                        xsishader.GetColorParameterValue(L"Diffuse", tmpColour.r, tmpColour.g,
286                                tmpColour.b, tmpColour.a);
287                        pass->setDiffuse(tmpColour);
288                        xsishader.GetColorParameterValue(L"Emissive", tmpColour.r, tmpColour.g,
289                                tmpColour.b, tmpColour.a);
290                        pass->setSelfIllumination(tmpColour);
291                        xsishader.GetColorParameterValue(L"Specular", tmpColour.r, tmpColour.g,
292                                tmpColour.b, tmpColour.a);
293                        pass->setSpecular(tmpColour);
294                       
295                        pass->setShininess(xsishader.GetParameter(L"Shininess").GetValue());
296                }
297
298               
299        }
300        //-------------------------------------------------------------------------
301        void XsiMaterialExporter::populatePassTextures(Pass* pass,
302                PassEntry* passEntry, bool copyTextures, const String& targetFolder)
303        {
304                // We need to search all shaders back to the point we would change
305                // passes, and add all the textures. This is because we don't know
306                // where in the shaders the texture transforms might be, since they
307                // are linked via 'target' not by being on the same object.
308                mTextureUnitTargetMap.clear();
309
310                for (int s = 0; s < passEntry->shaders.GetCount(); ++s)
311                {
312                        XSI::Shader shader(passEntry->shaders[s]);
313                        TextureUnitState* tex = 0;
314
315                        String progID = XSItoOgre(shader.GetProgID());
316                        if (progID.find("OGL13Texture") != String::npos ||
317                                progID.find("DXTexture") != String::npos ||
318                                progID.find("OGLCom") != String::npos)
319                        {
320                                if (!shader.GetParameter(L"bottom").IsValid())
321                                {
322                                        tex = add2DTexture(pass, shader, copyTextures, targetFolder);
323                                }
324                                else if (shader.GetParameter(L"bottom").IsValid())
325                                {
326                                        tex = addCubicTexture(pass, shader, copyTextures, targetFolder);
327                                }
328                        }
329                        else
330                        {
331                                continue; // not a texture so skip the rest
332                        }
333
334
335                        // texture coordinate set
336                        XSI::Parameter param = shader.GetParameter(L"tspace_id");
337                        if (param.IsValid())
338                        {
339                                // this is a name, need to look up index
340                                tex->setTextureCoordSet(
341                                        getTextureCoordIndex(XSItoOgre(param.GetValue())));
342                        }
343
344                        // filtering & anisotropy
345                        // DX and GL shaders deal differently
346                        if (progID.find("OGL") != String::npos)
347                        {
348                                populateOGLFiltering(tex, shader);
349                        }
350                        else if (progID.find("DX") != String::npos)
351                        {
352                                populateDXFiltering(tex, shader);
353                        }
354
355                        // colour operation
356                        param = shader.GetParameter(L"modulation");
357                        if (param.IsValid())
358                        {
359                                long colourop = param.GetValue();
360                                switch (colourop)
361                                {
362                                case 0:
363                                        // modulate
364                                        tex->setColourOperation(LBO_MODULATE);
365                                        break;
366                                case 1:
367                                        // decal
368                                        tex->setColourOperation(LBO_ALPHA_BLEND);
369                                        break;
370                                case 2:
371                                        // blend
372                                        tex->setColourOperation(LBO_MODULATE);
373                                        break;
374                                case 3:
375                                        // replace
376                                        tex->setColourOperation(LBO_REPLACE);
377                                        break;
378                                case 4:
379                                        // add
380                                        tex->setColourOperation(LBO_ADD);
381                                        break;
382                                }
383
384                        }
385
386
387                       
388                }
389        }
390        //-------------------------------------------------------------------------
391        TextureUnitState* XsiMaterialExporter::add2DTexture(Pass* pass, XSI::Shader& shader,
392                bool copyTextures, const String& targetFolder)
393        {
394                // create texture unit state and map from target incase future xforms
395                TextureUnitState* tex = pass->createTextureUnitState();
396
397                XSI::Parameter param = shader.GetParameter(L"target"); // OGL
398                if (!param.IsValid())
399                        param = shader.GetParameter(L"Texture_Target"); // DX
400
401                long target = param.GetValue();
402                mTextureUnitTargetMap.insert(
403                        TextureUnitTargetMap::value_type(target, tex));
404
405                // Get image
406                XSI::CRef src = shader.GetParameter(L"Texture").GetSource();
407                if (!src.IsValid() || !src.IsA(XSI::siImageClipID))
408                {
409                        // Try Texture_1 (OGL Combined)
410                        src = shader.GetParameter(L"Texture_1").GetSource();
411
412                }
413                if (src.IsValid() && src.IsA(XSI::siImageClipID))
414                {
415                        XSI::ImageClip imgClip(src);
416                        String srcTextureName =
417                                XSItoOgre(imgClip.GetParameter(L"SourceFileName").GetValue());
418
419                        String::size_type pos = srcTextureName.find_last_of("\\");
420                        if (pos == String::npos)
421                        {
422                                pos = srcTextureName.find_last_of("/");
423                        }
424                        String textureName =
425                                srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1);
426                        String destTextureName = targetFolder + textureName;
427
428                        // copy texture if required
429                        if (copyTextures)
430                        {
431                                copyFile(srcTextureName, destTextureName);
432                        }
433
434                        LogOgreAndXSI("Adding texture " + textureName);
435                        tex->setTextureName(textureName);
436
437                }
438
439                return tex;
440        }
441        //-------------------------------------------------------------------------
442        void XsiMaterialExporter::populateOGLFiltering(TextureUnitState* tex,
443                XSI::Shader& shader)
444        {
445                FilterOptions minFilter, mipFilter, magFilter;
446                minFilter = FO_LINEAR;
447                magFilter = FO_LINEAR;
448                mipFilter = FO_POINT;
449                XSI::Parameter param = shader.GetParameter(L"minfilter");
450                if (param.IsValid())
451                {
452                        // XSI OGL shader uses minfilter to determine mip too
453                        long filt = param.GetValue();
454                        switch(filt)
455                        {
456                        case 0:
457                                minFilter = FO_POINT;
458                                mipFilter = FO_NONE;
459                                break;
460                        case 1:
461                                minFilter = FO_LINEAR;
462                                mipFilter = FO_NONE;
463                                break;
464                        case 2:
465                                minFilter = FO_POINT;
466                                mipFilter = FO_POINT;
467                                break;
468                        case 3:
469                                minFilter = FO_POINT;
470                                mipFilter = FO_LINEAR;
471                                break;
472                        case 4:
473                                minFilter = FO_LINEAR;
474                                mipFilter = FO_POINT;
475                                break;
476                        case 5:
477                                minFilter = FO_LINEAR;
478                                mipFilter = FO_LINEAR;
479                                break;
480                        };
481
482                }
483                param = shader.GetParameter(L"magfilter");
484                if (param.IsValid())
485                {
486                        long filt = param.GetValue();
487                        switch(filt)
488                        {
489                        case 0:
490                                magFilter = FO_POINT;
491                                break;
492                        case 1:
493                                magFilter = FO_LINEAR;
494                                break;
495                        };
496                }
497
498                param = shader.GetParameter(L"anisotropy");
499                if (param.IsValid())
500                {
501                        long aniso = param.GetValue();
502                        if (aniso > 1)
503                        {
504                                // No specific aniso filtering option, so upgrade linear -> aniso
505                                if (minFilter == FO_LINEAR)
506                                        minFilter = FO_ANISOTROPIC;
507                                if (magFilter == FO_LINEAR)
508                                        magFilter = FO_ANISOTROPIC;
509                        }
510                        tex->setTextureAnisotropy(aniso);
511                }
512
513                tex->setTextureFiltering(minFilter, magFilter, mipFilter);
514        }
515        //-------------------------------------------------------------------------
516        void XsiMaterialExporter::populateDXFiltering(TextureUnitState* tex,
517                XSI::Shader& shader)
518        {
519                FilterOptions minFilter, mipFilter, magFilter;
520                minFilter = FO_LINEAR;
521                magFilter = FO_LINEAR;
522                mipFilter = FO_POINT;
523                XSI::Parameter param = shader.GetParameter(L"minfilter");
524                if (param.IsValid())
525                {
526                        // XSI DX shader has min/mag and mip, and has more options
527                        long filt = param.GetValue();
528                        switch(filt)
529                        {
530                        case 0:
531                                minFilter = FO_NONE;
532                                break;
533                        case 1:
534                                minFilter = FO_POINT;
535                                break;
536                        case 2:
537                                minFilter = FO_LINEAR;
538                                break;
539                        case 3:
540                        case 4: // we don't support cubic/gaussian, use aniso
541                        case 5:
542                                minFilter = FO_ANISOTROPIC;
543                                break;
544                        };
545                }
546                param = shader.GetParameter(L"magfilter");
547                if (param.IsValid())
548                {
549                        // XSI DX shader has mag/mag and mip, and has more options
550                        long filt = param.GetValue();
551                        switch(filt)
552                        {
553                        case 0:
554                                magFilter = FO_NONE;
555                                break;
556                        case 1:
557                                magFilter = FO_POINT;
558                                break;
559                        case 2:
560                                magFilter = FO_LINEAR;
561                                break;
562                        case 3:
563                        case 4: // we don't support cubic/gaussian, use aniso
564                        case 5:
565                                magFilter = FO_ANISOTROPIC;
566                                break;
567                        };
568                }
569                param = shader.GetParameter(L"mipfilter");
570                if (param.IsValid())
571                {
572                        // XSI DX shader has mip/mag and mip, and has more options
573                        long filt = param.GetValue();
574                        switch(filt)
575                        {
576                        case 0:
577                                mipFilter = FO_NONE;
578                                break;
579                        case 1:
580                                mipFilter = FO_POINT;
581                                break;
582                        case 2:
583                                mipFilter = FO_LINEAR;
584                                break;
585                        case 3:
586                        case 4: // we don't support cubic/gaussian, use aniso
587                        case 5:
588                                mipFilter = FO_ANISOTROPIC;
589                                break;
590                        };
591                }
592                // Aniso
593                param = shader.GetParameter(L"anisotropy");
594                if (param.IsValid())
595                {
596                        long aniso = param.GetValue();
597                        tex->setTextureAnisotropy(aniso);
598                }
599
600                tex->setTextureFiltering(minFilter, magFilter, mipFilter);
601        }
602        //-------------------------------------------------------------------------
603        TextureUnitState* XsiMaterialExporter::addCubicTexture(Pass* pass, XSI::Shader& shader,
604                bool copyTextures, const String& targetFolder)
605        {
606                // create texture unit state and map from target incase future xforms
607                TextureUnitState* tex = pass->createTextureUnitState();
608
609                XSI::Parameter param = shader.GetParameter(L"target"); // OGL
610                if (!param.IsValid())
611                        param = shader.GetParameter(L"Texture_Target"); // DX
612
613                long target = param.GetValue();
614                mTextureUnitTargetMap.insert(
615                        TextureUnitTargetMap::value_type(target, tex));
616
617                // Get images
618                wchar_t* cubeFaceName[6] = {
619                        L"front", L"back", L"top", L"bottom", L"left", L"right" };
620
621                String finalNames[6];
622
623
624                for (int face = 0; face < 6; ++face)
625                {
626                        XSI::CRef src = shader.GetParameter(cubeFaceName[face]).GetSource();
627                        if (src.IsValid() && src.IsA(XSI::siImageClipID))
628                        {
629                                XSI::ImageClip imgClip(src);
630                                String srcTextureName =
631                                        XSItoOgre(imgClip.GetParameter(L"SourceFileName").GetValue());
632
633                                String::size_type pos = srcTextureName.find_last_of("\\");
634                                if (pos == String::npos)
635                                {
636                                        pos = srcTextureName.find_last_of("/");
637                                }
638                                finalNames[face] =
639                                        srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1);
640                                String destTextureName = targetFolder + finalNames[face];
641
642                                // copy texture if required
643                                if (copyTextures)
644                                {
645                                        copyFile(srcTextureName, destTextureName);
646                                }
647
648
649                                LogOgreAndXSI("Cubemap face: " + srcTextureName);
650                        }
651                }
652
653                LogOgreAndXSI("Adding cubic texture");
654                // Cannot do combinedUVW for now, DevIL can't write DDS cubemap so
655                // go for separates (user can modify)
656                tex->setCubicTextureName(finalNames, false);
657
658                return tex;
659               
660        }
661        //-------------------------------------------------------------------------
662        unsigned short XsiMaterialExporter::getTextureCoordIndex(const String& tspace)
663        {
664                TextureProjectionMap::iterator i = mTextureProjectionMap.find(tspace);
665                if (i != mTextureProjectionMap.end())
666                {
667                        return i->second;
668                }
669                else
670                {
671                        // default
672                        return 0;
673                }
674        }
675        //-------------------------------------------------------------------------
676        void XsiMaterialExporter::populatePassTextureTransforms(Pass* pass,
677                XSI::Shader& shader)
678        {
679                // TODO
680                // Check we have the right object
681                XSI::Parameter param = shader.GetParameter(L"wrap_u");
682                if (param.IsValid())
683                {
684
685                        // addressing mode
686                        TextureUnitState::UVWAddressingMode uvwadd;
687                        uvwadd.u = convertAddressingMode(param.GetValue());
688                        // default other dimensions incase not supplied
689                        uvwadd.v = uvwadd.u;
690                        uvwadd.w = uvwadd.u;
691
692                        param = shader.GetParameter(L"wrap_v");
693                        if (param.IsValid())
694                        {
695                                uvwadd.v = convertAddressingMode(param.GetValue());
696                        }
697                        param = shader.GetParameter(L"wrap_w");
698                        if (param.IsValid())
699                        {
700                                uvwadd.w = convertAddressingMode(param.GetValue());
701                        }
702
703                        // transform
704                        bool usexform = false;
705                        Matrix4 xform = Matrix4::IDENTITY;
706                        param = shader.GetParameter(L"Transform");
707                        if (param.IsValid() && (bool)param.GetValue())
708                        {
709                                Quaternion qx, qy, qz, qfinal;
710                                qx.FromAngleAxis(Degree(shader.GetParameter(L"rotx").GetValue()),
711                                        Vector3::UNIT_X);
712                                qy.FromAngleAxis(Degree(shader.GetParameter(L"roty").GetValue()),
713                                        Vector3::UNIT_Y);
714                                qz.FromAngleAxis(Degree(shader.GetParameter(L"rotz").GetValue()),
715                                        Vector3::UNIT_Z);
716                                qfinal = qx * qy * qz;
717
718                                Vector3 trans;
719                                trans.x = shader.GetParameter(L"trsx").GetValue();
720                                trans.y = shader.GetParameter(L"trsy").GetValue();
721                                trans.z = shader.GetParameter(L"trsz").GetValue();
722
723                                Matrix3 rot3x3, scale3x3;
724                                qfinal.ToRotationMatrix(rot3x3);
725                                scale3x3 = Matrix3::ZERO;
726                                scale3x3[0][0] = shader.GetParameter(L"sclx").GetValue();
727                                scale3x3[1][1] = shader.GetParameter(L"scly").GetValue();
728                                scale3x3[2][2] = shader.GetParameter(L"sclz").GetValue();
729
730                                xform = rot3x3 * scale3x3;
731                                xform.setTrans(trans);
732                                usexform = true;
733
734                        }
735                       
736
737                        // Look up texture unit(s) that are using this target
738                        long target = shader.GetParameter(L"Texture_Target").GetValue();
739                        TextureUnitTargetMap::iterator i = mTextureUnitTargetMap.find(target);
740                        while (i != mTextureUnitTargetMap.end() && i->first == target)
741                        {
742                                TextureUnitState* tex = i->second;
743                                tex->setTextureAddressingMode(uvwadd);
744                                if (usexform)
745                                        tex->setTextureTransform(xform);
746
747                                // texgen (not texcoord_index as in OGRE!)
748                                // Can turn into 2 different calls
749                                param = shader.GetParameter(L"texcoord_index");
750                                if (param.IsValid())
751                                {
752                                        long e = param.GetValue();
753                                        if (e != 0)
754                                        {
755                                                // Not Explicit
756                                                // details differ per DX/OGL
757                                                if (XSItoOgre(shader.GetProgID()).find("DX") != String::npos)
758                                                {
759                                                        convertTexGenDX(tex, e, shader);
760                                                }
761                                                else
762                                                {
763                                                        convertTexGenDX(tex, e, shader);
764                                                }
765
766                                        }
767
768                                }
769                                ++i;
770                        }
771
772
773
774
775                }
776                param = shader.GetParameter(L"Additive_Transform");
777                if (param.IsValid())
778                {
779                        unsigned short target = shader.GetParameter(L"Texture_Coord_ID").GetValue();
780                        if (pass->getNumTextureUnitStates() > target)
781                        {
782                                TextureUnitState* tex = pass->getTextureUnitState(target);
783
784                                long uvType = shader.GetParameter(L"UV_Type").GetValue();
785                                if (uvType != 0)
786                                {
787                                        double val1 = shader.GetParameter(L"Val1").GetValue();
788                                        double val2 = shader.GetParameter(L"Val2").GetValue();
789                                        long wave = shader.GetParameter(L"Wave").GetValue();
790                                        WaveformType wft;
791                                        switch (wave)
792                                        {
793                                        case 1:
794                                                wft = WFT_SINE;
795                                                break;
796                                        case 2:
797                                                wft = WFT_TRIANGLE;
798                                                break;
799                                        case 3:
800                                                wft = WFT_SQUARE;
801                                                break;
802                                        case 4:
803                                                wft = WFT_SAWTOOTH;
804                                                break;
805                                        case 5:
806                                                wft = WFT_INVERSE_SAWTOOTH;
807                                                break;
808                                        }
809                                        double base = shader.GetParameter(L"Base").GetValue();
810                                        double amp = shader.GetParameter(L"Amplitude").GetValue();
811                                        double phase = shader.GetParameter(L"Phase").GetValue();
812                                        double freq = shader.GetParameter(L"Frequency").GetValue();
813
814                                        switch(uvType)
815                                        {
816                                        case 1:
817                                                // translate
818                                                tex->setTextureScroll(val1, val2);
819                                                break;
820                                        case 2:
821                                                // rotate
822                                                tex->setTextureRotate(Degree(val1));
823                                                break;
824                                        case 3:
825                                                // scale
826                                                tex->setTextureScale(val1, val2);
827                                                break;
828                                        case 4:
829                                                // scroll
830                                                if (wave != 0)
831                                                {
832                                                        tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U,
833                                                                wft, base, freq, phase, amp);
834                                                        tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V,
835                                                                wft, base, freq, phase, amp);
836                                                }
837                                                else
838                                                {
839                                                        tex->setScrollAnimation(val1, val2);
840                                                }
841                                                break;
842                                        case 5:
843                                                // turn
844                                                if (wave != 0)
845                                                {
846                                                        tex->setTransformAnimation(TextureUnitState::TT_ROTATE,
847                                                                wft, base, freq, phase, amp);
848                                                }
849                                                else
850                                                {
851                                                        tex->setRotateAnimation(val1 / 360.0f);
852                                                }
853                                                break;
854                                        case 6:
855                                                // stretch (only wave)
856                                                if (wave != 0)
857                                                {
858                                                        tex->setTransformAnimation(TextureUnitState::TT_SCALE_U,
859                                                                wft, base, freq, phase, amp);
860                                                        tex->setTransformAnimation(TextureUnitState::TT_SCALE_V,
861                                                                wft, base, freq, phase, amp);
862                                                }
863                                                break;
864
865                                        }
866                                }
867                        }
868
869                }
870
871                // if more than one entry for the same target is found, it is ok for the
872                // latter to take precedence since this is what happens in XSI.
873
874        }
875        //-------------------------------------------------------------------------
876        void XsiMaterialExporter::convertTexGenOGL(TextureUnitState* tex,
877                long xsiVal, XSI::Shader& shader)
878        {
879                switch(xsiVal)
880                {
881                        // no 0
882                case 1:
883                        // Object linear
884                        tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR);
885                        break;
886                case 2:
887                        // Eye linear (texture projection)
888                        tex->setProjectiveTexturing(true);
889                        break;
890                case 3:
891                        // Sphere map
892                        tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED);
893                        break;
894                case 4:
895                        // Reflection map
896                        tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION);
897                        break;
898                case 5:
899                        // Normal map
900                        tex->setEnvironmentMap(true, TextureUnitState::ENV_NORMAL);
901                        break;
902
903                };
904        }
905        //-------------------------------------------------------------------------
906        void XsiMaterialExporter::convertTexGenDX(TextureUnitState* tex,
907                long xsiVal, XSI::Shader& shader)
908        {
909                switch(xsiVal)
910                {
911                        // no 0
912                case 1:
913                        // Normal in camera space
914                        tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED);
915                        break;
916                case 2:
917                        // Position in camera space
918                        tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR);
919                        break;
920                case 3:
921                        // Reflection vector in camera space
922                        tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION);
923                        break;
924
925                };
926        }
927        //-------------------------------------------------------------------------
928        TextureUnitState::TextureAddressingMode
929        XsiMaterialExporter::convertAddressingMode(short xsiVal)
930        {
931                // same for OGL and DX
932                switch(xsiVal)
933                {
934                case 0:
935                        return TextureUnitState::TAM_WRAP;
936                case 1:
937                        return TextureUnitState::TAM_MIRROR;
938                case 2:
939                        return TextureUnitState::TAM_CLAMP;
940                case 3:
941                        // border?
942                        return TextureUnitState::TAM_CLAMP;
943                case 4:
944                        // mirror once
945                        return TextureUnitState::TAM_MIRROR;
946                case 5:
947                        // clamp to edge
948                        return TextureUnitState::TAM_CLAMP;
949
950                };
951
952                // Keep compiler happy
953                return TextureUnitState::TAM_WRAP;
954        }
955        //-------------------------------------------------------------------------
956        SceneBlendFactor XsiMaterialExporter::convertSceneBlend(short xsiVal)
957        {
958                switch(xsiVal)
959                {
960                case 0:
961                        return SBF_ZERO;
962                case 1:
963                        return SBF_ONE;
964                case 2:
965                        return SBF_DEST_COLOUR;
966                case 3:
967                        return SBF_ONE_MINUS_DEST_COLOUR;
968                case 4:
969                        return SBF_SOURCE_ALPHA;
970                case 5:
971                        return SBF_ONE_MINUS_SOURCE_ALPHA;
972                case 6:
973                        return SBF_DEST_ALPHA;
974                case 7:
975                        return SBF_ONE_MINUS_DEST_ALPHA;
976                };
977
978                return SBF_ZERO;
979               
980        }
981
982}
983
Note: See TracBrowser for help on using the repository browser.