00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "mayaShader.h"
00018 #include "maya_funcs.h"
00019 #include "config_maya.h"
00020 #include "string_utils.h"
00021 #include "pnmImageHeader.h"
00022 #include "pset.h"
00023
00024 #include "pre_maya_include.h"
00025 #include <maya/MFnDependencyNode.h>
00026 #include <maya/MFnLambertShader.h>
00027 #include <maya/MFnPhongShader.h>
00028 #include <maya/MFnMesh.h>
00029 #include <maya/MPlug.h>
00030 #include <maya/MPlugArray.h>
00031 #include <maya/MColor.h>
00032 #include <maya/MObject.h>
00033 #include <maya/MStatus.h>
00034 #include "post_maya_include.h"
00035
00036
00037
00038
00039
00040
00041
00042 MayaShader::
00043 MayaShader(MObject engine, bool legacy_shader) {
00044 MFnDependencyNode engine_fn(engine);
00045
00046 set_name(engine_fn.name().asChar());
00047
00048 if (maya_cat.is_debug()) {
00049 maya_cat.debug()
00050 << "Reading shading engine " << get_name() << "\n";
00051 }
00052 _legacy_mode = false;
00053 _flat_color.set(1,1,1,1);
00054
00055 MPlug shader_plug = engine_fn.findPlug("surfaceShader");
00056 bool found_shader = false;
00057 if (!shader_plug.isNull()) {
00058 MPlugArray shader_pa;
00059 shader_plug.connectedTo(shader_pa, true, false);
00060 maya_cat.spam() << "shader plug connected to: " << shader_pa.length() << endl;
00061 for (size_t i = 0; i < shader_pa.length() && !found_shader; i++) {
00062 MObject shader = shader_pa[0].node();
00063 if (shader.hasFn(MFn::kPhong)) {
00064 if (legacy_shader) {
00065 found_shader = find_textures_legacy(shader);
00066 } else {
00067 found_shader = find_textures_modern(shader);
00068 }
00069 } else if (shader.hasFn(MFn::kLambert)) {
00070 found_shader = find_textures_legacy(shader);
00071 if (found_shader) {
00072 _legacy_mode = true;
00073 }
00074 } else if (shader.hasFn(MFn::kSurfaceShader)) {
00075 found_shader = find_textures_legacy(shader);
00076 if (found_shader) {
00077 _legacy_mode = true;
00078 }
00079 } else {
00080 maya_cat.warning() <<
00081 "Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n";
00082 }
00083 }
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092 MayaShader::
00093 ~MayaShader() {
00094 }
00095
00096
00097
00098
00099
00100
00101 void MayaShader::
00102 output(ostream &out) const {
00103 out << "Shader " << get_name();
00104 }
00105
00106
00107
00108
00109
00110
00111 void MayaShader::
00112 write(ostream &out) const {
00113 out << "Shader " << get_name() << "\n";
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 MayaShaderColorDef *MayaShader::
00123 get_color_def(size_t idx) const {
00124 if (_color.size() > 0)
00125 return _color[idx];
00126 else
00127 return (MayaShaderColorDef *)NULL;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 LColor MayaShader::
00143 get_rgba(size_t idx) const {
00144 LColor rgba(1.0f, 1.0f, 1.0f, 1.0f);
00145
00146 if (_color.size() && _color[idx]->_has_flat_color) {
00147 rgba[0] = (PN_stdfloat)_color[idx]->_flat_color[0];
00148 rgba[1] = (PN_stdfloat)_color[idx]->_flat_color[1];
00149 rgba[2] = (PN_stdfloat)_color[idx]->_flat_color[2];
00150 }
00151
00152 if (_transparency._has_flat_color) {
00153
00154
00155
00156 double trans =
00157 _transparency._flat_color[0] * lumin_red +
00158 _transparency._flat_color[1] * lumin_grn +
00159 _transparency._flat_color[2] * lumin_blu;
00160 rgba[3] = 1.0f - (PN_stdfloat)trans;
00161 }
00162
00163 return rgba;
00164 }
00165
00166
00167
00168
00169
00170
00171 void MayaShader::
00172 collect_maps() {
00173 _all_maps.clear();
00174
00175 for (size_t i=0; i<_color_maps.size(); i++) {
00176 _all_maps.push_back(_color_maps[i]);
00177 }
00178 for (size_t i=0; i<_trans_maps.size(); i++) {
00179 _all_maps.push_back(_trans_maps[i]);
00180 }
00181 for (size_t i=0; i<_normal_maps.size(); i++) {
00182 _all_maps.push_back(_normal_maps[i]);
00183 }
00184 for (size_t i=0; i<_glow_maps.size(); i++) {
00185 _all_maps.push_back(_glow_maps[i]);
00186 }
00187 for (size_t i=0; i<_gloss_maps.size(); i++) {
00188 _all_maps.push_back(_gloss_maps[i]);
00189 }
00190 for (size_t i=0; i<_height_maps.size(); i++) {
00191 _all_maps.push_back(_height_maps[i]);
00192 }
00193
00194 for (size_t i=0; i<_color.size(); i++) {
00195 if (_color[i]->_has_texture) {
00196 _all_maps.push_back(_color[i]);
00197 }
00198 }
00199 if (_transparency._has_texture) {
00200 _all_maps.push_back(&_transparency);
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 bool MayaShader::
00211 find_textures_modern(MObject shader) {
00212 if (!shader.hasFn(MFn::kPhong)) {
00213 maya_cat.warning()
00214 << "The new codepath expects to see phong shaders only.\n";
00215 return false;
00216 }
00217 MStatus status;
00218 MFnPhongShader phong_fn(shader);
00219 MFnDependencyNode shader_fn(shader);
00220
00221 if (maya_cat.is_spam()) {
00222 maya_cat.spam()
00223 << " Reading modern surface shader " << shader_fn.name().asChar() << "\n";
00224 }
00225
00226 string n = shader_fn.name().asChar();
00227
00228 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color"), false);
00229 if (_color_maps.size() == 0) {
00230 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("colorR"), false);
00231 }
00232 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency"), true);
00233 if (_trans_maps.size() == 0) {
00234 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparencyR"), true);
00235 }
00236 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera"), false);
00237 if (_normal_maps.size() == 0) {
00238 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCameraR"), false);
00239 }
00240 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor"), true);
00241 if (_gloss_maps.size() == 0) {
00242 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColorR"), true);
00243 }
00244 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescence"), true);
00245 if (_glow_maps.size() == 0) {
00246 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true);
00247 }
00248 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"), true);
00249 if (_height_maps.size() == 0) {
00250 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"), true);
00251 }
00252
00253 collect_maps();
00254
00255 MColor color = phong_fn.color(&status);
00256 if (status) {
00257 _flat_color.set(color.r, color.g, color.b, color.a);
00258 }
00259
00260 color = phong_fn.transparency(&status);
00261 if (status) {
00262 _flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0));
00263 }
00264 return true;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 void MayaShader::
00274 bind_uvsets(MayaFileToUVSetMap &map) {
00275 for (size_t i=0; i<_all_maps.size(); i++) {
00276 MayaShaderColorDef *def = _all_maps[i];
00277 MayaFileToUVSetMap::iterator p = map.find(def->_texture_name);
00278 if (p == map.end()) {
00279 def->_uvset_name = "map1";
00280 } else {
00281 def->_uvset_name = (*p).second;
00282 }
00283 }
00284
00285 calculate_pairings();
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 void MayaShader::
00298 calculate_pairings() {
00299
00300 if (_legacy_mode) {
00301 return;
00302 }
00303
00304 for (size_t i=0; i<_all_maps.size(); i++) {
00305 _all_maps[i]->_opposite = 0;
00306 }
00307
00308 bool using_transparency = (_trans_maps.size() > 0);
00309
00310 for (int retry=0; retry<2; retry++) {
00311 bool perfect=(retry==0);
00312 for (size_t i=0; i<_color_maps.size(); i++) {
00313 if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)||
00314 (_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) {
00315 for (size_t j=0; j<_trans_maps.size(); j++) {
00316 try_pair(_color_maps[i], _trans_maps[j], perfect);
00317 }
00318 }
00319 }
00320 }
00321
00322 if (!using_transparency) {
00323 for (int retry=0; retry<2; retry++) {
00324 bool perfect=(retry==0);
00325 for (size_t i=0; i<_color_maps.size(); i++) {
00326 for (size_t j=0; j<_glow_maps.size(); j++) {
00327 try_pair(_color_maps[i], _glow_maps[j], perfect);
00328 }
00329 for (size_t j=0; j<_gloss_maps.size(); j++) {
00330 try_pair(_color_maps[i], _gloss_maps[j], perfect);
00331 }
00332 }
00333 }
00334 }
00335
00336 for (int retry=0; retry<2; retry++) {
00337 bool perfect=(retry==0);
00338 for (size_t i=0; i<_normal_maps.size(); i++) {
00339 for (size_t j=0; j<_height_maps.size(); j++) {
00340 try_pair(_normal_maps[i], _height_maps[j], perfect);
00341 }
00342 }
00343 }
00344
00345 for (size_t i=0; i<_normal_maps.size(); i++) {
00346 _normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
00347 }
00348 for (size_t i=0; i<_glow_maps.size(); i++) {
00349 if (_glow_maps[i]->_opposite) {
00350 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
00351 _glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
00352 } else {
00353 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
00354 }
00355 }
00356 for (size_t i=0; i<_gloss_maps.size(); i++) {
00357 if (_gloss_maps[i]->_opposite) {
00358 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
00359 _gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
00360 } else {
00361 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
00362 }
00363 }
00364 for (size_t i=0; i<_height_maps.size(); i++) {
00365 if (_height_maps[i]->_opposite) {
00366 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
00367 _height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
00368 } else {
00369 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
00370 }
00371 }
00372 for (size_t i=0; i<_trans_maps.size(); i++) {
00373 if (_trans_maps[i]->_opposite) {
00374 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
00375 _trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
00376 } else {
00377 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387 bool MayaShader::try_pair(MayaShaderColorDef *map1,
00388 MayaShaderColorDef *map2,
00389 bool perfect) {
00390 if ((map1->_opposite)||(map2->_opposite)) {
00391
00392 return false;
00393 }
00394 if (perfect) {
00395 if (map1->_texture_filename != map2->_texture_filename) {
00396
00397 return false;
00398 }
00399 } else {
00400 string pre1 = get_file_prefix(map1->_texture_filename);
00401 string pre2 = get_file_prefix(map2->_texture_filename);
00402 if (pre1 != pre2) {
00403
00404 return false;
00405 }
00406 }
00407
00408 if ((map1->_projection_type != map2->_projection_type) ||
00409 (map1->_projection_matrix != map2->_projection_matrix) ||
00410 (map1->_u_angle != map2->_u_angle) ||
00411 (map1->_v_angle != map2->_v_angle) ||
00412 (map1->_uvset_name != map2->_uvset_name) ||
00413 (map1->_mirror != map2->_mirror) ||
00414 (map1->_stagger != map2->_stagger) ||
00415 (map1->_wrap_u != map2->_wrap_u) ||
00416 (map1->_wrap_v != map2->_wrap_v) ||
00417 (map1->_repeat_uv != map2->_repeat_uv) ||
00418 (map1->_offset != map2->_offset) ||
00419 (map1->_rotate_uv != map2->_rotate_uv)) {
00420 return false;
00421 }
00422
00423 map1->_opposite = map2;
00424 map2->_opposite = map1;
00425 return true;
00426 }
00427
00428
00429
00430
00431
00432
00433 string MayaShader::
00434 get_file_prefix(const string &fn) {
00435 Filename pfn = Filename::from_os_specific(fn);
00436 string base = pfn.get_basename_wo_extension();
00437 size_t offs = base.find("_");
00438 if (offs != string::npos) {
00439 base = base.substr(0, offs);
00440 }
00441 offs = base.find("-");
00442 if (offs != string::npos) {
00443 base = base.substr(0, offs);
00444 }
00445 return base;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 bool MayaShader::
00456 find_textures_legacy(MObject shader) {
00457 MStatus status;
00458 MFnDependencyNode shader_fn(shader);
00459
00460 if (maya_cat.is_spam()) {
00461 maya_cat.spam()
00462 << " Reading legacy surface shader " << shader_fn.name().asChar() << "\n";
00463 }
00464
00465
00466
00467
00468
00469 MPlug color_plug = shader_fn.findPlug("color");
00470 if (color_plug.isNull()) {
00471
00472
00473
00474 color_plug = shader_fn.findPlug("outColor");
00475 }
00476
00477 if (!color_plug.isNull()) {
00478 MPlugArray color_pa;
00479 color_plug.connectedTo(color_pa, true, false);
00480
00481 MayaShaderColorDef *color_p = new MayaShaderColorDef;
00482 for (size_t i = 0; i < color_pa.length(); i++) {
00483 maya_cat.spam() << "color_pa[" << i << "]:" << color_pa[i].name().asChar() << endl;
00484 color_p->find_textures_legacy(this, color_pa[0].node());
00485 }
00486
00487 if (color_pa.length() < 1) {
00488
00489 maya_cat.spam() << shader_fn.name().asChar() << " was not connected to texture" << endl;
00490 this->_color.push_back(color_p);
00491 }
00492 }
00493
00494
00495 MPlug trans_plug = shader_fn.findPlug("transparency");
00496 if (trans_plug.isNull()) {
00497 trans_plug = shader_fn.findPlug("outTransparency");
00498 }
00499
00500 if (!trans_plug.isNull()) {
00501 MPlugArray trans_pa;
00502 trans_plug.connectedTo(trans_pa, true, false);
00503
00504 for (size_t i = 0; i < trans_pa.length(); i++) {
00505 maya_cat.spam() << "read a transparency texture" << endl;
00506 _transparency.find_textures_legacy(this, trans_pa[0].node(), true);
00507 }
00508 }
00509
00510
00511
00512 bool b_color_def = true;
00513 if (shader.hasFn(MFn::kLambert)) {
00514 MFnLambertShader lambert_fn(shader);
00515 MColor color = lambert_fn.color(&status);
00516 if (status) {
00517
00518
00519 for (size_t i=0; i<_color.size(); ++i) {
00520 _color[i]->_has_flat_color = true;
00521 _color[i]->_flat_color.set(color.r, color.g, color.b, color.a);
00522 maya_cat.spam() << shader_fn.name().asChar() << " set shader color" << endl;
00523
00524 if (!_color[i]->_has_flat_color && !_color[i]->_has_texture)
00525 b_color_def = false;
00526
00527 _transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
00528
00529
00530 color = lambert_fn.transparency(&status);
00531 if (status) {
00532 _transparency._has_flat_color = true;
00533 _transparency._flat_color.set(color.r, color.g, color.b, color.a);
00534 }
00535 }
00536 }
00537 }
00538
00539 if (!b_color_def) {
00540 maya_cat.info() << shader_fn.name().asChar() << "Color def not found" << endl;
00541 if (maya_cat.is_spam()) {
00542 maya_cat.spam()
00543 << " Color definition not found.\n";
00544 }
00545 }
00546
00547 collect_maps();
00548 return true;
00549 }