From b123c0823445f61fc4d5b4d8f4e375babb2cdc3e Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Thu, 11 Oct 2007 19:22:39 +0000 Subject: [PATCH] First half of maya2egg texture overhaul complete. Code stable. --- pandatool/src/maya/mayaShader.cxx | 246 +++++++++++++++++-- pandatool/src/maya/mayaShader.h | 41 +++- pandatool/src/maya/mayaShaderColorDef.cxx | 224 +++++++++++++++-- pandatool/src/maya/mayaShaderColorDef.h | 65 +++-- pandatool/src/maya/mayaShaders.cxx | 55 ++++- pandatool/src/maya/mayaShaders.h | 9 +- pandatool/src/mayaegg/mayaToEggConverter.cxx | 146 +++-------- pandatool/src/mayaegg/mayaToEggConverter.h | 6 +- pandatool/src/mayaprogs/mayaCopy.cxx | 7 +- 9 files changed, 609 insertions(+), 190 deletions(-) diff --git a/pandatool/src/maya/mayaShader.cxx b/pandatool/src/maya/mayaShader.cxx index e78a5a1ef9..cac901c32c 100644 --- a/pandatool/src/maya/mayaShader.cxx +++ b/pandatool/src/maya/mayaShader.cxx @@ -26,6 +26,8 @@ #include "pre_maya_include.h" #include #include +#include +#include #include #include #include @@ -50,15 +52,28 @@ MayaShader(MObject engine) { << "Reading shading engine " << get_name() << "\n"; } - bool found_shader = false; + _legacy_mode = false; + _flat_color.set(1,1,1,1); + MPlug shader_plug = engine_fn.findPlug("surfaceShader"); + bool found_shader = false; if (!shader_plug.isNull()) { MPlugArray shader_pa; shader_plug.connectedTo(shader_pa, true, false); maya_cat.spam() << "shader plug connected to: " << shader_pa.length() << endl; for (size_t i = 0; i < shader_pa.length() && !found_shader; i++) { MObject shader = shader_pa[0].node(); - found_shader = read_surface_shader(shader); + if (shader.hasFn(MFn::kPhong)) { + found_shader = find_textures_modern(shader); + } else if (shader.hasFn(MFn::kLambert)) { + found_shader = find_textures_legacy(shader); + if (found_shader) { + _legacy_mode = true; + } + } else { + maya_cat.warning() << + "Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n"; + } } } } @@ -70,9 +85,6 @@ MayaShader(MObject engine) { //////////////////////////////////////////////////////////////////// MayaShader:: ~MayaShader() { - for (size_t i=0; i<_color.size(); ++i) { - _color.pop_back(); - } } //////////////////////////////////////////////////////////////////// @@ -92,21 +104,13 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// void MayaShader:: write(ostream &out) const { - out << "Shader " << get_name() << "\n" - << " color:\n"; - - for (size_t i=0; i<_color.size(); ++i) { - _color[i]->write(out); - } - - out << " transparency:\n"; - _transparency.write(out); + out << "Shader " << get_name() << "\n"; } //////////////////////////////////////////////////////////////////// // Function: MayaShader::get_color_def // Access: Public -// Description: Now that the shaders can have multiple textures +// Description: This is part of the deprecated codepath. // return the color def i.e. texture at idx //////////////////////////////////////////////////////////////////// MayaShaderColorDef *MayaShader:: @@ -154,13 +158,213 @@ get_rgba(size_t idx) const { } //////////////////////////////////////////////////////////////////// -// Function: MayaShader::read_surface_shader +// Function: MayaShader::collect_maps // Access: Private -// Description: Extracts out the shading information from the Maya +// Description: Recalculates the all_maps list. +//////////////////////////////////////////////////////////////////// +void MayaShader:: +collect_maps() { + _all_maps.clear(); + + for (size_t i=0; i<_color_maps.size(); i++) { + _all_maps.push_back(_color_maps[i]); + } + for (size_t i=0; i<_trans_maps.size(); i++) { + _all_maps.push_back(_trans_maps[i]); + } + for (size_t i=0; i<_normal_maps.size(); i++) { + _all_maps.push_back(_normal_maps[i]); + } + for (size_t i=0; i<_gloss_maps.size(); i++) { + _all_maps.push_back(_gloss_maps[i]); + } + + for (size_t i=0; i<_color.size(); i++) { + if (_color[i]->_has_texture) { + _all_maps.push_back(_color[i]); + } + } + if (_transparency._has_texture) { + _all_maps.push_back(&_transparency); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::find_textures_modern +// Access: Private +// Description: Locates all file textures leading into the given +// shader. +//////////////////////////////////////////////////////////////////// +bool MayaShader:: +find_textures_modern(MObject shader) { + if (!shader.hasFn(MFn::kPhong)) { + maya_cat.warning() + << "The new codepath expects to see phong shaders only.\n"; + return false; + } + MStatus status; + MFnPhongShader phong_fn(shader); + MFnDependencyNode shader_fn(shader); + + if (maya_cat.is_spam()) { + maya_cat.spam() + << " Reading surface shader " << shader_fn.name().asChar() << "\n"; + } + + string n = shader_fn.name().asChar(); + + MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color")); + MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency")); + MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera")); + MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor")); + + collect_maps(); + + MColor color = phong_fn.color(&status); + if (status) { + _flat_color.set(color.r, color.g, color.b, color.a); + } + + color = phong_fn.transparency(&status); + if (status) { + _flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0)); + } + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::bind_uvsets +// Access: Public +// Description: Assigns the uvset_name of each MayaShaderColorDef +// using the given file-to-uvset map. +//////////////////////////////////////////////////////////////////// +void MayaShader:: +bind_uvsets(MayaFileToUVSetMap &map) { + for (size_t i=0; i<_all_maps.size(); i++) { + MayaShaderColorDef *def = _all_maps[i]; + MayaFileToUVSetMap::iterator p = map.find(def->_texture_name); + if (p == map.end()) { + def->_uvset_name = "default"; + } else { + def->_uvset_name = (*p).second; + } + } + + calculate_pairings(); +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::calculate_pairings +// Access: Public +// Description: For each Alpha texture, try to find an RGB texture +// that has the same properties. Attempt to make it +// so that the alpha texture isn't a separate texture, +// but rather, an Alpha-Filename associated with an +// existing texture. +//////////////////////////////////////////////////////////////////// +void MayaShader:: +calculate_pairings() { + + for (size_t i=0; i<_all_maps.size(); i++) { + _all_maps[i]->_opposite = 0; + } + + for (size_t i=0; i<_color_maps.size(); i++) { + for (size_t j=0; j<_trans_maps.size(); j++) { + try_pair(_color_maps[i], _trans_maps[j], true); + } + } + for (size_t i=0; i<_normal_maps.size(); i++) { + for (size_t j=0; j<_gloss_maps.size(); j++) { + try_pair(_normal_maps[i], _gloss_maps[j], true); + } + } + for (size_t i=0; i<_color_maps.size(); i++) { + for (size_t j=0; j<_trans_maps.size(); j++) { + try_pair(_color_maps[i], _trans_maps[j], false); + } + } + for (size_t i=0; i<_normal_maps.size(); i++) { + for (size_t j=0; j<_gloss_maps.size(); j++) { + try_pair(_normal_maps[i], _gloss_maps[j], false); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::try_pair +// Access: Private +// Description: Try to associate an RGB tex with an Alpha tex. +//////////////////////////////////////////////////////////////////// +void MayaShader::try_pair(MayaShaderColorDef *map1, + MayaShaderColorDef *map2, + bool perfect) { + if ((map1->_opposite)||(map2->_opposite)) { + // one of the maps is already paired + return; + } + if (perfect) { + if (map1->_texture_filename != map2->_texture_filename) { + // perfect mode requires a filename match. + return; + } + } else { + string pre1 = get_file_prefix(map1->_texture_filename); + string pre2 = get_file_prefix(map2->_texture_filename); + if (pre1 != pre2) { + // imperfect mode requires a filename prefix match. + return; + } + } + + if ((map1->_projection_type != map2->_projection_type) || + (map1->_projection_matrix != map2->_projection_matrix) || + (map1->_u_angle != map2->_u_angle) || + (map1->_v_angle != map2->_v_angle) || + (map1->_uvset_name != map2->_uvset_name) || + (map1->_mirror != map2->_mirror) || + (map1->_stagger != map2->_stagger) || + (map1->_wrap_u != map2->_wrap_u) || + (map1->_wrap_v != map2->_wrap_v) || + (map1->_repeat_uv != map2->_repeat_uv) || + (map1->_offset != map2->_offset) || + (map1->_rotate_uv != map2->_rotate_uv)) { + return; + } + // Pairing successful. + map1->_opposite = map2; + map2->_opposite = map1; +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::get_file_prefix +// Access: Private +// Description: Try to associate an RGB tex with an Alpha tex. +//////////////////////////////////////////////////////////////////// +string MayaShader:: +get_file_prefix(const string &fn) { + Filename pfn = Filename::from_os_specific(fn); + string base = pfn.get_basename_wo_extension(); + size_t offs = base.find("_"); + if (offs != string::npos) { + base = base.substr(0, offs); + } + offs = base.find("-"); + if (offs != string::npos) { + base = base.substr(0, offs); + } + return base; +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::find_textures_legacy +// Access: Private +// Description: This is part of the legacy codepath. +// Extracts out the shading information from the Maya // surface shader. //////////////////////////////////////////////////////////////////// bool MayaShader:: -read_surface_shader(MObject shader) { +find_textures_legacy(MObject shader) { MStatus status; MFnDependencyNode shader_fn(shader); @@ -188,7 +392,7 @@ read_surface_shader(MObject shader) { MayaShaderColorDef *color_p = new MayaShaderColorDef; for (size_t i = 0; i < color_pa.length(); i++) { maya_cat.spam() << "color_pa[" << i << "]:" << color_pa[i].name().asChar() << endl; - color_p->read_surface_color(this, color_pa[0].node()); + color_p->find_textures_legacy(this, color_pa[0].node()); } if (color_pa.length() < 1) { @@ -210,7 +414,7 @@ read_surface_shader(MObject shader) { for (size_t i = 0; i < trans_pa.length(); i++) { maya_cat.spam() << "read a transparency texture" << endl; - _transparency.read_surface_color(this, trans_pa[0].node(), true); + _transparency.find_textures_legacy(this, trans_pa[0].node(), true); } } @@ -250,5 +454,7 @@ read_surface_shader(MObject shader) { << " Color definition not found.\n"; } } + + collect_maps(); return true; } diff --git a/pandatool/src/maya/mayaShader.h b/pandatool/src/maya/mayaShader.h index 48b75e700e..b5517ed20e 100644 --- a/pandatool/src/maya/mayaShader.h +++ b/pandatool/src/maya/mayaShader.h @@ -43,18 +43,41 @@ public: void output(ostream &out) const; void write(ostream &out) const; + +private: + bool find_textures_modern(MObject shader); + bool find_textures_legacy(MObject shader); +public: + void collect_maps(); + bool _legacy_mode; + + MayaShaderColorList _all_maps; + +public: // relevant only to modern mode. + + Colord _flat_color; + + MayaShaderColorList _color_maps; + MayaShaderColorList _trans_maps; + MayaShaderColorList _normal_maps; + MayaShaderColorList _gloss_maps; + + void bind_uvsets(MayaFileToUVSetMap &map); + +private: + void calculate_pairings(); + void try_pair(MayaShaderColorDef *map1, + MayaShaderColorDef *map2, + bool perfect); + string get_file_prefix(const string &fn); + +public: // relevant only to legacy mode. + + MayaShaderColorList _color; + MayaShaderColorDef _transparency; Colorf get_rgba(size_t idx=0) const; MayaShaderColorDef *get_color_def(size_t idx=0) const; - - MayaShaderColorDef _transparency; - //MayaShaderColorDef _color; - // There could be multiple textures, so create an array of these colordefs - typedef pvector ColorDef; - ColorDef _color; - -private: - bool read_surface_shader(MObject shader); }; INLINE ostream &operator << (ostream &out, const MayaShader &shader) { diff --git a/pandatool/src/maya/mayaShaderColorDef.cxx b/pandatool/src/maya/mayaShaderColorDef.cxx index 4e05c99351..f940d7ff30 100644 --- a/pandatool/src/maya/mayaShaderColorDef.cxx +++ b/pandatool/src/maya/mayaShaderColorDef.cxx @@ -39,17 +39,18 @@ //////////////////////////////////////////////////////////////////// MayaShaderColorDef:: MayaShaderColorDef() { - _color_gain.set(1.0f, 1.0f, 1.0f, 1.0f); - _has_flat_color = false; - _flat_color.set(0.0, 0.0, 0.0, 0.0); + _blend_type = BT_unspecified; - _has_texture = false; - _texture_name = ""; - _uvset_name = "default"; _projection_type = PT_off; - _map_uvs = NULL; - + _projection_matrix = LMatrix4d::ident_mat(); + _u_angle = 0.0; + _v_angle = 0.0; + + _texture_filename = ""; + _texture_name = ""; + _color_gain.set(1.0f, 1.0f, 1.0f, 1.0f); + _coverage.set(1.0, 1.0); _translate_frame.set(0.0, 0.0); _rotate_frame = 0.0; @@ -59,18 +60,24 @@ MayaShaderColorDef() { _wrap_u = true; _wrap_v = true; - _has_alpha_channel = false; - _keep_color = false; // classic mode overwrites color: new mode retains color with a 3rd layer - _keep_alpha = false; - _interpolate = false; - - _blend_type = BT_unspecified; - _repeat_uv.set(1.0, 1.0); _offset.set(0.0, 0.0); _rotate_uv = 0.0; + _opposite = 0; + _color_object = (MObject *)NULL; + + _has_texture = false; + _has_flat_color = false; + _flat_color.set(0.0, 0.0, 0.0, 0.0); + _has_alpha_channel = false; + _keep_color = false; // classic mode overwrites color: new mode retains color with a 3rd layer + _keep_alpha = false; + _interpolate = false; + _uvset_name = "default"; + + _map_uvs = NULL; } //////////////////////////////////////////////////////////////////// @@ -115,6 +122,8 @@ MayaShaderColorDef(MayaShaderColorDef ©) { _map_uvs = copy._map_uvs; _color_object = copy._color_object; + + _opposite = 0; } //////////////////////////////////////////////////////////////////// @@ -253,14 +262,15 @@ strip_prefix(string full_name) { } //////////////////////////////////////////////////////////////////// -// Function: MayaShaderColorDef::read_surface_color +// Function: MayaShaderColorDef::find_textures_legacy // Access: Private -// Description: Determines the surface color specified by the shader. +// Description: This is part of the deprecated codepath. +// Determines the surface color specified by the shader. // This includes texturing and other advanced shader // properties. //////////////////////////////////////////////////////////////////// void MayaShaderColorDef:: -read_surface_color(MayaShader *shader, MObject color, bool trans) { +find_textures_legacy(MayaShader *shader, MObject color, bool trans) { RGBColorf color_gain; if (get_vec3f_attribute(color, "colorGain", color_gain)) { color_gain[0] = color_gain[0] > 1.0 ? 1.0 : color_gain[0]; @@ -331,7 +341,7 @@ read_surface_color(MayaShader *shader, MObject color, bool trans) { image_plug.connectedTo(image_pa, true, false); for (size_t i = 0; i < image_pa.length(); i++) { - read_surface_color(shader, image_pa[0].node()); + find_textures_legacy(shader, image_pa[0].node()); } } @@ -438,7 +448,7 @@ read_surface_color(MayaShader *shader, MObject color, bool trans) { maya_cat.debug() << pl.name().asChar() << " next:connectedTo: " << pla_name << endl; } MayaShaderColorDef *color_p = new MayaShaderColorDef; - color_p->read_surface_color(shader, pla[j].node()); + color_p->find_textures_legacy(shader, pla[j].node()); color_p->_texture_name.assign(pla[j].name().asChar()); color_p->_blend_type = bt; size_t loc = color_p->_texture_name.find('.',0); @@ -453,7 +463,7 @@ read_surface_color(MayaShader *shader, MObject color, bool trans) { if (maya_cat.is_debug()) { maya_cat.debug() << pl.name().asChar() << " first:connectedTo: " << pla_name << endl; } - read_surface_color(shader, pla[j].node()); + find_textures_legacy(shader, pla[j].node()); _texture_name.assign(pla[j].name().asChar()); _blend_type = bt; size_t loc = _texture_name.find('.',0); @@ -487,6 +497,178 @@ read_surface_color(MayaShader *shader, MObject color, bool trans) { } } +//////////////////////////////////////////////////////////////////// +// Function: MayaShaderColorDef::find_textures +// Access: Private +// Description: Search to find any file textures that lead into the +// given input plug. Any textures found will be added +// to the provided MayaShaderColorList. +//////////////////////////////////////////////////////////////////// +void MayaShaderColorDef:: +find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug) { + + MPlugArray outplugs; + inplug.connectedTo(outplugs, true, false); + if (outplugs.length() == 0) { + return; + } + if (outplugs.length() > 1) { + // Only one output plug should be connected to a given input plug. + maya_cat.warning() + << "Shader " << shadername << " has weird plug connections.\n"; + return; + } + MPlug outplug = outplugs[0]; + MObject source = outplug.node(); + MFnDependencyNode sourceFn(source); + + if (source.hasFn(MFn::kFileTexture)) { + + string filename; + bool hasfn = get_string_attribute(source, "fileTextureName", filename); + if ((!hasfn) || (filename.empty())) { + maya_cat.warning() + << "Shader " << shadername << " references file texture " + << "with no file name, ignoring invalid file texture.\n"; + return; + } + Filename fn = filename; + if (fn.is_directory()) { + maya_cat.warning() + << "Shader " << shadername << " references file name " + << filename << " which is a directory, ignoring it.\n"; + return; + } + + MayaShaderColorDef *def = new MayaShaderColorDef; + + def->_color_object = new MObject(source); + def->_texture_filename = Filename::from_os_specific(filename); + def->_texture_name = sourceFn.name().asChar(); + + get_vec2f_attribute(source, "coverage", def->_coverage); + get_vec2f_attribute(source, "translateFrame", def->_translate_frame); + get_angle_attribute(source, "rotateFrame", def->_rotate_frame); + + get_bool_attribute(source, "mirror", def->_mirror); + get_bool_attribute(source, "stagger", def->_stagger); + get_bool_attribute(source, "wrapU", def->_wrap_u); + get_bool_attribute(source, "wrapV", def->_wrap_v); + + get_vec2f_attribute(source, "repeatUV", def->_repeat_uv); + get_vec2f_attribute(source, "offset", def->_offset); + get_angle_attribute(source, "rotateUV", def->_rotate_uv); + + RGBColorf color_gain; + float alpha_gain; + get_vec3f_attribute(source, "colorGain", color_gain); + get_maya_attribute(source, "alphaGain", alpha_gain); + def->_color_gain[0] = color_gain[0]; + def->_color_gain[1] = color_gain[1]; + def->_color_gain[2] = color_gain[2]; + def->_color_gain[3] = alpha_gain; + + if (maya_cat.is_debug()) { + maya_cat.debug() << "pushed a file texture" << endl; + } + list.push_back(def); + + return; + } + + if (source.hasFn(MFn::kProjection)) { + // This is a projected texture. We will have to step one level + // deeper to find the actual texture. + size_t before = list.size(); + MPlug image_plug = sourceFn.findPlug("image"); + if (!image_plug.isNull()) { + MPlugArray image_pa; + image_plug.connectedTo(image_pa, true, false); + + for (size_t i = 0; i < image_pa.length(); i++) { + find_textures_modern(shadername, list, image_pa[0]); + } + } + + // Now apply any inherited attributes to all textures found. + + for (size_t i=before; i_projection_matrix)) { + def->_projection_matrix = LMatrix4d::ident_mat(); + } + + // The uAngle and vAngle might be used for certain kinds of + // projections. + if (!get_angle_attribute(source, "uAngle", def->_u_angle)) { + def->_u_angle = 360.0; + } + if (!get_angle_attribute(source, "vAngle", def->_v_angle)) { + def->_v_angle = 180.0; + } + + string type; + if (get_enum_attribute(source, "projType", type)) { + def->set_projection_type(type); + } + } + return; + } + + if (source.hasFn(MFn::kLayeredTexture)) { + if (maya_cat.is_debug()) { + maya_cat.debug() << "Found layered texture" << endl; + } + + MPlug inputsPlug = sourceFn.findPlug("inputs"); + size_t nlayers = inputsPlug.numElements(); + for (size_t layer=0; layer < nlayers; layer++) { + MPlug elt = inputsPlug.elementByPhysicalIndex(layer); + MPlug color; + MPlug blend; + for (size_t j=0; j_blend_type = BT_decal; break; + case 6: def->_blend_type = BT_modulate; break; + case 4: def->_blend_type = BT_add; break; + } + } + } + } + + // This shader wasn't understood. + if (maya_cat.is_debug()) { + maya_cat.info() + << "**Don't know how to interpret color attribute type " + << source.apiTypeStr() << "\n"; + } else { + // If we don't have a heavy verbose count, only report each type + // of unsupported shader once. + static pset bad_types; + if (bad_types.insert(source.apiType()).second) { + maya_cat.info() + << "**Don't know how to interpret color attribute type " + << source.apiTypeStr() << "\n"; + } + } +} + //////////////////////////////////////////////////////////////////// // Function: MayaShaderColorDef::set_projection_type // Access: Private diff --git a/pandatool/src/maya/mayaShaderColorDef.h b/pandatool/src/maya/mayaShaderColorDef.h index cf90c9701c..62d59ab9b8 100755 --- a/pandatool/src/maya/mayaShaderColorDef.h +++ b/pandatool/src/maya/mayaShaderColorDef.h @@ -25,7 +25,11 @@ #include "lmatrix.h" class MObject; +class MPlug; class MayaShader; +class MayaShaderColorDef; +typedef pvector MayaShaderColorList; +typedef pmap MayaFileToUVSetMap; //////////////////////////////////////////////////////////////////// // Class : MayaShaderColorDef @@ -36,7 +40,7 @@ class MayaShader; class MayaShaderColorDef { public: MayaShaderColorDef(); - MayaShaderColorDef(MayaShaderColorDef&); + MayaShaderColorDef (MayaShaderColorDef&); ~MayaShaderColorDef(); string strip_prefix(string full_name); @@ -58,8 +62,6 @@ public: BT_blend_color_scale, }; - BlendType _blend_type; - enum ProjectionType { PT_off, PT_planar, @@ -71,21 +73,17 @@ public: PT_concentric, PT_perspective, }; - + + BlendType _blend_type; ProjectionType _projection_type; LMatrix4d _projection_matrix; double _u_angle; double _v_angle; - bool _has_texture; Filename _texture_filename; string _texture_name; - string _uvset_name; Colorf _color_gain; - bool _has_flat_color; - Colord _flat_color; - LVector2f _coverage; LVector2f _translate_frame; double _rotate_frame; @@ -95,17 +93,19 @@ public: bool _wrap_u; bool _wrap_v; - bool _has_alpha_channel; - bool _keep_color; - bool _keep_alpha; - bool _interpolate; - LVector2f _repeat_uv; LVector2f _offset; double _rotate_uv; + MayaShaderColorDef *_opposite; + private: - void read_surface_color(MayaShader *shader, MObject color, bool trans=false); + MObject *_color_object; + +private: + static void find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug); + void find_textures_legacy(MayaShader *shader, MObject color, bool trans=false); + void set_projection_type(const string &type); LPoint2d map_planar(const LPoint3d &pos, const LPoint3d ¢roid) const; @@ -115,9 +115,40 @@ private: // Define a pointer to one of the above member functions. LPoint2d (MayaShaderColorDef::*_map_uvs)(const LPoint3d &pos, const LPoint3d ¢roid) const; - MObject *_color_object; - friend class MayaShader; + + + // Deprecated Fields - these fields are only used by the + // deprecated codepath. These fields are deprecated for the + // following reasons: + // + // * has_texture is redundant --- if there's no + // texture, just don't allocate a MayaShaderColorDef. + // + // * has_flat_color and flat_color don't belong here, + // they belong in the shader. + // + // * has_alpha_channel is not needed - there are better + // ways to determine if a texture stage involves an alpha + // channel. + // + // * keep_color, keep_alpha, and interpolate are all + // adjuncts to blend_mode - it would make more sense just to + // add some more blend_modes. + // + // * uvset_name is a property of a mesh, not a property + // of a shader. It varies as you move through the scene. + +public: + bool _has_texture; // deprecated, see above. + bool _has_flat_color; // deprecated, see above. + Colord _flat_color; // deprecated, see above. + bool _has_alpha_channel; // deprecated, see above. + bool _keep_color; // deprecated, see above. + bool _keep_alpha; // deprecated, see above. + bool _interpolate; // deprecated, see above. + string _uvset_name; // deprecated, see above. + }; #endif diff --git a/pandatool/src/maya/mayaShaders.cxx b/pandatool/src/maya/mayaShaders.cxx index ffdf968fca..8d25f1d092 100644 --- a/pandatool/src/maya/mayaShaders.cxx +++ b/pandatool/src/maya/mayaShaders.cxx @@ -100,6 +100,41 @@ find_shader_for_node(MObject node) { return (MayaShader *)NULL; } +//////////////////////////////////////////////////////////////////// +// Function: MayaShaders::bind_uvsets +// Access: Public +// Description: Causes all shaders in the set to use the given +// mesh as a file-to-uvset map. +//////////////////////////////////////////////////////////////////// +void MayaShaders:: +bind_uvsets(MObject mesh) { + _uvset_names.clear(); + _file_to_uvset.clear(); + + if (mesh.hasFn(MFn::kMesh)) { + MFnMesh mesh_fn(mesh); + MStatus status; + MStringArray maya_uvset_names; + status = mesh_fn.getUVSetNames(maya_uvset_names); + for (size_t i=0; ibind_uvsets(_file_to_uvset); + } +} + //////////////////////////////////////////////////////////////////// // Function: MayaShaders::find_shader_for_shading_engine // Access: Public @@ -122,13 +157,30 @@ find_shader_for_shading_engine(MObject engine) { // All right, this is a newly encountered shading engine. Create a // new MayaShader object to represent it. MayaShader *shader = new MayaShader(engine); - + shader->bind_uvsets(_file_to_uvset); + // Record this for the future. _shaders.insert(Shaders::value_type(engine_name, shader)); _shaders_in_order.push_back(shader); return shader; } +//////////////////////////////////////////////////////////////////// +// Function: MayaShaders::find_uv_link +// Access: Public +// Description: Returns the current mapping from file to uvset +// for the given file texture name. +//////////////////////////////////////////////////////////////////// +string MayaShaders:: +find_uv_link(const string &match) { + MayaFileToUVSetMap::iterator it = _file_to_uvset.find(match); + if (it == _file_to_uvset.end()) { + return "not found"; + } else { + return (*it).second; + } +} + //////////////////////////////////////////////////////////////////// // Function: MayaShaders::get_num_shaders // Access: Public @@ -167,4 +219,5 @@ clear() { _shaders.clear(); _shaders_in_order.clear(); + _file_to_uvset.clear(); } diff --git a/pandatool/src/maya/mayaShaders.h b/pandatool/src/maya/mayaShaders.h index 3b986c96b1..4f360b6b0d 100644 --- a/pandatool/src/maya/mayaShaders.h +++ b/pandatool/src/maya/mayaShaders.h @@ -23,6 +23,7 @@ #include "pmap.h" #include "pvector.h" +#include "mayaShaderColorDef.h" class MayaShader; class MObject; @@ -38,11 +39,15 @@ public: ~MayaShaders(); MayaShader *find_shader_for_node(MObject node); MayaShader *find_shader_for_shading_engine(MObject engine); - + int get_num_shaders() const; MayaShader *get_shader(int n) const; - + + MayaFileToUVSetMap _file_to_uvset; + pvector _uvset_names; void clear(); + void bind_uvsets(MObject mesh); + string find_uv_link(const string &match); private: typedef pmap Shaders; diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index c114cd1d26..6ead0e7747 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -1685,32 +1685,6 @@ make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve, } } -//////////////////////////////////////////////////////////////////// -// Function: MayaShader::find_uv_link -// Access: Private -// Description: given the texture name, find corresponding uvLink -//////////////////////////////////////////////////////////////////// -string MayaToEggConverter:: -find_uv_link(string match) { - // find the index of this string in the _tex_names - int idx = 0; - vector_string::iterator vi; - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ful: looking for " << match << endl; - } - for (vi = _tex_names.begin(); vi != _tex_names.end(); ++vi, ++idx) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ful:" << idx << ":stored_name is " << vi->c_str() << endl; - } - if (vi->find(match) != string::npos) { - return _uvset_names[idx]; - } - } - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ful: did not find uvset-texture link called:" << match << endl; - } - return "not found"; -} //////////////////////////////////////////////////////////////////// // Function: MayaShader::round uvs // Access: Private @@ -1725,58 +1699,7 @@ round(double value) { else return floor( value + 0.5); } -/* -//////////////////////////////////////////////////////////////////// -// Function: MayaToEggConverter::store_tex_names -// Access: Private -// Description: check the uvsets and see what texture these are -// connected to. set_shader_attribute will use this -// information to write eggTexture -//////////////////////////////////////////////////////////////////// -void MayaToEggConverter:: -make_tex_names(const MFnMesh &mesh, const MObject &mesh_object) { - // test the connection editor to gather the uvLink to the texture name - MFnDependencyNode dn(mesh_object); - MStringArray mresult; - MPlugArray pla; - - _tex_names.clear(); - dn.getConnections(pla); - mayaegg_cat.info() << "number of connections: " << pla.length() << endl; - string uv1("uvLink -query -uvSet "); - uv1.append(mesh.name().asChar()); - uv1.append(".uvSet[0].uvSetName"); - MGlobal::executeCommand(MString(uv1.c_str()), mresult); - string tcat; - for (size_t k=0; ktref.size is " << egg_poly->get_num_textures() << endl; } - for (size_t ti=0; ti< _uvset_names.size(); ++ti) { + for (size_t ti=0; ti< _shaders._uvset_names.size(); ++ti) { // get the eggTexture pointer - string colordef_uv_name = uvset_name= _uvset_names[ti]; + string colordef_uv_name = uvset_name= _shaders._uvset_names[ti]; if (mayaegg_cat.is_debug()) { mayaegg_cat.debug() << "--uvset_name :" << uvset_name << endl; } @@ -2569,7 +2495,7 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, mayaegg_cat.debug() << "ssa:texture name[" << i << "]: " << color_def->_texture_name << endl; } - string uvset_name = find_uv_link(color_def->_texture_name); + string uvset_name = _shaders.find_uv_link(color_def->_texture_name); if (mayaegg_cat.is_debug()) { mayaegg_cat.debug() << "ssa:corresponding uvset name is " << uvset_name << endl; } @@ -2752,7 +2678,7 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, new_tex->set_uv_name(color_def->_uvset_name); if (i == (int)shader._color.size()-1 && is_decal) { dummy_uvset_name.assign(color_def->_uvset_name); - } + } } } else { primitive.add_texture(new_tex); diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index 9be6fc367e..d503ad35bb 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -25,6 +25,7 @@ #include "mayaApi.h" #include "mayaShaders.h" +#include "mayaShaderColorDef.h" #include "eggTextureCollection.h" #include "distanceUnit.h" #include "coordinateSystem.h" @@ -154,15 +155,10 @@ private: bool reparent_decals(EggGroupNode *egg_parent); - string find_uv_link(string match); - int round(double value); string _program_name; - vector_string _uvset_names; - vector_string _tex_names; - bool _from_selection; string _subroot; typedef pvector Globs; diff --git a/pandatool/src/mayaprogs/mayaCopy.cxx b/pandatool/src/mayaprogs/mayaCopy.cxx index 9abe3cf0ed..d0626f52ab 100644 --- a/pandatool/src/mayaprogs/mayaCopy.cxx +++ b/pandatool/src/mayaprogs/mayaCopy.cxx @@ -253,14 +253,11 @@ copy_maya_file(const Filename &source, const Filename &dest, int num_shaders = _shaders.get_num_shaders(); for (int i = 0; i < num_shaders; i++) { MayaShader *shader = _shaders.get_shader(i); - for (size_t j = 0; j < shader->_color.size(); j++) { - if (!extract_texture(*shader->get_color_def(j), dir)) { + for (size_t j = 0; j < shader->_all_maps.size(); j++) { + if (!extract_texture(*shader->_all_maps[j], dir)) { return false; } } - if (!extract_texture(shader->_transparency, dir)) { - return false; - } } // Now write out the Maya file.