source: OGRE/trunk/ogrenew/Tools/MayaExport/src/material.cpp @ 692

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

adding ogre 1.2 and dependencies

Line 
1#include "material.h"
2
3namespace OgreMayaExporter
4{
5        // Constructor
6        Material::Material()
7        {
8                clear();
9        }
10
11
12        // Destructor
13        Material::~Material()
14        {
15        }
16
17
18        // Get material name
19        MString& Material::name()
20        {
21                return m_name;
22        }
23
24
25        // Clear data
26        void Material::clear()
27        {
28                m_name = "";
29                m_type = MT_LAMBERT;
30                m_lightingOff = false;
31                m_isTransparent = false;
32                m_isTextured = false;
33                m_isMultiTextured = false;
34                m_ambient = MColor(0,0,0,0);
35                m_diffuse = MColor(0,0,0,0);
36                m_specular = MColor(0,0,0,0);
37                m_emissive = MColor(0,0,0,0);
38                m_textures.clear();
39        }
40
41
42        // Load material data
43        MStatus Material::load(MFnLambertShader* pShader,MStringArray& uvsets,ParamList& params)
44        {
45                MStatus stat;
46                clear();
47                //read material name, adding the requested prefix
48                m_name = params.matPrefix;
49                if (m_name != "")
50                        m_name += "/";
51                m_name += pShader->name();
52                //check if we want to export with lighting off option
53                m_lightingOff = params.lightingOff;
54
55                MFnPhongShader* pPhong = NULL;
56                MFnBlinnShader* pBlinn = NULL;
57                MPlugArray colorSrcPlugs;
58                MPlugArray texSrcPlugs;
59                MPlugArray placetexSrcPlugs;
60
61                // GET MATERIAL DATA
62
63                // Check material type
64                if (pShader->object().hasFn(MFn::kPhong))
65                {
66                        m_type = MT_PHONG;
67                        pPhong = new MFnPhongShader(pShader->object());
68                }
69                else if (pShader->object().hasFn(MFn::kBlinn))
70                {
71                        m_type = MT_BLINN;
72                        pBlinn = new MFnBlinnShader(pShader->object());
73                }
74
75                // Check if material is textured
76                pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false);
77                for (int i=0; i<colorSrcPlugs.length(); i++)
78                {
79                        if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture))
80                        {
81                                m_isTextured = true;
82                                continue;
83                        }
84                        else if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture))
85                        {
86                                m_isTextured = true;
87                                m_isMultiTextured = true;
88                                continue;
89                        }
90                }
91
92                // Check if material is transparent
93                if (pShader->findPlug("transparency").isConnected() || pShader->transparency().r>0.0f)
94                        m_isTransparent = true;
95
96                // Get material colours
97                //diffuse colour
98                if (m_isTextured)
99                        m_diffuse = MColor(1.0,1.0,1.0,1.0);
100                else
101                {
102                        m_diffuse = pShader->color();
103                        m_diffuse.a = 1.0 - pShader->transparency().r;
104                }
105                //ambient colour
106                m_ambient = m_diffuse;
107                //emissive colour
108                m_emissive = pShader->incandescence();
109                //specular colour
110                switch(m_type)
111                {
112                case MT_PHONG:
113                        m_specular = pPhong->specularColor();
114                        m_specular.a = pPhong->cosPower();
115                        break;
116                case MT_BLINN:
117                        m_specular = pBlinn->specularColor();
118                        m_specular.a = 1.0 / pBlinn->eccentricity();
119                        break;
120                default:
121                        m_specular = MColor(0.0,0.0,0.0,0.0);
122                }
123
124                // Get textures data
125                if (m_isTextured)
126                {
127                        // Translate multiple textures if material is multitextured
128                        if (m_isMultiTextured)
129                        {
130                                // Get layered texture node
131                                MFnDependencyNode* pLayeredTexNode = NULL;
132                                pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false);
133                                for (i=0; i<colorSrcPlugs.length(); i++)
134                                {
135                                        if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture))
136                                        {
137                                                pLayeredTexNode = new MFnDependencyNode(colorSrcPlugs[i].node());
138                                                continue;
139                                        }
140                                }
141
142                                // Get inputs to layered texture
143                                MPlug inputsPlug = pLayeredTexNode->findPlug("inputs");
144
145                                // Scan inputs and export textures
146                                for (i=inputsPlug.numElements()-1; i>=0; i--)
147                                {
148                                        MFnDependencyNode* pTextureNode = NULL;
149                                        // Search for a connected texture
150                                        inputsPlug[i].child(0).connectedTo(colorSrcPlugs,true,false);
151                                        for (int j=0; j<colorSrcPlugs.length(); j++)
152                                        {
153                                                if (colorSrcPlugs[j].node().hasFn(MFn::kFileTexture))
154                                                {
155                                                        pTextureNode = new MFnDependencyNode(colorSrcPlugs[j].node());
156                                                        continue;
157                                                }
158                                        }
159
160                                        // Translate the texture if it was found
161                                        if (pTextureNode)
162                                        {
163                                                // Get blend mode
164                                                TexOpType opType;
165                                                short bm;
166                                                inputsPlug[i].child(2).getValue(bm);
167                                                switch(bm)
168                                                {                               
169                                                case 0:
170                                                        opType = TOT_REPLACE;
171                                                        break;
172                                                case 1:
173                                                        opType = TOT_ALPHABLEND;
174                                                        break;                         
175                                                case 4:
176                                                        opType = TOT_ADD;
177                                                        break;
178                                                case 6:
179                                                        opType = TOT_MODULATE;
180                                                        break;
181                                                default:
182                                                        opType = TOT_MODULATE;
183                                                }
184
185                                                stat = loadTexture(pTextureNode,opType,uvsets,params);
186                                                delete pTextureNode;
187                                                if (MS::kSuccess != stat)
188                                                {
189                                                        std::cout << "Error loading layered texture\n";
190                                                        delete pLayeredTexNode;
191                                                        return MS::kFailure;
192                                                }
193                                        }
194                                }
195                                if (pLayeredTexNode)
196                                        delete pLayeredTexNode;
197                        }
198                        // Else translate the single texture
199                        else
200                        {
201                                // Get texture node
202                                MFnDependencyNode* pTextureNode = NULL;
203                                pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false);
204                                for (i=0; i<colorSrcPlugs.length(); i++)
205                                {
206                                        if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture))
207                                        {
208                                                pTextureNode = new MFnDependencyNode(colorSrcPlugs[i].node());
209                                                continue;
210                                        }
211                                }
212                                if (pTextureNode)
213                                {
214                                        TexOpType opType = TOT_MODULATE;
215                                        stat = loadTexture(pTextureNode,opType,uvsets,params);
216                                        delete pTextureNode;
217                                        if (MS::kSuccess != stat)
218                                        {
219                                                std::cout << "Error loading texture\n";
220                                                return MS::kFailure;
221                                        }
222                                }
223                        }
224                }
225                // Free up memory
226                if (pPhong)
227                        delete pPhong;
228                if (pBlinn)
229                        delete pBlinn;
230
231                return MS::kSuccess;
232        }
233
234
235        // Load texture data from a texture node
236        MStatus Material::loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params)
237        {
238                texture tex;
239                // Get texture filename
240                MString filename, absFilename;
241                MRenderUtil::exactFileTextureName(pTexNode->object(),absFilename);
242                filename = absFilename.substring(absFilename.rindex('/')+1,absFilename.length()-1);
243                MString command = "toNativePath(\"";
244                command += absFilename;
245                command += "\")";
246                MGlobal::executeCommand(command,absFilename);
247                tex.absFilename = absFilename;
248                tex.filename = filename;
249                tex.uvsetIndex = 0;
250                tex.uvsetName = "";
251                // Set texture operation type
252                tex.opType = opType;
253                // Get connections to uvCoord attribute of texture node
254                MPlugArray texSrcPlugs;
255                pTexNode->findPlug("uvCoord").connectedTo(texSrcPlugs,true,false);
256                // Get place2dtexture node (if connected)
257                MFnDependencyNode* pPlace2dTexNode = NULL;
258                for (int j=0; j<texSrcPlugs.length(); j++)
259                {
260                        if (texSrcPlugs[j].node().hasFn(MFn::kPlace2dTexture))
261                        {
262                                pPlace2dTexNode = new MFnDependencyNode(texSrcPlugs[j].node());
263                                continue;
264                        }
265                }
266                // Get uvChooser node (if connected)
267                MFnDependencyNode* pUvChooserNode = NULL;
268                if (pPlace2dTexNode)
269                {
270                        MPlugArray placetexSrcPlugs;
271                        pPlace2dTexNode->findPlug("uvCoord").connectedTo(placetexSrcPlugs,true,false);
272                        for (j=0; j<placetexSrcPlugs.length(); j++)
273                        {
274                                if (placetexSrcPlugs[j].node().hasFn(MFn::kUvChooser))
275                                {
276                                        pUvChooserNode = new MFnDependencyNode(placetexSrcPlugs[j].node());
277                                        continue;
278                                }
279                        }
280                }
281                // Get uvset index
282                if (pUvChooserNode)
283                {
284                        bool foundMesh = false;
285                        bool foundUvset = false;
286                        MPlug uvsetsPlug = pUvChooserNode->findPlug("uvSets");
287                        MPlugArray uvsetsSrcPlugs;
288                        for (int i=0; i<uvsetsPlug.evaluateNumElements() && !foundMesh; i++)
289                        {
290                                uvsetsPlug[i].connectedTo(uvsetsSrcPlugs,true,false);
291                                for (j=0; j<uvsetsSrcPlugs.length() && !foundMesh; j++)
292                                {
293                                        if (uvsetsSrcPlugs[j].node().hasFn(MFn::kMesh))
294                                        {
295                                                uvsetsSrcPlugs[j].getValue(tex.uvsetName);
296                                                for (int k=0; k<uvsets.length() && !foundUvset; k++)
297                                                {
298                                                        if (uvsets[k] == tex.uvsetName)
299                                                        {
300                                                                tex.uvsetIndex = k;
301                                                                foundUvset = true;
302                                                        }
303                                                }
304                                        }
305                                }
306                        }
307                }
308                // add texture to material texture list
309                m_textures.push_back(tex);
310                // free up memory
311                if (pUvChooserNode)
312                        delete pUvChooserNode;
313                if (pPlace2dTexNode)
314                        delete pPlace2dTexNode;
315
316                return MS::kSuccess;
317        }
318
319
320        // Write material data to Ogre XML file
321        MStatus Material::writeXML(ParamList &params)
322        {
323                //Start material description
324                params.outMaterial << "material " << m_name.asChar() << "\n";
325                params.outMaterial << "{\n";
326
327                //Start technique description
328                params.outMaterial << "\ttechnique\n";
329                params.outMaterial << "\t{\n";
330
331                //Start render pass description
332                params.outMaterial << "\t\tpass\n";
333                params.outMaterial << "\t\t{\n";
334                //set lighting off option if requested
335                if (m_lightingOff)
336                        params.outMaterial << "\t\t\tlighting off\n\n";
337                //ambient colour
338                params.outMaterial << "\t\t\tambient " << m_ambient.r << " " << m_ambient.g << " " << m_ambient.b
339                        << " " << m_ambient.a << "\n";
340                //diffuse colour
341                params.outMaterial << "\t\t\tdiffuse " << m_diffuse.r << " " << m_diffuse.g << " " << m_diffuse.b
342                        << " " << m_diffuse.a << "\n";
343                //specular colour
344                params.outMaterial << "\t\t\tspecular " << m_specular.r << " " << m_specular.g << " " << m_specular.b
345                        << " " << m_specular.a << "\n";
346                //emissive colour
347                params.outMaterial << "\t\t\temissive " << m_emissive.r << " " << m_emissive.g << " "
348                        << m_emissive.b << "\n";
349                //if material is transparent set blend mode and turn off depth_writing
350                if (m_isTransparent)
351                {
352                        params.outMaterial << "\n\t\t\tscene_blend alpha_blend\n";
353                        params.outMaterial << "\t\t\tdepth_write off\n";
354                }
355                //write texture units
356                for (int i=0; i<m_textures.size(); i++)
357                {
358                        //start texture unit description
359                        params.outMaterial << "\n\t\t\ttexture_unit\n";
360                        params.outMaterial << "\t\t\t{\n";
361                        //write texture name
362                        params.outMaterial << "\t\t\t\ttexture " << m_textures[i].filename.asChar() << "\n";
363                        //write texture coordinate index
364                        params.outMaterial << "\t\t\t\ttex_coord_set " << m_textures[i].uvsetIndex << "\n";
365                        //write colour operation
366                        switch (m_textures[i].opType)
367                        {
368                        case TOT_REPLACE:
369                                params.outMaterial << "\t\t\t\tcolour_op replace\n";
370                                break;
371                        case TOT_ADD:
372                                params.outMaterial << "\t\t\t\tcolour_op add\n";
373                                break;
374                        case TOT_MODULATE:
375                                params.outMaterial << "\t\t\t\tcolour_op modulate\n";
376                                break;
377                        case TOT_ALPHABLEND:
378                                params.outMaterial << "\t\t\t\tcolour_op alpha_blend\n";
379                                break;
380                        }
381                        //end texture unit desription
382                        params.outMaterial << "\t\t\t}\n";
383                }
384
385                //End render pass description
386                params.outMaterial << "\t\t}\n";
387
388                //End technique description
389                params.outMaterial << "\t}\n";
390
391                //End material description
392                params.outMaterial << "}\n";
393
394                //Copy textures to output dir if required
395                if (params.copyTextures)
396                        copyTextures(params);
397
398                return MS::kSuccess;
399        }
400
401
402        // Copy textures to path specified by params
403        MStatus Material::copyTextures(ParamList &params)
404        {
405                for (int i=0; i<m_textures.size(); i++)
406                {
407                        // Copy file texture to output dir
408                        MString command = "copy \"";
409                        command += m_textures[i].absFilename;
410                        command += "\" \"";
411                        command += params.texOutputDir;
412                        command += "\"";
413                        system(command.asChar());
414                }
415                return MS::kSuccess;
416        }
417
418};      //end namespace
Note: See TracBrowser for help on using the repository browser.