Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp @ 6

Last change on this file since 6 was 6, checked in by anonymous, 17 years ago

=…

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