| [6] | 1 | //////////////////////////////////////////////////////////////////////////////// |
|---|
| 2 | // material.cpp |
|---|
| 3 | // Author : Francesco Giordana |
|---|
| 4 | // Start Date : January 13, 2005 |
|---|
| 5 | // Copyright : (C) 2006 by Francesco Giordana |
|---|
| 6 | // Email : fra.giordana@tiscali.it |
|---|
| 7 | //////////////////////////////////////////////////////////////////////////////// |
|---|
| 8 | |
|---|
| 9 | /********************************************************************************* |
|---|
| 10 | * * |
|---|
| 11 | * This program is free software; you can redistribute it and/or modify * |
|---|
| 12 | * it under the terms of the GNU Lesser General Public License as published by * |
|---|
| 13 | * the Free Software Foundation; either version 2 of the License, or * |
|---|
| 14 | * (at your option) any later version. * |
|---|
| 15 | * * |
|---|
| 16 | **********************************************************************************/ |
|---|
| 17 | |
|---|
| 18 | #include "material.h" |
|---|
| 19 | |
|---|
| 20 | namespace OgreMayaExporter |
|---|
| 21 | { |
|---|
| 22 | // Constructor |
|---|
| 23 | Material::Material() |
|---|
| 24 | { |
|---|
| 25 | clear(); |
|---|
| 26 | } |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | // Destructor |
|---|
| 30 | Material::~Material() |
|---|
| 31 | { |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | |
|---|
| 35 | // Get material name |
|---|
| 36 | MString& Material::name() |
|---|
| 37 | { |
|---|
| 38 | return m_name; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | |
|---|
| 42 | // Clear data |
|---|
| 43 | void Material::clear() |
|---|
| 44 | { |
|---|
| 45 | m_name = ""; |
|---|
| 46 | m_type = MT_LAMBERT; |
|---|
| 47 | m_lightingOff = false; |
|---|
| 48 | m_isTransparent = false; |
|---|
| 49 | m_isTextured = false; |
|---|
| 50 | m_isMultiTextured = false; |
|---|
| 51 | m_ambient = MColor(0,0,0,0); |
|---|
| 52 | m_diffuse = MColor(0,0,0,0); |
|---|
| 53 | m_specular = MColor(0,0,0,0); |
|---|
| 54 | m_emissive = MColor(0,0,0,0); |
|---|
| 55 | m_textures.clear(); |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | // Load material data |
|---|
| 60 | MStatus Material::load(MFnDependencyNode* pShader,MStringArray& uvsets,ParamList& params) |
|---|
| 61 | { |
|---|
| 62 | int i; |
|---|
| 63 | MStatus stat; |
|---|
| 64 | clear(); |
|---|
| 65 | //read material name, adding the requested prefix |
|---|
| 66 | MString tmpStr = params.matPrefix; |
|---|
| 67 | if (tmpStr != "") |
|---|
| 68 | tmpStr += "/"; |
|---|
| 69 | tmpStr += pShader->name(); |
|---|
| 70 | MStringArray tmpStrArray; |
|---|
| 71 | tmpStr.split(':',tmpStrArray); |
|---|
| 72 | m_name = ""; |
|---|
| 73 | for (i=0; i<tmpStrArray.length(); i++) |
|---|
| 74 | { |
|---|
| 75 | m_name += tmpStrArray[i]; |
|---|
| 76 | if (i < tmpStrArray.length()-1) |
|---|
| 77 | m_name += "_"; |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | //check if we want to export with lighting off option |
|---|
| 81 | m_lightingOff = params.lightingOff; |
|---|
| 82 | |
|---|
| 83 | // GET MATERIAL DATA |
|---|
| 84 | |
|---|
| 85 | // Check material type |
|---|
| 86 | if (pShader->object().hasFn(MFn::kPhong)) |
|---|
| 87 | { |
|---|
| 88 | stat = loadPhong(pShader); |
|---|
| 89 | } |
|---|
| 90 | else if (pShader->object().hasFn(MFn::kBlinn)) |
|---|
| 91 | { |
|---|
| 92 | stat = loadBlinn(pShader); |
|---|
| 93 | } |
|---|
| 94 | else if (pShader->object().hasFn(MFn::kLambert)) |
|---|
| 95 | { |
|---|
| 96 | stat = loadLambert(pShader); |
|---|
| 97 | } |
|---|
| 98 | else if (pShader->object().hasFn(MFn::kPluginHwShaderNode)) |
|---|
| 99 | { |
|---|
| 100 | stat = loadCgFxShader(pShader); |
|---|
| 101 | } |
|---|
| 102 | else |
|---|
| 103 | { |
|---|
| 104 | stat = loadSurfaceShader(pShader); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | // Get textures data |
|---|
| 108 | MPlugArray colorSrcPlugs; |
|---|
| 109 | MPlugArray texSrcPlugs; |
|---|
| 110 | MPlugArray placetexSrcPlugs; |
|---|
| 111 | if (m_isTextured) |
|---|
| 112 | { |
|---|
| 113 | // Translate multiple textures if material is multitextured |
|---|
| 114 | if (m_isMultiTextured) |
|---|
| 115 | { |
|---|
| 116 | // Get layered texture node |
|---|
| 117 | MFnDependencyNode* pLayeredTexNode = NULL; |
|---|
| 118 | if (m_type == MT_SURFACE_SHADER) |
|---|
| 119 | pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false); |
|---|
| 120 | else |
|---|
| 121 | pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); |
|---|
| 122 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 123 | { |
|---|
| 124 | if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture)) |
|---|
| 125 | { |
|---|
| 126 | pLayeredTexNode = new MFnDependencyNode(colorSrcPlugs[i].node()); |
|---|
| 127 | continue; |
|---|
| 128 | } |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | // Get inputs to layered texture |
|---|
| 132 | MPlug inputsPlug = pLayeredTexNode->findPlug("inputs"); |
|---|
| 133 | |
|---|
| 134 | // Scan inputs and export textures |
|---|
| 135 | for (i=inputsPlug.numElements()-1; i>=0; i--) |
|---|
| 136 | { |
|---|
| 137 | MFnDependencyNode* pTextureNode = NULL; |
|---|
| 138 | // Search for a connected texture |
|---|
| 139 | inputsPlug[i].child(0).connectedTo(colorSrcPlugs,true,false); |
|---|
| 140 | for (int j=0; j<colorSrcPlugs.length(); j++) |
|---|
| 141 | { |
|---|
| 142 | if (colorSrcPlugs[j].node().hasFn(MFn::kFileTexture)) |
|---|
| 143 | { |
|---|
| 144 | pTextureNode = new MFnDependencyNode(colorSrcPlugs[j].node()); |
|---|
| 145 | continue; |
|---|
| 146 | } |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | // Translate the texture if it was found |
|---|
| 150 | if (pTextureNode) |
|---|
| 151 | { |
|---|
| 152 | // Get blend mode |
|---|
| 153 | TexOpType opType; |
|---|
| 154 | short bm; |
|---|
| 155 | inputsPlug[i].child(2).getValue(bm); |
|---|
| 156 | switch(bm) |
|---|
| 157 | { |
|---|
| 158 | case 0: |
|---|
| 159 | opType = TOT_REPLACE; |
|---|
| 160 | break; |
|---|
| 161 | case 1: |
|---|
| 162 | opType = TOT_ALPHABLEND; |
|---|
| 163 | break; |
|---|
| 164 | case 4: |
|---|
| 165 | opType = TOT_ADD; |
|---|
| 166 | break; |
|---|
| 167 | case 6: |
|---|
| 168 | opType = TOT_MODULATE; |
|---|
| 169 | break; |
|---|
| 170 | default: |
|---|
| 171 | opType = TOT_MODULATE; |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | stat = loadTexture(pTextureNode,opType,uvsets,params); |
|---|
| 175 | delete pTextureNode; |
|---|
| 176 | if (MS::kSuccess != stat) |
|---|
| 177 | { |
|---|
| 178 | std::cout << "Error loading layered texture\n"; |
|---|
| 179 | std::cout.flush(); |
|---|
| 180 | delete pLayeredTexNode; |
|---|
| 181 | return MS::kFailure; |
|---|
| 182 | } |
|---|
| 183 | } |
|---|
| 184 | } |
|---|
| 185 | if (pLayeredTexNode) |
|---|
| 186 | delete pLayeredTexNode; |
|---|
| 187 | } |
|---|
| 188 | // Else translate the single texture |
|---|
| 189 | else |
|---|
| 190 | { |
|---|
| 191 | // Get texture node |
|---|
| 192 | MFnDependencyNode* pTextureNode = NULL; |
|---|
| 193 | if (m_type == MT_SURFACE_SHADER) |
|---|
| 194 | pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false); |
|---|
| 195 | else |
|---|
| 196 | pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); |
|---|
| 197 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 198 | { |
|---|
| 199 | if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture)) |
|---|
| 200 | { |
|---|
| 201 | pTextureNode = new MFnDependencyNode(colorSrcPlugs[i].node()); |
|---|
| 202 | continue; |
|---|
| 203 | } |
|---|
| 204 | } |
|---|
| 205 | if (pTextureNode) |
|---|
| 206 | { |
|---|
| 207 | TexOpType opType = TOT_MODULATE; |
|---|
| 208 | stat = loadTexture(pTextureNode,opType,uvsets,params); |
|---|
| 209 | delete pTextureNode; |
|---|
| 210 | if (MS::kSuccess != stat) |
|---|
| 211 | { |
|---|
| 212 | std::cout << "Error loading texture\n"; |
|---|
| 213 | std::cout.flush(); |
|---|
| 214 | return MS::kFailure; |
|---|
| 215 | } |
|---|
| 216 | } |
|---|
| 217 | } |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | return MS::kSuccess; |
|---|
| 221 | } |
|---|
| 222 | |
|---|
| 223 | |
|---|
| 224 | // Load a surface shader |
|---|
| 225 | MStatus Material::loadSurfaceShader(MFnDependencyNode *pShader) |
|---|
| 226 | { |
|---|
| 227 | int i; |
|---|
| 228 | m_type = MT_SURFACE_SHADER; |
|---|
| 229 | MPlugArray colorSrcPlugs; |
|---|
| 230 | // Check if material is textured |
|---|
| 231 | pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false); |
|---|
| 232 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 233 | { |
|---|
| 234 | if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture)) |
|---|
| 235 | { |
|---|
| 236 | m_isTextured = true; |
|---|
| 237 | continue; |
|---|
| 238 | } |
|---|
| 239 | else if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture)) |
|---|
| 240 | { |
|---|
| 241 | m_isTextured = true; |
|---|
| 242 | m_isMultiTextured = true; |
|---|
| 243 | continue; |
|---|
| 244 | } |
|---|
| 245 | } |
|---|
| 246 | |
|---|
| 247 | // Check if material is transparent |
|---|
| 248 | float trasp; |
|---|
| 249 | pShader->findPlug("outTransparencyR").getValue(trasp); |
|---|
| 250 | if (pShader->findPlug("outTransparency").isConnected() || trasp>0.0f) |
|---|
| 251 | m_isTransparent = true; |
|---|
| 252 | |
|---|
| 253 | // Get material colours |
|---|
| 254 | if (m_isTextured) |
|---|
| 255 | m_diffuse = MColor(1.0,1.0,1.0,1.0); |
|---|
| 256 | else |
|---|
| 257 | { |
|---|
| 258 | pShader->findPlug("outColorR").getValue(m_diffuse.r); |
|---|
| 259 | pShader->findPlug("outColorG").getValue(m_diffuse.g); |
|---|
| 260 | pShader->findPlug("outColorB").getValue(m_diffuse.b); |
|---|
| 261 | float trasp; |
|---|
| 262 | pShader->findPlug("outTransparencyR").getValue(trasp); |
|---|
| 263 | m_diffuse.a = 1.0 - trasp; |
|---|
| 264 | } |
|---|
| 265 | m_ambient = MColor(0,0,0,1); |
|---|
| 266 | m_emissive = MColor(0,0,0,1); |
|---|
| 267 | m_specular = MColor(0,0,0,1); |
|---|
| 268 | return MS::kSuccess; |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | // Load a lambert shader |
|---|
| 272 | MStatus Material::loadLambert(MFnDependencyNode *pShader) |
|---|
| 273 | { |
|---|
| 274 | int i; |
|---|
| 275 | MPlugArray colorSrcPlugs; |
|---|
| 276 | m_type = MT_LAMBERT; |
|---|
| 277 | MFnLambertShader* pLambert = new MFnLambertShader(pShader->object()); |
|---|
| 278 | // Check if material is textured |
|---|
| 279 | pLambert->findPlug("color").connectedTo(colorSrcPlugs,true,false); |
|---|
| 280 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 281 | { |
|---|
| 282 | if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture)) |
|---|
| 283 | { |
|---|
| 284 | m_isTextured = true; |
|---|
| 285 | continue; |
|---|
| 286 | } |
|---|
| 287 | else if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture)) |
|---|
| 288 | { |
|---|
| 289 | m_isTextured = true; |
|---|
| 290 | m_isMultiTextured = true; |
|---|
| 291 | continue; |
|---|
| 292 | } |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | // Check if material is transparent |
|---|
| 296 | if (pLambert->findPlug("transparency").isConnected() || pLambert->transparency().r>0.0f) |
|---|
| 297 | m_isTransparent = true; |
|---|
| 298 | |
|---|
| 299 | // Get material colours |
|---|
| 300 | //diffuse colour |
|---|
| 301 | if (m_isTextured) |
|---|
| 302 | m_diffuse = MColor(1.0,1.0,1.0,1.0); |
|---|
| 303 | else |
|---|
| 304 | { |
|---|
| 305 | m_diffuse = pLambert->color(); |
|---|
| 306 | m_diffuse.a = 1.0 - pLambert->transparency().r; |
|---|
| 307 | } |
|---|
| 308 | //ambient colour |
|---|
| 309 | m_ambient = pLambert->ambientColor(); |
|---|
| 310 | //emissive colour |
|---|
| 311 | m_emissive = pLambert->incandescence(); |
|---|
| 312 | //specular colour |
|---|
| 313 | m_specular = MColor(0,0,0,1); |
|---|
| 314 | delete pLambert; |
|---|
| 315 | return MS::kSuccess; |
|---|
| 316 | } |
|---|
| 317 | |
|---|
| 318 | // Load a phong shader |
|---|
| 319 | MStatus Material::loadPhong(MFnDependencyNode *pShader) |
|---|
| 320 | { |
|---|
| 321 | int i; |
|---|
| 322 | MPlugArray colorSrcPlugs; |
|---|
| 323 | m_type = MT_PHONG; |
|---|
| 324 | MFnPhongShader* pPhong = new MFnPhongShader(pShader->object()); |
|---|
| 325 | // Check if material is textured |
|---|
| 326 | pPhong->findPlug("color").connectedTo(colorSrcPlugs,true,false); |
|---|
| 327 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 328 | { |
|---|
| 329 | if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture)) |
|---|
| 330 | { |
|---|
| 331 | m_isTextured = true; |
|---|
| 332 | continue; |
|---|
| 333 | } |
|---|
| 334 | else if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture)) |
|---|
| 335 | { |
|---|
| 336 | m_isTextured = true; |
|---|
| 337 | m_isMultiTextured = true; |
|---|
| 338 | continue; |
|---|
| 339 | } |
|---|
| 340 | } |
|---|
| 341 | |
|---|
| 342 | // Check if material is transparent |
|---|
| 343 | if (pPhong->findPlug("transparency").isConnected() || pPhong->transparency().r>0.0f) |
|---|
| 344 | m_isTransparent = true; |
|---|
| 345 | |
|---|
| 346 | // Get material colours |
|---|
| 347 | //diffuse colour |
|---|
| 348 | if (m_isTextured) |
|---|
| 349 | m_diffuse = MColor(1.0,1.0,1.0,1.0); |
|---|
| 350 | else |
|---|
| 351 | { |
|---|
| 352 | m_diffuse = pPhong->color(); |
|---|
| 353 | m_diffuse.a = 1.0 - pPhong->transparency().r; |
|---|
| 354 | } |
|---|
| 355 | //ambient colour |
|---|
| 356 | m_ambient = pPhong->ambientColor(); |
|---|
| 357 | //emissive colour |
|---|
| 358 | m_emissive = pPhong->incandescence(); |
|---|
| 359 | //specular colour |
|---|
| 360 | m_specular = pPhong->specularColor(); |
|---|
| 361 | m_specular.a = pPhong->cosPower(); |
|---|
| 362 | delete pPhong; |
|---|
| 363 | return MS::kSuccess; |
|---|
| 364 | } |
|---|
| 365 | |
|---|
| 366 | // load a blinn shader |
|---|
| 367 | MStatus Material::loadBlinn(MFnDependencyNode *pShader) |
|---|
| 368 | { |
|---|
| 369 | int i; |
|---|
| 370 | MPlugArray colorSrcPlugs; |
|---|
| 371 | m_type = MT_BLINN; |
|---|
| 372 | MFnBlinnShader* pBlinn = new MFnBlinnShader(pShader->object()); |
|---|
| 373 | // Check if material is textured |
|---|
| 374 | pBlinn->findPlug("color").connectedTo(colorSrcPlugs,true,false); |
|---|
| 375 | for (i=0; i<colorSrcPlugs.length(); i++) |
|---|
| 376 | { |
|---|
| 377 | if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture)) |
|---|
| 378 | { |
|---|
| 379 | m_isTextured = true; |
|---|
| 380 | continue; |
|---|
| 381 | } |
|---|
| 382 | else if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture)) |
|---|
| 383 | { |
|---|
| 384 | m_isTextured = true; |
|---|
| 385 | m_isMultiTextured = true; |
|---|
| 386 | continue; |
|---|
| 387 | } |
|---|
| 388 | } |
|---|
| 389 | |
|---|
| 390 | // Check if material is transparent |
|---|
| 391 | if (pBlinn->findPlug("transparency").isConnected() || pBlinn->transparency().r>0.0f) |
|---|
| 392 | m_isTransparent = true; |
|---|
| 393 | |
|---|
| 394 | // Get material colours |
|---|
| 395 | //diffuse colour |
|---|
| 396 | if (m_isTextured) |
|---|
| 397 | m_diffuse = MColor(1.0,1.0,1.0,1.0); |
|---|
| 398 | else |
|---|
| 399 | { |
|---|
| 400 | m_diffuse = pBlinn->color(); |
|---|
| 401 | m_diffuse.a = 1.0 - pBlinn->transparency().r; |
|---|
| 402 | } |
|---|
| 403 | //ambient colour |
|---|
| 404 | m_ambient = pBlinn->ambientColor(); |
|---|
| 405 | //emissive colour |
|---|
| 406 | m_emissive = pBlinn->incandescence(); |
|---|
| 407 | //specular colour |
|---|
| 408 | m_specular = pBlinn->specularColor(); |
|---|
| 409 | m_specular.a = 1.0 / pBlinn->eccentricity(); |
|---|
| 410 | delete pBlinn; |
|---|
| 411 | return MS::kSuccess; |
|---|
| 412 | } |
|---|
| 413 | |
|---|
| 414 | // load a cgFx shader |
|---|
| 415 | MStatus Material::loadCgFxShader(MFnDependencyNode *pShader) |
|---|
| 416 | { |
|---|
| 417 | m_type = MT_CGFX; |
|---|
| 418 | // Create a default white lambert |
|---|
| 419 | m_isTextured = false; |
|---|
| 420 | m_isMultiTextured = false; |
|---|
| 421 | m_diffuse = MColor(1.0,1.0,1.0,1.0); |
|---|
| 422 | m_specular = MColor(0,0,0,1); |
|---|
| 423 | m_emissive = MColor(0,0,0,1); |
|---|
| 424 | m_ambient = MColor(0,0,0,1); |
|---|
| 425 | return MS::kSuccess; |
|---|
| 426 | } |
|---|
| 427 | |
|---|
| 428 | // Load texture data from a texture node |
|---|
| 429 | MStatus Material::loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params) |
|---|
| 430 | { |
|---|
| 431 | int j; |
|---|
| 432 | Texture tex; |
|---|
| 433 | // Get texture filename |
|---|
| 434 | MString filename, absFilename; |
|---|
| 435 | MRenderUtil::exactFileTextureName(pTexNode->object(),absFilename); |
|---|
| 436 | filename = absFilename.substring(absFilename.rindex('/')+1,absFilename.length()-1); |
|---|
| 437 | MString command = "toNativePath(\""; |
|---|
| 438 | command += absFilename; |
|---|
| 439 | command += "\")"; |
|---|
| 440 | MGlobal::executeCommand(command,absFilename); |
|---|
| 441 | tex.absFilename = absFilename; |
|---|
| 442 | tex.filename = filename; |
|---|
| 443 | tex.uvsetIndex = 0; |
|---|
| 444 | tex.uvsetName = ""; |
|---|
| 445 | // Set texture operation type |
|---|
| 446 | tex.opType = opType; |
|---|
| 447 | // Get connections to uvCoord attribute of texture node |
|---|
| 448 | MPlugArray texSrcPlugs; |
|---|
| 449 | pTexNode->findPlug("uvCoord").connectedTo(texSrcPlugs,true,false); |
|---|
| 450 | // Get place2dtexture node (if connected) |
|---|
| 451 | MFnDependencyNode* pPlace2dTexNode = NULL; |
|---|
| 452 | for (j=0; j<texSrcPlugs.length(); j++) |
|---|
| 453 | { |
|---|
| 454 | if (texSrcPlugs[j].node().hasFn(MFn::kPlace2dTexture)) |
|---|
| 455 | { |
|---|
| 456 | pPlace2dTexNode = new MFnDependencyNode(texSrcPlugs[j].node()); |
|---|
| 457 | continue; |
|---|
| 458 | } |
|---|
| 459 | } |
|---|
| 460 | // Get uvChooser node (if connected) |
|---|
| 461 | MFnDependencyNode* pUvChooserNode = NULL; |
|---|
| 462 | if (pPlace2dTexNode) |
|---|
| 463 | { |
|---|
| 464 | MPlugArray placetexSrcPlugs; |
|---|
| 465 | pPlace2dTexNode->findPlug("uvCoord").connectedTo(placetexSrcPlugs,true,false); |
|---|
| 466 | for (j=0; j<placetexSrcPlugs.length(); j++) |
|---|
| 467 | { |
|---|
| 468 | if (placetexSrcPlugs[j].node().hasFn(MFn::kUvChooser)) |
|---|
| 469 | { |
|---|
| 470 | pUvChooserNode = new MFnDependencyNode(placetexSrcPlugs[j].node()); |
|---|
| 471 | continue; |
|---|
| 472 | } |
|---|
| 473 | } |
|---|
| 474 | } |
|---|
| 475 | // Get uvset index |
|---|
| 476 | if (pUvChooserNode) |
|---|
| 477 | { |
|---|
| 478 | bool foundMesh = false; |
|---|
| 479 | bool foundUvset = false; |
|---|
| 480 | MPlug uvsetsPlug = pUvChooserNode->findPlug("uvSets"); |
|---|
| 481 | MPlugArray uvsetsSrcPlugs; |
|---|
| 482 | for (int i=0; i<uvsetsPlug.evaluateNumElements() && !foundMesh; i++) |
|---|
| 483 | { |
|---|
| 484 | uvsetsPlug[i].connectedTo(uvsetsSrcPlugs,true,false); |
|---|
| 485 | for (j=0; j<uvsetsSrcPlugs.length() && !foundMesh; j++) |
|---|
| 486 | { |
|---|
| 487 | if (uvsetsSrcPlugs[j].node().hasFn(MFn::kMesh)) |
|---|
| 488 | { |
|---|
| 489 | uvsetsSrcPlugs[j].getValue(tex.uvsetName); |
|---|
| 490 | for (int k=0; k<uvsets.length() && !foundUvset; k++) |
|---|
| 491 | { |
|---|
| 492 | if (uvsets[k] == tex.uvsetName) |
|---|
| 493 | { |
|---|
| 494 | tex.uvsetIndex = k; |
|---|
| 495 | foundUvset = true; |
|---|
| 496 | } |
|---|
| 497 | } |
|---|
| 498 | } |
|---|
| 499 | } |
|---|
| 500 | } |
|---|
| 501 | } |
|---|
| 502 | // Get texture options from Place2dTexture node |
|---|
| 503 | if (pPlace2dTexNode) |
|---|
| 504 | { |
|---|
| 505 | // Get address mode |
|---|
| 506 | //U |
|---|
| 507 | bool wrapU, mirrorU; |
|---|
| 508 | pPlace2dTexNode->findPlug("wrapU").getValue(wrapU); |
|---|
| 509 | pPlace2dTexNode->findPlug("mirrorU").getValue(mirrorU); |
|---|
| 510 | if (mirrorU) |
|---|
| 511 | tex.am_u = TAM_MIRROR; |
|---|
| 512 | else if (wrapU) |
|---|
| 513 | tex.am_u = TAM_WRAP; |
|---|
| 514 | else |
|---|
| 515 | tex.am_u = TAM_CLAMP; |
|---|
| 516 | // V |
|---|
| 517 | bool wrapV,mirrorV; |
|---|
| 518 | pPlace2dTexNode->findPlug("wrapV").getValue(wrapV); |
|---|
| 519 | pPlace2dTexNode->findPlug("mirrorV").getValue(mirrorV); |
|---|
| 520 | if (mirrorV) |
|---|
| 521 | tex.am_v = TAM_MIRROR; |
|---|
| 522 | else if (wrapV) |
|---|
| 523 | tex.am_v = TAM_WRAP; |
|---|
| 524 | else |
|---|
| 525 | tex.am_v = TAM_CLAMP; |
|---|
| 526 | // Get texture scale |
|---|
| 527 | double covU,covV; |
|---|
| 528 | pPlace2dTexNode->findPlug("coverageU").getValue(covU); |
|---|
| 529 | pPlace2dTexNode->findPlug("coverageV").getValue(covV); |
|---|
| 530 | tex.scale_u = covU; |
|---|
| 531 | if (fabs(tex.scale_u) < PRECISION) |
|---|
| 532 | tex.scale_u = 0; |
|---|
| 533 | tex.scale_v = covV; |
|---|
| 534 | if (fabs(tex.scale_v) < PRECISION) |
|---|
| 535 | tex.scale_v = 0; |
|---|
| 536 | // Get texture scroll |
|---|
| 537 | double transU,transV; |
|---|
| 538 | pPlace2dTexNode->findPlug("translateFrameU").getValue(transU); |
|---|
| 539 | pPlace2dTexNode->findPlug("translateFrameV").getValue(transV); |
|---|
| 540 | tex.scroll_u = -0.5 * (covU-1.0)/covU - transU/covU; |
|---|
| 541 | if (fabs(tex.scroll_u) < PRECISION) |
|---|
| 542 | tex.scroll_u = 0; |
|---|
| 543 | tex.scroll_v = 0.5 * (covV-1.0)/covV + transV/covV; |
|---|
| 544 | if (fabs(tex.scroll_v) < PRECISION) |
|---|
| 545 | tex.scroll_v = 0; |
|---|
| 546 | // Get texture rotation |
|---|
| 547 | double rot; |
|---|
| 548 | pPlace2dTexNode->findPlug("rotateFrame").getValue(rot); |
|---|
| 549 | tex.rot = -rot; |
|---|
| 550 | if (fabs(rot) < PRECISION) |
|---|
| 551 | tex.rot = 0; |
|---|
| 552 | } |
|---|
| 553 | // add texture to material texture list |
|---|
| 554 | m_textures.push_back(tex); |
|---|
| 555 | // free up memory |
|---|
| 556 | if (pUvChooserNode) |
|---|
| 557 | delete pUvChooserNode; |
|---|
| 558 | if (pPlace2dTexNode) |
|---|
| 559 | delete pPlace2dTexNode; |
|---|
| 560 | |
|---|
| 561 | return MS::kSuccess; |
|---|
| 562 | } |
|---|
| 563 | |
|---|
| 564 | |
|---|
| 565 | // Write material data to an Ogre material script file |
|---|
| 566 | MStatus Material::writeOgreScript(ParamList ¶ms) |
|---|
| 567 | { |
|---|
| 568 | //Start material description |
|---|
| 569 | params.outMaterial << "material " << m_name.asChar() << "\n"; |
|---|
| 570 | params.outMaterial << "{\n"; |
|---|
| 571 | |
|---|
| 572 | //Start technique description |
|---|
| 573 | params.outMaterial << "\ttechnique\n"; |
|---|
| 574 | params.outMaterial << "\t{\n"; |
|---|
| 575 | |
|---|
| 576 | //Start render pass description |
|---|
| 577 | params.outMaterial << "\t\tpass\n"; |
|---|
| 578 | params.outMaterial << "\t\t{\n"; |
|---|
| 579 | //set lighting off option if requested |
|---|
| 580 | if (m_lightingOff) |
|---|
| 581 | params.outMaterial << "\t\t\tlighting off\n\n"; |
|---|
| 582 | //ambient colour |
|---|
| 583 | params.outMaterial << "\t\t\tambient " << m_ambient.r << " " << m_ambient.g << " " << m_ambient.b |
|---|
| 584 | << " " << m_ambient.a << "\n"; |
|---|
| 585 | //diffuse colour |
|---|
| 586 | params.outMaterial << "\t\t\tdiffuse " << m_diffuse.r << " " << m_diffuse.g << " " << m_diffuse.b |
|---|
| 587 | << " " << m_diffuse.a << "\n"; |
|---|
| 588 | //specular colour |
|---|
| 589 | params.outMaterial << "\t\t\tspecular " << m_specular.r << " " << m_specular.g << " " << m_specular.b |
|---|
| 590 | << " " << m_specular.a << "\n"; |
|---|
| 591 | //emissive colour |
|---|
| 592 | params.outMaterial << "\t\t\temissive " << m_emissive.r << " " << m_emissive.g << " " |
|---|
| 593 | << m_emissive.b << "\n"; |
|---|
| 594 | //if material is transparent set blend mode and turn off depth_writing |
|---|
| 595 | if (m_isTransparent) |
|---|
| 596 | { |
|---|
| 597 | params.outMaterial << "\n\t\t\tscene_blend alpha_blend\n"; |
|---|
| 598 | params.outMaterial << "\t\t\tdepth_write off\n"; |
|---|
| 599 | } |
|---|
| 600 | //write texture units |
|---|
| 601 | for (int i=0; i<m_textures.size(); i++) |
|---|
| 602 | { |
|---|
| 603 | //start texture unit description |
|---|
| 604 | params.outMaterial << "\n\t\t\ttexture_unit\n"; |
|---|
| 605 | params.outMaterial << "\t\t\t{\n"; |
|---|
| 606 | //write texture name |
|---|
| 607 | params.outMaterial << "\t\t\t\ttexture " << m_textures[i].filename.asChar() << "\n"; |
|---|
| 608 | //write texture coordinate index |
|---|
| 609 | params.outMaterial << "\t\t\t\ttex_coord_set " << m_textures[i].uvsetIndex << "\n"; |
|---|
| 610 | //write colour operation |
|---|
| 611 | switch (m_textures[i].opType) |
|---|
| 612 | { |
|---|
| 613 | case TOT_REPLACE: |
|---|
| 614 | params.outMaterial << "\t\t\t\tcolour_op replace\n"; |
|---|
| 615 | break; |
|---|
| 616 | case TOT_ADD: |
|---|
| 617 | params.outMaterial << "\t\t\t\tcolour_op add\n"; |
|---|
| 618 | break; |
|---|
| 619 | case TOT_MODULATE: |
|---|
| 620 | params.outMaterial << "\t\t\t\tcolour_op modulate\n"; |
|---|
| 621 | break; |
|---|
| 622 | case TOT_ALPHABLEND: |
|---|
| 623 | params.outMaterial << "\t\t\t\tcolour_op alpha_blend\n"; |
|---|
| 624 | break; |
|---|
| 625 | } |
|---|
| 626 | //write texture transforms |
|---|
| 627 | params.outMaterial << "\t\t\t\tscale " << m_textures[i].scale_u << " " << m_textures[i].scale_v << "\n"; |
|---|
| 628 | params.outMaterial << "\t\t\t\tscroll " << m_textures[i].scroll_u << " " << m_textures[i].scroll_v << "\n"; |
|---|
| 629 | params.outMaterial << "\t\t\t\trotate " << m_textures[i].rot << "\n"; |
|---|
| 630 | //end texture unit desription |
|---|
| 631 | params.outMaterial << "\t\t\t}\n"; |
|---|
| 632 | } |
|---|
| 633 | |
|---|
| 634 | //End render pass description |
|---|
| 635 | params.outMaterial << "\t\t}\n"; |
|---|
| 636 | |
|---|
| 637 | //End technique description |
|---|
| 638 | params.outMaterial << "\t}\n"; |
|---|
| 639 | |
|---|
| 640 | //End material description |
|---|
| 641 | params.outMaterial << "}\n"; |
|---|
| 642 | |
|---|
| 643 | //Copy textures to output dir if required |
|---|
| 644 | if (params.copyTextures) |
|---|
| 645 | copyTextures(params); |
|---|
| 646 | |
|---|
| 647 | return MS::kSuccess; |
|---|
| 648 | } |
|---|
| 649 | |
|---|
| 650 | |
|---|
| 651 | // Copy textures to path specified by params |
|---|
| 652 | MStatus Material::copyTextures(ParamList ¶ms) |
|---|
| 653 | { |
|---|
| 654 | for (int i=0; i<m_textures.size(); i++) |
|---|
| 655 | { |
|---|
| 656 | // Copy file texture to output dir |
|---|
| 657 | MString command = "copy \""; |
|---|
| 658 | command += m_textures[i].absFilename; |
|---|
| 659 | command += "\" \""; |
|---|
| 660 | command += params.texOutputDir; |
|---|
| 661 | command += "\""; |
|---|
| 662 | system(command.asChar()); |
|---|
| 663 | } |
|---|
| 664 | return MS::kSuccess; |
|---|
| 665 | } |
|---|
| 666 | |
|---|
| 667 | }; //end namespace |
|---|