24 #include <maya/MFnDependencyNode.h>
25 #include <maya/MFnLambertShader.h>
26 #include <maya/MFnPhongShader.h>
27 #include <maya/MFnMesh.h>
28 #include <maya/MPlug.h>
29 #include <maya/MPlugArray.h>
30 #include <maya/MColor.h>
31 #include <maya/MObject.h>
32 #include <maya/MStatus.h>
43 MayaShader(MObject engine,
bool legacy_shader) {
44 MFnDependencyNode engine_fn(engine);
46 set_name(engine_fn.name().asChar());
48 if (maya_cat.is_debug()) {
50 <<
"Reading shading engine " << get_name() <<
"\n";
53 _flat_color.set(1,1,1,1);
55 MPlug shader_plug = engine_fn.findPlug(
"surfaceShader");
56 bool found_shader =
false;
57 if (!shader_plug.isNull()) {
59 shader_plug.connectedTo(shader_pa,
true,
false);
60 maya_cat.spam() <<
"shader plug connected to: " << shader_pa.length() << endl;
61 for (
size_t i = 0; i < shader_pa.length() && !found_shader; i++) {
62 MObject shader = shader_pa[0].node();
63 if (shader.hasFn(MFn::kPhong)) {
65 found_shader = find_textures_legacy(shader);
67 found_shader = find_textures_modern(shader);
69 }
else if (shader.hasFn(MFn::kLambert)) {
70 found_shader = find_textures_legacy(shader);
74 }
else if (shader.hasFn(MFn::kSurfaceShader)) {
75 found_shader = find_textures_legacy(shader);
81 "Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n";
98 output(std::ostream &out)
const {
99 out <<
"Shader " << get_name();
106 write(std::ostream &out)
const {
107 out <<
"Shader " << get_name() <<
"\n";
116 if (_color.size() > 0)
132 LColor rgba(1.0f, 1.0f, 1.0f, 1.0f);
134 if (_color.size() && _color[idx]->_has_flat_color) {
135 rgba[0] = (PN_stdfloat)_color[idx]->_flat_color[0];
136 rgba[1] = (PN_stdfloat)_color[idx]->_flat_color[1];
137 rgba[2] = (PN_stdfloat)_color[idx]->_flat_color[2];
140 if (_transparency._has_flat_color) {
145 _transparency._flat_color[0] * lumin_red +
146 _transparency._flat_color[1] * lumin_grn +
147 _transparency._flat_color[2] * lumin_blu;
148 rgba[3] = 1.0f - (PN_stdfloat)trans;
161 for (
size_t i=0; i<_color_maps.size(); i++) {
162 _all_maps.push_back(_color_maps[i]);
164 for (
size_t i=0; i<_trans_maps.size(); i++) {
165 _all_maps.push_back(_trans_maps[i]);
167 for (
size_t i=0; i<_normal_maps.size(); i++) {
168 _all_maps.push_back(_normal_maps[i]);
170 for (
size_t i=0; i<_glow_maps.size(); i++) {
171 _all_maps.push_back(_glow_maps[i]);
173 for (
size_t i=0; i<_gloss_maps.size(); i++) {
174 _all_maps.push_back(_gloss_maps[i]);
176 for (
size_t i=0; i<_height_maps.size(); i++) {
177 _all_maps.push_back(_height_maps[i]);
180 for (
size_t i=0; i<_color.size(); i++) {
181 if (_color[i]->_has_texture) {
182 _all_maps.push_back(_color[i]);
185 if (_transparency._has_texture) {
186 _all_maps.push_back(&_transparency);
194 find_textures_modern(MObject shader) {
195 if (!shader.hasFn(MFn::kPhong)) {
197 <<
"The new codepath expects to see phong shaders only.\n";
201 MFnPhongShader phong_fn(shader);
202 MFnDependencyNode shader_fn(shader);
204 if (maya_cat.is_spam()) {
206 <<
" Reading modern surface shader " << shader_fn.name().asChar() <<
"\n";
209 string n = shader_fn.name().asChar();
211 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug(
"color"),
false);
212 if (_color_maps.size() == 0) {
213 MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug(
"colorR"),
false);
215 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug(
"transparency"),
true);
216 if (_trans_maps.size() == 0) {
217 MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug(
"transparencyR"),
true);
219 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug(
"normalCamera"),
false);
220 if (_normal_maps.size() == 0) {
221 MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug(
"normalCameraR"),
false);
223 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug(
"specularColor"),
true);
224 if (_gloss_maps.size() == 0) {
225 MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug(
"specularColorR"),
true);
227 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug(
"incandescence"),
true);
228 if (_glow_maps.size() == 0) {
229 MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug(
"incandescenceR"),
true);
231 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug(
"surfaceThickness"),
true);
232 if (_height_maps.size() == 0) {
233 MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug(
"surfaceThicknessR"),
true);
238 MColor color = phong_fn.color(&status);
240 _flat_color.set(color.r, color.g, color.b, color.a);
243 color = phong_fn.transparency(&status);
245 _flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0));
256 for (
size_t i=0; i<_all_maps.size(); i++) {
258 MayaFileToUVSetMap::iterator p = map.find(def->_texture_name);
259 if (p == map.end()) {
260 def->_uvset_name =
"map1";
262 def->_uvset_name = (*p).second;
266 calculate_pairings();
275 calculate_pairings() {
281 for (
size_t i=0; i<_all_maps.size(); i++) {
282 _all_maps[i]->_opposite = 0;
285 bool using_transparency = (_trans_maps.size() > 0);
287 for (
int retry=0; retry<2; retry++) {
288 bool perfect=(retry==0);
289 for (
size_t i=0; i<_color_maps.size(); i++) {
290 if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)||
291 (_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) {
292 for (
size_t j=0; j<_trans_maps.size(); j++) {
293 try_pair(_color_maps[i], _trans_maps[j], perfect);
299 if (!using_transparency) {
300 for (
int retry=0; retry<2; retry++) {
301 bool perfect=(retry==0);
302 for (
size_t i=0; i<_color_maps.size(); i++) {
303 for (
size_t j=0; j<_glow_maps.size(); j++) {
304 try_pair(_color_maps[i], _glow_maps[j], perfect);
306 for (
size_t j=0; j<_gloss_maps.size(); j++) {
307 try_pair(_color_maps[i], _gloss_maps[j], perfect);
313 for (
int retry=0; retry<2; retry++) {
314 bool perfect=(retry==0);
315 for (
size_t i=0; i<_normal_maps.size(); i++) {
316 for (
size_t j=0; j<_height_maps.size(); j++) {
317 try_pair(_normal_maps[i], _height_maps[j], perfect);
322 for (
size_t i=0; i<_normal_maps.size(); i++) {
323 _normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
325 for (
size_t i=0; i<_glow_maps.size(); i++) {
326 if (_glow_maps[i]->_opposite) {
327 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
328 _glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
330 _glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
333 for (
size_t i=0; i<_gloss_maps.size(); i++) {
334 if (_gloss_maps[i]->_opposite) {
335 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
336 _gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
338 _gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
341 for (
size_t i=0; i<_height_maps.size(); i++) {
342 if (_height_maps[i]->_opposite) {
343 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
344 _height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
346 _height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
349 for (
size_t i=0; i<_trans_maps.size(); i++) {
350 if (_trans_maps[i]->_opposite) {
351 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
352 _trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
354 _trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
365 if ((map1->_opposite)||(map2->_opposite)) {
370 if (map1->_texture_filename != map2->_texture_filename) {
375 string pre1 = get_file_prefix(map1->_texture_filename);
376 string pre2 = get_file_prefix(map2->_texture_filename);
383 if ((map1->_projection_type != map2->_projection_type) ||
384 (map1->_projection_matrix != map2->_projection_matrix) ||
385 (map1->_u_angle != map2->_u_angle) ||
386 (map1->_v_angle != map2->_v_angle) ||
387 (map1->_uvset_name != map2->_uvset_name) ||
388 (map1->_mirror != map2->_mirror) ||
389 (map1->_stagger != map2->_stagger) ||
390 (map1->_wrap_u != map2->_wrap_u) ||
391 (map1->_wrap_v != map2->_wrap_v) ||
392 (map1->_repeat_uv != map2->_repeat_uv) ||
393 (map1->_offset != map2->_offset) ||
394 (map1->_rotate_uv != map2->_rotate_uv)) {
398 map1->_opposite = map2;
399 map2->_opposite = map1;
407 get_file_prefix(
const string &fn) {
410 size_t offs = base.find(
"_");
411 if (offs != string::npos) {
412 base = base.substr(0, offs);
414 offs = base.find(
"-");
415 if (offs != string::npos) {
416 base = base.substr(0, offs);
426 find_textures_legacy(MObject shader) {
428 MFnDependencyNode shader_fn(shader);
430 if (maya_cat.is_spam()) {
432 <<
" Reading legacy surface shader " << shader_fn.name().asChar() <<
"\n";
439 MPlug color_plug = shader_fn.findPlug(
"color");
440 if (color_plug.isNull()) {
443 color_plug = shader_fn.findPlug(
"outColor");
446 if (!color_plug.isNull()) {
448 color_plug.connectedTo(color_pa,
true,
false);
451 for (
size_t i = 0; i < color_pa.length(); i++) {
452 maya_cat.spam() <<
"color_pa[" << i <<
"]:" << color_pa[i].name().asChar() << endl;
453 color_p->find_textures_legacy(
this, color_pa[0].node());
456 if (color_pa.length() < 1) {
458 maya_cat.spam() << shader_fn.name().asChar() <<
" was not connected to texture" << endl;
459 this->_color.push_back(color_p);
464 MPlug trans_plug = shader_fn.findPlug(
"transparency");
465 if (trans_plug.isNull()) {
466 trans_plug = shader_fn.findPlug(
"outTransparency");
469 if (!trans_plug.isNull()) {
471 trans_plug.connectedTo(trans_pa,
true,
false);
473 for (
size_t i = 0; i < trans_pa.length(); i++) {
474 maya_cat.spam() <<
"read a transparency texture" << endl;
475 _transparency.find_textures_legacy(
this, trans_pa[0].node(),
true);
480 bool b_color_def =
true;
481 if (shader.hasFn(MFn::kLambert)) {
482 MFnLambertShader lambert_fn(shader);
483 MColor color = lambert_fn.color(&status);
487 for (
size_t i=0; i<_color.size(); ++i) {
488 _color[i]->_has_flat_color =
true;
489 _color[i]->_flat_color.set(color.r, color.g, color.b, color.a);
490 maya_cat.spam() << shader_fn.name().asChar() <<
" set shader color" << endl;
492 if (!_color[i]->_has_flat_color && !_color[i]->_has_texture)
495 _transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
498 color = lambert_fn.transparency(&status);
500 _transparency._has_flat_color =
true;
501 _transparency._flat_color.set(color.r, color.g, color.b, color.a);
508 maya_cat.info() << shader_fn.name().asChar() <<
"Color def not found" << endl;
509 if (maya_cat.is_spam()) {
511 <<
" Color definition not found.\n";
The name of a file, such as a texture file or an Egg file.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
This defines the various attributes that Maya may associate with the "color" channel for a particular...
MayaShader(MObject engine, bool legacy_shader)
Reads the Maya "shading engine" to determine the relevant shader properties.
void collect_maps()
Recalculates the all_maps list.
LColor get_rgba(size_t idx=0) const
Returns the overall color of the shader as a single-precision rgba value, where the alpha component r...
MayaShaderColorDef * get_color_def(size_t idx=0) const
This is part of the deprecated codepath.
void bind_uvsets(MayaFileToUVSetMap &map)
Assigns the uvset_name of each MayaShaderColorDef using the given file-to- uvset map.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.