From ce2e5ec10ce2cadfff7de66cb3bd02eede97463b Mon Sep 17 00:00:00 2001 From: Mike Christel Date: Fri, 19 Mar 2010 17:35:21 +0000 Subject: [PATCH] new options "legacy-shaders" and "texture-copy"; egger now supports vertex color, flat color, and file textures in any combination with Maya Phong materials --- pandatool/src/maya/mayaShader.cxx | 48 +++--- pandatool/src/maya/mayaShader.h | 7 +- pandatool/src/maya/mayaShaderColorDef.cxx | 53 ++++++- pandatool/src/maya/mayaShaderColorDef.h | 4 +- pandatool/src/maya/mayaShaders.cxx | 15 +- pandatool/src/maya/mayaShaders.h | 4 +- pandatool/src/mayaegg/mayaToEggConverter.cxx | 147 ++++++++++++++----- pandatool/src/mayaegg/mayaToEggConverter.h | 11 +- pandatool/src/mayaprogs/mayaCopy.cxx | 8 +- pandatool/src/mayaprogs/mayaToEgg.cxx | 47 ++++++ pandatool/src/mayaprogs/mayaToEgg.h | 4 + 11 files changed, 268 insertions(+), 80 deletions(-) diff --git a/pandatool/src/maya/mayaShader.cxx b/pandatool/src/maya/mayaShader.cxx index 49e95b11e0..f9beb3ff00 100644 --- a/pandatool/src/maya/mayaShader.cxx +++ b/pandatool/src/maya/mayaShader.cxx @@ -1,5 +1,7 @@ // Filename: mayaShader.cxx // Created by: drose (01Feb00) +// Modified 19Mar10 by ETC PandaSE team (see +// header comment for mayaToEgg.cxx for details) // //////////////////////////////////////////////////////////////////// // @@ -38,7 +40,7 @@ // relevant shader properties. //////////////////////////////////////////////////////////////////// MayaShader:: -MayaShader(MObject engine) { +MayaShader(MObject engine, bool texture_copy, Filename tout_dir, bool legacy_shader) { MFnDependencyNode engine_fn(engine); set_name(engine_fn.name().asChar()); @@ -47,7 +49,9 @@ MayaShader(MObject engine) { maya_cat.debug() << "Reading shading engine " << get_name() << "\n"; } - + // passing the output texture dir to the shader constructor + _texture_copy = texture_copy; + _texture_out_dir = tout_dir; _legacy_mode = false; _flat_color.set(1,1,1,1); @@ -59,8 +63,12 @@ MayaShader(MObject engine) { 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(); - if (shader.hasFn(MFn::kPhong)) { - found_shader = find_textures_modern(shader); + if (shader.hasFn(MFn::kPhong)) { + if (legacy_shader) { + found_shader = find_textures_legacy(shader); + } else { + found_shader = find_textures_modern(shader); + } } else if (shader.hasFn(MFn::kLambert)) { found_shader = find_textures_legacy(shader); if (found_shader) { @@ -215,34 +223,34 @@ find_textures_modern(MObject shader) { if (maya_cat.is_spam()) { maya_cat.spam() - << " Reading surface shader " << shader_fn.name().asChar() << "\n"; + << " Reading modern surface shader " << shader_fn.name().asChar() << "\n"; } string n = shader_fn.name().asChar(); - MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color"), false); + MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color"), _texture_copy, _texture_out_dir,false); if (_color_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("colorR"), false); + MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("colorR"),_texture_copy, _texture_out_dir, false); } - MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency"), true); + MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency"),_texture_copy, _texture_out_dir, true); if (_trans_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparencyR"), true); + MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparencyR"),_texture_copy, _texture_out_dir, true); } - MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera"), false); + MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera"),_texture_copy, _texture_out_dir, false); if (_normal_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCameraR"), false); + MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCameraR"),_texture_copy, _texture_out_dir, false); } - MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor"), true); + MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor"),_texture_copy, _texture_out_dir, true); if (_gloss_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColorR"), true); + MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColorR"),_texture_copy, _texture_out_dir, true); } - MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescence"), true); + MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescence"),_texture_copy, _texture_out_dir, true); if (_glow_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true); + MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"),_texture_copy, _texture_out_dir, true); } - MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"), true); + MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"),_texture_copy, _texture_out_dir, true); if (_height_maps.size() == 0) { - MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"), true); + MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"),_texture_copy, _texture_out_dir, true); } collect_maps(); @@ -454,7 +462,7 @@ find_textures_legacy(MObject shader) { if (maya_cat.is_spam()) { maya_cat.spam() - << " Reading surface shader " << shader_fn.name().asChar() << "\n"; + << " Reading legacy surface shader " << shader_fn.name().asChar() << "\n"; } // First, check for a connection to the color attribute. This could @@ -476,7 +484,7 @@ find_textures_legacy(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->find_textures_legacy(this, color_pa[0].node()); + color_p->find_textures_legacy(this, color_pa[0].node(), _texture_copy, _texture_out_dir); } if (color_pa.length() < 1) { @@ -498,7 +506,7 @@ find_textures_legacy(MObject shader) { for (size_t i = 0; i < trans_pa.length(); i++) { maya_cat.spam() << "read a transparency texture" << endl; - _transparency.find_textures_legacy(this, trans_pa[0].node(), true); + _transparency.find_textures_legacy(this, trans_pa[0].node(), _texture_copy, _texture_out_dir, true); } } diff --git a/pandatool/src/maya/mayaShader.h b/pandatool/src/maya/mayaShader.h index c388e1ab03..6d53c84e11 100644 --- a/pandatool/src/maya/mayaShader.h +++ b/pandatool/src/maya/mayaShader.h @@ -34,7 +34,7 @@ class MObject; //////////////////////////////////////////////////////////////////// class MayaShader : public Namable { public: - MayaShader(MObject engine); + MayaShader(MObject engine, bool texture_copy, Filename tout_dir, bool legacy_shader); ~MayaShader(); void output(ostream &out) const; @@ -69,9 +69,10 @@ private: MayaShaderColorDef *map2, bool perfect); string get_file_prefix(const string &fn); - + bool _texture_copy; + Filename _texture_out_dir; + bool _legacy_shader; public: // relevant only to legacy mode. - MayaShaderColorList _color; MayaShaderColorDef _transparency; Colorf get_rgba(size_t idx=0) const; diff --git a/pandatool/src/maya/mayaShaderColorDef.cxx b/pandatool/src/maya/mayaShaderColorDef.cxx index a4978bc7f2..3ac3fcc871 100644 --- a/pandatool/src/maya/mayaShaderColorDef.cxx +++ b/pandatool/src/maya/mayaShaderColorDef.cxx @@ -1,5 +1,7 @@ // Filename: mayaShaderColorDef.cxx // Created by: drose (12Apr03) +// Modified 19Mar10 by ETC PandaSE team (see +// header comment for mayaToEgg.cxx for details) // //////////////////////////////////////////////////////////////////// // @@ -264,7 +266,7 @@ get_panda_uvset_name() { // properties. //////////////////////////////////////////////////////////////////// void MayaShaderColorDef:: -find_textures_legacy(MayaShader *shader, MObject color, bool trans) { +find_textures_legacy(MayaShader *shader, MObject color, bool _texture_copy, Filename _texture_out_dir, 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]; @@ -300,6 +302,23 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { _has_texture = false; set_string_attribute(color, "fileTextureName", ""); } + // create directory, copy texture, modify texture filename + if (_texture_copy) { + if (_texture_out_dir[_texture_out_dir.length()-1] != '/') + _texture_out_dir+="/"; + _texture_out_dir.make_dir(); + Filename texture_copy_filename=Filename(_texture_out_dir, _texture_filename.get_basename()); + if (_texture_filename.copy_to(texture_copy_filename)) { + _texture_filename=texture_copy_filename; + } + else { + maya_cat.warning() + <<"unable to copy texture files from "<<_texture_filename.get_dirname() + <<" to "<<_texture_out_dir<<"\n" + <<"make sure you have the access right to the assigned directory\n" + <<"the output egg file will adapt to the original texture files' path\n"; + } + } } get_vec2f_attribute(color, "coverage", _coverage); @@ -337,7 +356,7 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { image_plug.connectedTo(image_pa, true, false); for (size_t i = 0; i < image_pa.length(); i++) { - find_textures_legacy(shader, image_pa[0].node()); + find_textures_legacy(shader, image_pa[0].node(), _texture_copy, _texture_out_dir); } } @@ -444,7 +463,7 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { maya_cat.debug() << pl.name().asChar() << " next:connectedTo: " << pla_name << endl; } MayaShaderColorDef *color_p = new MayaShaderColorDef; - color_p->find_textures_legacy(shader, pla[j].node()); + color_p->find_textures_legacy(shader, pla[j].node(), _texture_copy, _texture_out_dir); color_p->_blend_type = bt; size_t loc = color_p->_texture_name.find('.',0); if (loc != string::npos) { @@ -458,7 +477,7 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { if (maya_cat.is_debug()) { maya_cat.debug() << pl.name().asChar() << " first:connectedTo: " << pla_name << endl; } - find_textures_legacy(shader, pla[j].node()); + find_textures_legacy(shader, pla[j].node(), _texture_copy, _texture_out_dir); _texture_name.assign(pla[j].name().asChar()); _blend_type = bt; size_t loc = _texture_name.find('.',0); @@ -500,7 +519,7 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { // to the provided MayaShaderColorList. //////////////////////////////////////////////////////////////////// void MayaShaderColorDef:: -find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug, bool is_alpha) { +find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug,bool _texture_copy, Filename _texture_out_dir, bool is_alpha) { MPlugArray outplugs; inplug.connectedTo(outplugs, true, false); @@ -539,6 +558,24 @@ find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug def->_color_object = new MObject(source); def->_texture_filename = Filename::from_os_specific(filename); + // create directory, copy texture, modify texture filename + if (_texture_copy) { + if (_texture_out_dir[_texture_out_dir.length()-1] != '/') { + _texture_out_dir+="/"; + } + _texture_out_dir.make_dir(); + Filename texture_copy_filename=Filename(_texture_out_dir, def->_texture_filename.get_basename()); + if (def->_texture_filename.copy_to(texture_copy_filename)) { + def->_texture_filename=texture_copy_filename; + } + else { + maya_cat.warning() + <<"unable to copy texture files from "<_texture_filename.get_dirname() + <<" to "<<_texture_out_dir<<"\n" + <<"make sure you have the access right to the assigned directory\n" + <<"the output egg file will adapt to the original texture files' path\n"; + } + } def->_texture_name = sourceFn.name().asChar(); get_vec2f_attribute(source, "coverage", def->_coverage); @@ -583,7 +620,7 @@ find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug 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], is_alpha); + find_textures_modern(shadername, list, image_pa[0], _texture_copy, _texture_out_dir, is_alpha); } } @@ -635,7 +672,7 @@ find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug return; } size_t before = list.size(); - find_textures_modern(shadername, list, color, is_alpha); + find_textures_modern(shadername, list, color, _texture_copy, _texture_out_dir, is_alpha); int blendValue; blend.getValue(blendValue); for (size_t sub=before; subbind_uvsets(_file_to_uvset); // Record this for the future. diff --git a/pandatool/src/maya/mayaShaders.h b/pandatool/src/maya/mayaShaders.h index 86ceb6eee4..c1353dac22 100644 --- a/pandatool/src/maya/mayaShaders.h +++ b/pandatool/src/maya/mayaShaders.h @@ -33,8 +33,8 @@ class MayaShaders { public: MayaShaders(); ~MayaShaders(); - MayaShader *find_shader_for_node(MObject node); - MayaShader *find_shader_for_shading_engine(MObject engine); + MayaShader *find_shader_for_node(MObject node, bool _texture_copy, Filename _tout_dir, bool _legacy_shader); + MayaShader *find_shader_for_shading_engine(MObject engine, bool _texture_copy, Filename _tout_dir, bool _legacy_shader); int get_num_shaders() const; MayaShader *get_shader(int n) const; diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index 9ac80f8cbe..99ad933611 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -1,5 +1,8 @@ // Filename: mayaToEggConverter.cxx // Created by: drose (10Nov99) +// Modified 19Mar10 by ETC PandaSE team +// Added set_vertex_color_modern to fix Phong shader bug; also see +// header comment for mayaToEgg.cxx for more details // //////////////////////////////////////////////////////////////////// // @@ -97,6 +100,9 @@ MayaToEggConverter(const string &program_name) : _always_show_vertex_color = maya_default_vertex_color; _keep_all_uvsets = false; _round_uvs = false; + _texture_copy = false; + _legacy_shader = false; + _transform_type = TT_model; } @@ -122,6 +128,8 @@ MayaToEggConverter(const MayaToEggConverter ©) : _always_show_vertex_color(copy._always_show_vertex_color), _keep_all_uvsets(copy._keep_all_uvsets), _round_uvs(copy._round_uvs), + _texture_copy(copy._texture_copy), + _legacy_shader(copy._legacy_shader), _transform_type(copy._transform_type) { } @@ -594,6 +602,7 @@ convert_maya() { //////////////////////////////////////////////////////////////////// bool MayaToEggConverter:: open_api(bool revert_directory) { + if (_maya == (MayaApi *)NULL || !_maya->is_valid()) { //maya to egg converter only needs a read license. //only egg2maya need write lisences. @@ -823,7 +832,13 @@ convert_hierarchy(EggGroupNode *egg_root) { if (_keep_all_uvsets) { mayaegg_cat.info() << "will keep_all_uvsets" << endl; } - + // give some feedback about whether special options are on + if (_texture_copy) { + mayaegg_cat.info() << "will copy textures to" <<_texture_out_dir<< endl; + } + if (_legacy_shader) { + mayaegg_cat.info() << "will disable modern Phong shader path. using legacy" << endl; + } _tree.clear_egg(get_egg_data(), egg_root, NULL, NULL); for (int i = 0; i < num_nodes; i++) { MayaNodeDesc *node = _tree.get_node(i); @@ -930,6 +945,7 @@ process_model_node(MayaNodeDesc *node_desc) { << "\n"; } /* + MFnLight light (dag_path, &status); if ( !status ) { status.perror("MFnLight constructor"); @@ -1263,8 +1279,7 @@ make_nurbs_surface(MayaNodeDesc *node_desc, const MDagPath &dag_path, << surface.numSpansInV() << "\n"; } - - MayaShader *shader = _shaders.find_shader_for_node(surface.object()); + MayaShader *shader = _shaders.find_shader_for_node(surface.object(), _texture_copy, _texture_out_dir, _legacy_shader); if (_polygon_output) { // If we want polygon output only, tesselate the NURBS and output @@ -1713,8 +1728,7 @@ make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve, egg_curve->add_vertex(vpool->create_unique_vertex(vert)); } } - - MayaShader *shader = _shaders.find_shader_for_node(curve.object()); + MayaShader *shader = _shaders.find_shader_for_node(curve.object(), _texture_copy, _texture_out_dir, _legacy_shader); if (shader != (MayaShader *)NULL) { set_shader_attributes(*egg_curve, *shader); } @@ -1837,14 +1851,16 @@ make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path, } _shaders.bind_uvsets(mesh.object()); - + while (!pi.isDone()) { EggPolygon *egg_poly = new EggPolygon; egg_group->add_child(egg_poly); egg_poly->set_bface_flag(double_sided); - // Determine the shader for this particular polygon. + // Determine the MayaShader for this particular polygon. + // There appears to be two diverging paths for any Maya node with a Material (MayaShader) on it + // This next bit kicks us out into mayaShader et al. to pull textures and everything else. MayaShader *shader = NULL; int index = pi.index(); nassertv(index >= 0 && index < (int)poly_shader_indices.length()); @@ -1854,9 +1870,9 @@ make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path, nassertv(shader_index >= 0 && shader_index < (int)shaders.length()); MObject engine = shaders[shader_index]; shader = - _shaders.find_shader_for_shading_engine(engine); - - } else if (default_shader != (MayaShader *)NULL) { + _shaders.find_shader_for_shading_engine(engine, _texture_copy, _texture_out_dir, _legacy_shader); //head out to the other classes + //does this mean if we didn't find a Maya shader give it a default value anyway? + } else if (default_shader != (MayaShader *)NULL) { shader = default_shader; } @@ -2017,28 +2033,7 @@ make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path, if (mayaegg_cat.is_spam()) { mayaegg_cat.spam() << "poly_color = " << poly_color << endl; } - if (pi.hasColor()) { - MColor c; - status = pi.getColor(c, i); - if (!status) { - status.perror("MItMeshPolygon::getColor"); - } else { - // I saw instances where the color components exceeded 1.0 - // so lets clamp the values to 0 to 1 - c /= 1.0; - // The vertex color is a color scale that modifies the - // polygon color, not an override that replaces it. - vert.set_color(Colorf(c.r * poly_color[0], c.g * poly_color[1], - c.b * poly_color[2], c.a * poly_color[3])); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "maya_color = " << c.r << " " << c.g << " " << c.b << " " << c.a << endl; - mayaegg_cat.spam() << "vert_color = " << vert.get_color() << endl; - } - } - } else { - vert.set_color(poly_color); - } + set_vertex_color(vert,pi,i,shader,poly_color); } vert.set_external_index(pi.vertexIndex(i, &status)); @@ -2614,9 +2609,9 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, if (color_def->_has_texture) { // If we have a texture on color, apply it as the filename. - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() << "ssa:got texture name" << color_def->_texture_filename << endl; - } + //if (mayaegg_cat.is_debug()) { + //mayaegg_cat.debug() << "ssa:got texture name" << color_def->_texture_filename << endl; + //} Filename filename = Filename::from_os_specific(color_def->_texture_filename); Filename fullpath, outpath; _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath); @@ -2667,7 +2662,7 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, fullpath, outpath); tex.set_alpha_filename(outpath); tex.set_alpha_fullpath(fullpath); - } + } } else { // If there is no transparency texture specified, we don't // have any transparency, so tell the egg format to ignore any @@ -3100,3 +3095,83 @@ string_transform_type(const string &arg) { return TT_invalid; } } +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::MayaToEggConverter::set_vertex_color +// Access: Private +// Description: Checks to see if we're using legacy or modern +// shaders and based on the result, it passes +// the vertex color calculations off to either +// the legacy or modern vertex color functions. +//////////////////////////////////////////////////////////////////// +void MayaToEggConverter:: +set_vertex_color(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color) { + if (shader->_legacy_mode) { + set_vertex_color_legacy(vert, pi, vert_index, shader, color); + } else { + set_vertex_color_modern(vert, pi, vert_index, shader, color); + } +} +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::MayaToEggConverter::set_vertex_color_legacy +// Access: Private +// Description: Calls set_color on an EggVertex, determining the +// correct color values, based on the shader, vert_color +// Maya's vertex & flat color(s). This is the original +// implementation that works only on Lambert shaders/materials +// in Maya. +//////////////////////////////////////////////////////////////////// +void MayaToEggConverter:: +set_vertex_color_legacy(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color){ + if (pi.hasColor()) { + MColor c; + MStatus status = pi.getColor(c, vert_index); + if (!status) { + status.perror("MItMeshPolygon::getColor"); + } else { + // I saw instances where the color components exceeded 1.0 + // so lets clamp the values to 0 to 1 + c /= 1.0; + // The vertex color is a color scale that modifies the + // polygon color, not an override that replaces it. + vert.set_color(Colorf(c.r * color[0], c.g * color[1], c.b * color[2], c.a * color[3])); + + if (mayaegg_cat.is_spam()) { + mayaegg_cat.spam() << "maya_color = " << c.r << " " << c.g << " " << c.b << " " << c.a << endl; + mayaegg_cat.spam() << "vert_color = " << vert.get_color() << endl; + } + } + } else { + vert.set_color(color); + } + +} +//////////////////////////////////////////////////////////////////// +// Function: MayaShader::MayaToEggConverter::set_vertex_color_modern +// Access: Private +// Description: Calls set_color on an EggVertex, determining the +// correct color values, based on the shader, vert_color +// Maya's vertex & flat color(s). This implementation +// is designed to work specifically with Phong materials +// or shaders. +//////////////////////////////////////////////////////////////////// +void MayaToEggConverter:: +set_vertex_color_modern(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color) { + // If there's an explicit vertex color, output it. + if (pi.hasColor(vert_index)) { + MColor c; + MStatus status = pi.getColor(c, vert_index); + if (status) { + vert.set_color(Colorf(c.r, c.g, c.b, c.a)); + return; + } + } + + // If there's no explicit color, use flat color, or white on a textured model. + if (shader->_color_maps.empty()) { + const Colord &c = shader->_flat_color; + vert.set_color(Colorf((float)c[0], (float)c[1], (float)c[2], (float)c[3])); + } else { + //there's no explicit color anywhere, must be textured (or blank) + vert.set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + } +} diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index d8048f2955..143dd6325c 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -160,6 +160,11 @@ private: bool mesh); void set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, bool mesh); + void set_vertex_color(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color); + + void set_vertex_color_legacy(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color); + + void set_vertex_color_modern(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const Colorf &color); int round(double value); @@ -175,7 +180,7 @@ private: Globs _force_joints; MayaNodeTree _tree; - + public: MayaShaders _shaders; EggTextureCollection _textures; @@ -187,6 +192,10 @@ public: bool _always_show_vertex_color; bool _keep_all_uvsets; bool _round_uvs; + bool _texture_copy; + Filename _texture_out_dir; + bool _legacy_shader; + enum TransformType { TT_invalid, diff --git a/pandatool/src/mayaprogs/mayaCopy.cxx b/pandatool/src/mayaprogs/mayaCopy.cxx index 88aecc9996..fffaffe88b 100644 --- a/pandatool/src/mayaprogs/mayaCopy.cxx +++ b/pandatool/src/mayaprogs/mayaCopy.cxx @@ -1,5 +1,7 @@ // Filename: mayaCopy.cxx // Created by: drose (10May02) +// Modified 19Mar10 by ETC PandaSE team (see +// header comment for mayaToEgg.cxx for more details) // //////////////////////////////////////////////////////////////////// // @@ -432,7 +434,8 @@ collect_shader_for_node(const MDagPath &dag_path) { if (dag_path.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface surface(dag_path, &status); if (status) { - _shaders.find_shader_for_node(surface.object()); + Filename dummy; + _shaders.find_shader_for_node(surface.object(),false,dummy,false); } } else if (dag_path.hasFn(MFn::kMesh)) { @@ -450,7 +453,8 @@ collect_shader_for_node(const MDagPath &dag_path) { shader_index < num_shaders; shader_index++) { MObject engine = shaders[shader_index]; - _shaders.find_shader_for_shading_engine(engine); + Filename dummy; + _shaders.find_shader_for_shading_engine(engine,false,dummy,false); } } } diff --git a/pandatool/src/mayaprogs/mayaToEgg.cxx b/pandatool/src/mayaprogs/mayaToEgg.cxx index 6c01496736..30c2c9a56d 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.cxx +++ b/pandatool/src/mayaprogs/mayaToEgg.cxx @@ -1,6 +1,33 @@ // Filename: mayaToEgg.cxx // Created by: drose (15Feb00) // +// Additional Maintenance by the PandaSE team +// Carnegie Mellon Entertainment Technology Center +// Spring '10 +// Team Members: +// Deepak Chandraskeran - producer / programmer +// Andrew Gartner - programmer/technical artist +// Federico Perazzi - programmer +// Shuying Feng - programmer +// Wei-Feng Huang - programmer +// (Egger additions by Andrew Gartner and Wei-Feng Huang) +// The egger can now support vertex color in a variety +// of combinations with flat color and file color textures +// (see set_vertex_color). Also, there are two new +// command line options "legacy-shaders" and "texture-copy". +// The first treats any Maya material/shader as if it were +// a legacy shader. Passing it through the legacy codepath. +// This feature was originally intended to fix a bug where +// flat-color was being ignored in the modern (Phong) codepath +// However, with the new vertex and flat color functions it +// may not be necessary. Still, until the newer color functions +// have been tried and tested more, the feature has been left in +// to anticipate any problems that may arise. The texture copy +// feature was added to provide a way to resolve build path issues +// and can support both relative and absolute paths. The feature +// will copy any file maps/textures to the specified directory +// and update the egg file accordingly. +// //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE @@ -87,6 +114,12 @@ MayaToEgg() : "0.0; 0.444 becomes 0.44; 0.778 becomes 0.78.", &MayaToEgg::dispatch_none, &_round_uvs); + add_option + ("copytex","dir",0, + "copy the textures to a ""Textures"" sub directory relative to the written out egg file." + """dir"" is a sub directory in the same format as those used by -pr, etc." , + &MayaToEgg::dispatch_filename, &_texture_copy, &_texture_out_dir); + add_option ("trans", "type", 0, "Specifies which transforms in the Maya file should be converted to " @@ -145,6 +178,12 @@ MayaToEgg() : "Increase verbosity. More v's means more verbose.", &MayaToEgg::dispatch_count, NULL, &_verbose); + add_option + ("legacy-shaders", "", 0, + "Use this flag to turn off modern (Phong) shader generation" + "and treat all shaders as if they were Lamberts (legacy).", + &MayaToEgg::dispatch_none, &_legacy_shader); + // Unfortunately, the Maya API doesn't allow us to differentiate // between relative and absolute pathnames--everything comes out as // an absolute pathname, even if it is stored in the Maya file as a @@ -181,6 +220,11 @@ run() { // directory. if (_got_output_filename) { _output_filename.make_absolute(); + //conjunct the relative output path with output file's dir weifengh + if (_texture_out_dir.is_local()) { + Filename tempdir = _output_filename.get_dirname() + "/"; + _texture_out_dir = tempdir + _texture_out_dir; + } } nout << "Initializing Maya.\n"; @@ -200,6 +244,9 @@ run() { converter._keep_all_uvsets = _keep_all_uvsets; converter._round_uvs = _round_uvs; converter._transform_type = _transform_type; + converter._texture_copy = _texture_copy; + converter._texture_out_dir = _texture_out_dir; + converter._legacy_shader = _legacy_shader; vector_string::const_iterator si; if (!_subroots.empty()) { diff --git a/pandatool/src/mayaprogs/mayaToEgg.h b/pandatool/src/mayaprogs/mayaToEgg.h index 7cf4db6f2c..3e41671398 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.h +++ b/pandatool/src/mayaprogs/mayaToEgg.h @@ -39,6 +39,10 @@ protected: bool _suppress_vertex_color; bool _keep_all_uvsets; bool _round_uvs; + bool _texture_copy; + Filename _texture_out_dir; + bool _legacy_shader; + MayaToEggConverter::TransformType _transform_type; vector_string _subroots; vector_string _subsets;