24 #include <maya/MFnDependencyNode.h>
25 #include <maya/MPlug.h>
26 #include <maya/MPlugArray.h>
27 #include <maya/MObject.h>
28 #include <maya/MStatus.h>
29 #include <maya/MFnEnumAttribute.h>
39 MayaShaderColorDef() {
41 _blend_type = BT_unspecified;
43 _projection_type = PT_off;
44 _projection_matrix = LMatrix4d::ident_mat();
48 _texture_filename =
"";
50 _color_gain.set(1.0f, 1.0f, 1.0f, 1.0f);
52 _coverage.set(1.0, 1.0);
53 _translate_frame.set(0.0, 0.0);
61 _repeat_uv.set(1.0, 1.0);
62 _offset.set(0.0, 0.0);
69 _color_object =
nullptr;
72 _has_flat_color =
false;
73 _flat_color.set(0.0, 0.0, 0.0, 0.0);
74 _has_alpha_channel =
false;
88 _has_texture = copy._has_texture;
89 _texture_filename = copy._texture_filename;
90 _texture_name = copy._texture_name;
91 _uvset_name = copy._uvset_name;
92 _color_gain = copy._color_gain;
94 _has_flat_color = copy._has_flat_color;
95 _flat_color = copy._flat_color;
97 _projection_type = copy._projection_type;
98 _projection_matrix = copy._projection_matrix;
99 _u_angle = copy._u_angle;
100 _v_angle = copy._v_angle;
102 _coverage = copy._coverage;
103 _translate_frame = copy._translate_frame;
104 _rotate_frame = copy._rotate_frame;
106 _mirror = copy._mirror;
107 _stagger = copy._stagger;
108 _wrap_u = copy._wrap_u;
109 _wrap_v = copy._wrap_v;
111 _blend_type = copy._blend_type;
112 _has_alpha_channel = copy._has_alpha_channel;
113 _keep_color = copy._keep_color;
114 _keep_alpha = copy._keep_alpha;
115 _interpolate = copy._interpolate;
117 _repeat_uv = copy._repeat_uv;
118 _offset = copy._offset;
119 _rotate_uv = copy._rotate_uv;
121 _is_alpha = copy._is_alpha;
123 _map_uvs = copy._map_uvs;
124 _color_object = copy._color_object;
133 ~MayaShaderColorDef() {
134 if (_color_object !=
nullptr) {
135 delete _color_object;
145 LVector2d scale(_repeat_uv[0] / _coverage[0],
146 _repeat_uv[1] / _coverage[1]);
147 LVector2d trans(_offset[0] - _translate_frame[0] / _coverage[0],
148 _offset[1] - _translate_frame[1] / _coverage[1]);
151 (LMatrix3d::translate_mat(LVector2d(-0.5, -0.5)) *
152 LMatrix3d::rotate_mat(_rotate_frame) *
153 LMatrix3d::translate_mat(LVector2d(0.5, 0.5))) *
154 LMatrix3d::scale_mat(scale) *
155 LMatrix3d::translate_mat(trans);
163 return (_projection_type != PT_off);
174 project_uv(
const LPoint3d &pos,
const LPoint3d ¢roid)
const {
175 nassertr(_map_uvs !=
nullptr, LTexCoordd::zero());
176 return (this->*_map_uvs)(pos * _projection_matrix, centroid * _projection_matrix);
182 void MayaShaderColorDef::
183 write(std::ostream &out)
const {
185 out <<
" texture filename is " << _texture_filename <<
"\n"
186 <<
" texture name is " << _texture_name <<
"\n"
187 <<
" uv_set name is " << _uvset_name <<
"\n"
188 <<
" coverage is " << _coverage <<
"\n"
189 <<
" translate_frame is " << _translate_frame <<
"\n"
190 <<
" rotate_frame is " << _rotate_frame <<
"\n"
191 <<
" mirror is " << _mirror <<
"\n"
192 <<
" stagger is " << _stagger <<
"\n"
193 <<
" wrap_u is " << _wrap_u <<
"\n"
194 <<
" wrap_v is " << _wrap_v <<
"\n"
195 <<
" repeat_uv is " << _repeat_uv <<
"\n"
196 <<
" offset is " << _offset <<
"\n"
197 <<
" rotate_uv is " << _rotate_uv <<
"\n"
198 <<
" color_gain is " << _color_gain <<
"\n";
200 }
else if (_has_flat_color) {
201 out <<
" flat color is " << _flat_color <<
"\n";
211 if (_color_object !=
nullptr) {
214 _texture_filename = texture;
218 <<
"Unable to reset texture filename.\n";
225 <<
"Attempt to reset texture on Maya object that has no color set.\n";
236 if (_uvset_name ==
"map1") {
247 void MayaShaderColorDef::
248 find_textures_legacy(
MayaShader *shader, MObject color,
bool trans) {
249 LRGBColor color_gain;
251 color_gain[0] = color_gain[0] > 1.0 ? 1.0 : color_gain[0];
252 color_gain[0] = color_gain[0] < 0.0 ? 0.0 : color_gain[0];
253 _color_gain[0] *= color_gain[0];
254 color_gain[1] = color_gain[1] > 1.0 ? 1.0 : color_gain[1];
255 color_gain[1] = color_gain[1] < 0.0 ? 0.0 : color_gain[1];
256 _color_gain[1] *= color_gain[1];
257 color_gain[2] = color_gain[2] > 1.0 ? 1.0 : color_gain[2];
258 color_gain[2] = color_gain[2] < 0.0 ? 0.0 : color_gain[2];
259 _color_gain[2] *= color_gain[2];
261 PN_stdfloat alpha_gain;
262 if (get_maya_attribute(color,
"alphaGain", alpha_gain)) {
263 alpha_gain = alpha_gain > 1.0 ? 1.0 : alpha_gain;
264 alpha_gain = alpha_gain < 0.0 ? 0.0 : alpha_gain;
265 _color_gain[3] *= alpha_gain;
267 if (color.hasFn(MFn::kFileTexture)) {
268 MFnDependencyNode dfn(color);
269 _color_object =
new MObject(color);
270 _texture_name = dfn.name().asChar();
273 _has_texture = _has_texture && !filename.empty();
278 <<
"Shader " << shader->get_name()
279 <<
" references texture filename " << filename
280 <<
" which is a directory; clearing.\n";
281 _has_texture =
false;
302 if (maya_cat.is_debug()) {
303 maya_cat.debug() <<
"pushed a file texture" << endl;
305 shader->_color.push_back(
this);
308 }
else if (color.hasFn(MFn::kProjection)) {
309 if (maya_cat.is_debug()) {
310 maya_cat.debug() <<
"reading a projection texture" << endl;
314 MFnDependencyNode projection_fn(color);
315 MPlug image_plug = projection_fn.findPlug(
"image");
316 if (!image_plug.isNull()) {
318 image_plug.connectedTo(image_pa,
true,
false);
320 for (
size_t i = 0; i < image_pa.length(); i++) {
321 find_textures_legacy(shader, image_pa[0].node());
326 _projection_matrix = LMatrix4d::ident_mat();
339 set_projection_type(type);
342 }
else if (color.hasFn(MFn::kLayeredTexture)) {
343 if (maya_cat.is_debug()) {
344 maya_cat.debug() <<
"Found layered texture" << endl;
350 MFnDependencyNode layered_fn(color);
351 layered_fn.getConnections(color_pa);
352 MPlug inputsPlug = layered_fn.findPlug(
"inputs", &status);
353 MPlug blendModePlug = layered_fn.findPlug(
"blendMode", &status);
355 if (maya_cat.is_debug()) {
356 maya_cat.debug() <<
"number of connections: " << color_pa.length() << endl;
359 BlendType bt = BT_modulate;
360 for (
size_t i=0; i<color_pa.length(); ++i) {
361 MPlug pl = color_pa[i];
363 pl.connectedTo(pla,
true,
false);
366 int li = pl.logicalIndex();
369 if (maya_cat.is_spam()) {
370 MString name = inputsPlug.name();
371 maya_cat.spam() <<
"*** Start doIt... ***" << endl;
372 maya_cat.spam() <<
"inputsPlug Name: " << name.asChar() << endl;
374 status = blendModePlug.selectAncestorLogicalIndex(li,inputsPlug);
375 blendModePlug.getValue(blendValue);
377 if (maya_cat.is_spam()) {
378 MString name = blendModePlug.name();
380 << name.asChar() <<
": has value " << blendValue << endl;
383 MFnEnumAttribute blendModeEnum(blendModePlug);
384 MString blendName = blendModeEnum.fieldName(blendValue, &status);
386 switch (blendValue) {
390 maya_cat.info() <<
"interpolate: " << _interpolate << endl;
396 maya_cat.info() <<
"keepAlpha: " << _keep_alpha << endl;
403 if (maya_cat.is_info()) {
404 MString name = layered_fn.name();
405 maya_cat.info() << name.asChar() <<
": blendMode used " << blendName.asChar() << endl;
406 if (maya_cat.is_spam()) {
407 maya_cat.spam() <<
"*** END doIt... ***" << endl;
413 pl.connectedTo(pla,
true,
false);
415 for (
size_t j=0; j<pla.length(); ++j) {
419 string pla_name = pla[j].name().asChar();
422 if (pla_name.find(
"outAlpha") != string::npos) {
425 if (maya_cat.is_debug()) {
426 maya_cat.debug() << pl.name().asChar() <<
":has alpha channel" << pla_name << endl;
428 _has_alpha_channel =
true;
432 if (maya_cat.is_debug()) {
433 maya_cat.debug() << pl.name().asChar() <<
" next:connectedTo: " << pla_name << endl;
436 color_p->find_textures_legacy(shader, pla[j].node());
437 color_p->_blend_type = bt;
438 size_t loc = color_p->_texture_name.find(
'.',0);
439 if (loc != string::npos) {
440 color_p->_texture_name.resize(loc);
442 if (maya_cat.is_debug()) {
443 maya_cat.debug() <<
"uv_name : " << color_p->_texture_name << endl;
447 if (maya_cat.is_debug()) {
448 maya_cat.debug() << pl.name().asChar() <<
" first:connectedTo: " << pla_name << endl;
450 find_textures_legacy(shader, pla[j].node());
451 _texture_name.assign(pla[j].name().asChar());
453 size_t loc = _texture_name.find(
'.',0);
454 if (loc != string::npos) {
455 _texture_name.resize(loc);
457 if (maya_cat.is_debug()) {
458 maya_cat.debug() <<
"uv_name : " << _texture_name << endl;
466 if (maya_cat.is_debug()) {
468 <<
"**Don't know how to interpret color attribute type "
469 << color.apiTypeStr() <<
"\n";
475 if (bad_types.insert(color.apiType()).second) {
477 <<
"**Don't know how to interpret color attribute type "
478 << color.apiTypeStr() <<
"\n";
488 void MayaShaderColorDef::
489 find_textures_modern(
const string &shadername,
MayaShaderColorList &list, MPlug inplug,
bool is_alpha) {
492 inplug.connectedTo(outplugs,
true,
false);
493 if (outplugs.length() == 0) {
496 if (outplugs.length() > 1) {
499 <<
"Shader " << shadername <<
" has weird plug connections.\n";
502 MPlug outplug = outplugs[0];
503 MObject source = outplug.node();
504 MFnDependencyNode sourceFn(source);
506 if (source.hasFn(MFn::kFileTexture)) {
510 if ((!hasfn) || (filename.empty())) {
512 <<
"Shader " << shadername <<
" references file texture "
513 <<
"with no file name, ignoring invalid file texture.\n";
519 <<
"Shader " << shadername <<
" references file name "
520 << filename <<
" which is a directory, ignoring it.\n";
526 def->_color_object =
new MObject(source);
528 def->_texture_name = sourceFn.name().asChar();
543 LRGBColor color_gain;
544 PN_stdfloat alpha_gain;
546 get_maya_attribute(source,
"alphaGain", alpha_gain);
547 def->_color_gain[0] = color_gain[0];
548 def->_color_gain[1] = color_gain[1];
549 def->_color_gain[2] = color_gain[2];
550 def->_color_gain[3] = alpha_gain;
552 def->_is_alpha = is_alpha;
554 if (maya_cat.is_debug()) {
555 maya_cat.debug() <<
"pushed a file texture" << endl;
562 if (source.hasFn(MFn::kProjection)) {
565 size_t before = list.size();
566 MPlug image_plug = sourceFn.findPlug(
"image");
567 if (!image_plug.isNull()) {
569 image_plug.connectedTo(image_pa,
true,
false);
571 for (
size_t i = 0; i < image_pa.length(); i++) {
572 find_textures_modern(shadername, list, image_pa[0], is_alpha);
578 for (
size_t i=before; i<list.size(); i++) {
582 def->_projection_matrix = LMatrix4d::ident_mat();
587 def->_u_angle = 360.0;
590 def->_v_angle = 180.0;
595 def->set_projection_type(type);
601 if (source.hasFn(MFn::kLayeredTexture)) {
602 if (maya_cat.is_debug()) {
603 maya_cat.debug() <<
"Found layered texture" << endl;
606 MPlug inputsPlug = sourceFn.findPlug(
"inputs");
607 size_t nlayers = inputsPlug.numElements();
608 for (
size_t layer=0; layer<nlayers; layer++) {
609 MPlug elt = inputsPlug.elementByPhysicalIndex(layer);
612 for (
size_t j=0; j<elt.numChildren(); j++) {
613 MPlug child = elt.child(j);
614 MFnAttribute att(child.attribute());
615 if (att.name() ==
"color") color = child;
616 if (att.name() ==
"blendMode") blend = child;
618 if (color.isNull() || blend.isNull()) {
619 maya_cat.warning() <<
"Invalid layered texture - bad inputs.\n";
622 size_t before = list.size();
623 find_textures_modern(shadername, list, color, is_alpha);
625 blend.getValue(blendValue);
626 for (
size_t sub=before; sub<list.size(); sub++) {
628 switch (blendValue) {
629 case 1: def->_blend_type = BT_decal;
break;
630 case 6: def->_blend_type = BT_modulate;
break;
631 case 4: def->_blend_type = BT_add;
break;
638 if (source.apiType() == MFn::kReverse) {
639 MPlug input_plug = sourceFn.findPlug(
"input");
640 find_textures_modern(shadername, list, input_plug, is_alpha);
645 if (maya_cat.is_debug()) {
647 <<
"**Don't know how to interpret color attribute type "
648 << source.apiTypeStr() <<
"\n";
653 if (bad_types.insert(source.apiType()).second) {
655 <<
"Don't know how to export a shader of type "
656 << source.apiTypeStr() <<
" " << sourceFn.type() <<
"\n";
665 void MayaShaderColorDef::
666 set_projection_type(
const string &type) {
667 if (cmp_nocase(type,
"planar") == 0) {
668 _projection_type = PT_planar;
669 _map_uvs = &MayaShaderColorDef::map_planar;
673 _projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
678 }
else if (cmp_nocase(type,
"cylindrical") == 0) {
679 _projection_type = PT_cylindrical;
680 _map_uvs = &MayaShaderColorDef::map_cylindrical;
684 _projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
689 }
else if (cmp_nocase(type,
"spherical") == 0) {
690 _projection_type = PT_spherical;
691 _map_uvs = &MayaShaderColorDef::map_spherical;
696 <<
"Don't know how to handle type " << type <<
" projections.\n";
697 _projection_type = PT_off;
705 LPoint2d MayaShaderColorDef::
706 map_planar(
const LPoint3d &pos,
const LPoint3d &)
const {
709 return LPoint2d(pos[0], pos[1]);
716 LPoint2d MayaShaderColorDef::
717 map_spherical(
const LPoint3d &pos,
const LPoint3d ¢roid)
const {
722 LVector2d xz(pos[0], pos[2]);
723 double xz_length = xz.length();
725 if (xz_length < 0.01) {
733 xz.set(centroid[0], centroid[2]);
739 double u = rad_2_deg(atan2(xz[0], xz[1])) / (2.0 * _u_angle);
740 double c = rad_2_deg(atan2(centroid[0], centroid[2])) / (2.0 * _u_angle);
743 u -= floor(u - c + 0.5);
744 }
else if (u - c < -0.5) {
745 u += floor(c - u + 0.5);
750 LVector2d yz(pos[1], xz_length);
751 double v = rad_2_deg(atan2(yz[0], yz[1])) / (2.0 * _v_angle);
753 LPoint2d uv(u - 0.5, v - 0.5);
755 nassertr(fabs(u - c) <= 0.5, uv);
763 LPoint2d MayaShaderColorDef::
764 map_cylindrical(
const LPoint3d &pos,
const LPoint3d ¢roid)
const {
768 LVector2d xz(pos[0], pos[2]);
769 double xz_length = xz.length();
771 if (xz_length < 0.01) {
783 xz.set(centroid[0], centroid[2]);
787 double u = rad_2_deg(atan2(xz[0], xz[1])) / _u_angle;
788 double c = rad_2_deg(atan2(centroid[0], centroid[2])) / _u_angle;
791 u -= floor(u - c + 0.5);
792 }
else if (u - c < -0.5) {
793 u += floor(c - u + 0.5);
797 LPoint2d uv(u - 0.5, pos[1]);
799 nassertr(fabs(u - c) <= 0.5, uv);
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 to_os_generic() const
This is similar to to_os_specific(), but it is designed to generate a filename that can be understood...
bool is_directory() const
Returns true if the filename exists and is a directory name, false otherwise.
This defines the various attributes that Maya may associate with the "color" channel for a particular...
bool reset_maya_texture(const Filename &texture)
Changes the texture filename stored in the Maya file for this particular shader.
LMatrix3d compute_texture_matrix() const
Returns a texture matrix corresponding to the texture transforms indicated by the shader.
bool has_projection() const
Returns true if the shader has a projection in effect.
std::string get_panda_uvset_name()
Maya's default uvset name is "map1".
LTexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const
If the shader has a projection (has_projection() returns true), this computes the appropriate UV corr...
Corresponds to a single "shader" in Maya.
This is our own Panda specialization on the default STL set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool get_string_attribute(MObject &node, const string &attribute_name, string &value)
Extracts the named string attribute from the MObject.
bool get_angle_attribute(MObject &node, const string &attribute_name, double &value)
Extracts the named angle in degrees from the MObject.
bool set_string_attribute(MObject &node, const string &attribute_name, const string &value)
Sets the named string attribute on the MObject.
bool get_vec3_attribute(MObject &node, const string &attribute_name, LVecBase3 &value)
Extracts the named three-component vector from the MObject.
bool get_enum_attribute(MObject &node, const string &attribute_name, string &value)
Extracts the enum attribute from the MObject as a string value.
bool get_mat4d_attribute(MObject &node, const string &attribute_name, LMatrix4d &value)
Extracts the named 4x4 matrix from the MObject.
bool get_vec2_attribute(MObject &node, const string &attribute_name, LVecBase2 &value)
Extracts the named two-component vector from the MObject.
bool get_bool_attribute(MObject &node, const string &attribute_name, bool &value)
Extracts the named boolean attribute from the MObject.
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.