00001 // Filename: mayaShaders.cxx 00002 // Created by: drose (11Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "mayaShaders.h" 00020 #include "mayaShader.h" 00021 #include "maya_funcs.h" 00022 #include "config_maya.h" 00023 00024 #include "pre_maya_include.h" 00025 #include <maya/MStatus.h> 00026 #include <maya/MObject.h> 00027 #include <maya/MFnDependencyNode.h> 00028 #include <maya/MPlug.h> 00029 #include <maya/MPlugArray.h> 00030 #include <maya/MFn.h> 00031 #include "post_maya_include.h" 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: MayaShaders::Constructor 00035 // Access: Public 00036 // Description: 00037 //////////////////////////////////////////////////////////////////// 00038 MayaShaders:: 00039 MayaShaders() { 00040 } 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: MayaShaders::Destructor 00044 // Access: Public 00045 // Description: 00046 //////////////////////////////////////////////////////////////////// 00047 MayaShaders:: 00048 ~MayaShaders() { 00049 clear(); 00050 } 00051 00052 //////////////////////////////////////////////////////////////////// 00053 // Function: MayaShaders::find_shader_for_node 00054 // Access: Public 00055 // Description: Extracts the shader assigned to the indicated node. 00056 //////////////////////////////////////////////////////////////////// 00057 MayaShader *MayaShaders:: 00058 find_shader_for_node(MObject node) { 00059 MStatus status; 00060 MFnDependencyNode node_fn(node); 00061 00062 // Look on the instObjGroups attribute for shading engines. 00063 MObject iog_attr = node_fn.attribute("instObjGroups", &status); 00064 if (!status) { 00065 // The node is not renderable. What are you thinking? 00066 maya_cat.error() 00067 << node_fn.name() << " : not a renderable object.\n"; 00068 return (MayaShader *)NULL; 00069 } 00070 00071 // instObjGroups is a multi attribute, whatever that means. For 00072 // now, we'll just get the first connection, since that's what the 00073 // example code did. Is there any reason to search deeper? 00074 00075 MPlug iog_plug(node, iog_attr); 00076 MPlugArray iog_pa; 00077 iog_plug.elementByLogicalIndex(0).connectedTo(iog_pa, false, true, &status); 00078 if (!status) { 00079 // No shading group defined for this object. 00080 maya_cat.error() 00081 << node_fn.name() << " : no shading group defined.\n"; 00082 return (MayaShader *)NULL; 00083 } 00084 00085 // Now we have a number of ShadingEngines defined, one for each of 00086 // these connections we just turned up. Usually there will only be 00087 // one. In fact, we'll just take the first one we find. 00088 00089 size_t i; 00090 for (i = 0; i < iog_pa.length(); i++) { 00091 MObject engine = iog_pa[i].node(); 00092 if (engine.hasFn(MFn::kShadingEngine)) { 00093 return find_shader_for_shading_engine(engine); 00094 } 00095 } 00096 00097 // Well, we didn't find a ShadingEngine after all. Huh. 00098 maya_cat.debug() 00099 << node_fn.name() << " : no shading engine found.\n"; 00100 return (MayaShader *)NULL; 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: MayaShaders::find_shader_for_shading_engine 00105 // Access: Public 00106 // Description: Returns the MayaShader object associated with the 00107 // indicated "shading engine". This will create a new 00108 // MayaShader object if this is the first time we have 00109 // encountered the indicated engine. 00110 //////////////////////////////////////////////////////////////////// 00111 MayaShader *MayaShaders:: 00112 find_shader_for_shading_engine(MObject engine) { 00113 MFnDependencyNode engine_fn(engine); 00114 00115 // See if we have already decoded this engine. 00116 string engine_name = engine_fn.name().asChar(); 00117 Shaders::const_iterator si = _shaders.find(engine_name); 00118 if (si != _shaders.end()) { 00119 return (*si).second; 00120 } 00121 00122 // All right, this is a newly encountered shading engine. Create a 00123 // new MayaShader object to represent it. 00124 MayaShader *shader = new MayaShader(engine); 00125 00126 // Record this for the future. 00127 _shaders.insert(Shaders::value_type(engine_name, shader)); 00128 _shaders_in_order.push_back(shader); 00129 return shader; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: MayaShaders::get_num_shaders 00134 // Access: Public 00135 // Description: Returns the number of unique MayaShaders that have 00136 // been discovered so far. 00137 //////////////////////////////////////////////////////////////////// 00138 int MayaShaders:: 00139 get_num_shaders() const { 00140 return _shaders_in_order.size(); 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: MayaShaders::get_shader 00145 // Access: Public 00146 // Description: Returns the nth MayaShader that has been discovered 00147 // so far. 00148 //////////////////////////////////////////////////////////////////// 00149 MayaShader *MayaShaders:: 00150 get_shader(int n) const { 00151 nassertr(n >= 0 && n < (int)_shaders_in_order.size(), NULL); 00152 return _shaders_in_order[n]; 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: MayaShaders::clear 00157 // Access: Public 00158 // Description: Frees all of the previously-defined MayaShader 00159 // objects associated with this set. 00160 //////////////////////////////////////////////////////////////////// 00161 void MayaShaders:: 00162 clear() { 00163 ShadersInOrder::iterator si; 00164 for (si = _shaders_in_order.begin(); si != _shaders_in_order.end(); ++si) { 00165 delete (*si); 00166 } 00167 00168 _shaders.clear(); 00169 _shaders_in_order.clear(); 00170 }