00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mayaShaderColorDef.h"
00020 #include "maya_funcs.h"
00021 #include "config_maya.h"
00022 #include "string_utils.h"
00023 #include "pset.h"
00024
00025 #include "pre_maya_include.h"
00026 #include <maya/MFnDependencyNode.h>
00027 #include <maya/MPlug.h>
00028 #include <maya/MPlugArray.h>
00029 #include <maya/MObject.h>
00030 #include <maya/MStatus.h>
00031 #include "post_maya_include.h"
00032
00033
00034
00035
00036
00037
00038 MayaShaderColorDef::
00039 MayaShaderColorDef() {
00040 _color_gain.set(1.0f, 1.0f, 1.0f);
00041
00042 _has_flat_color = false;
00043 _flat_color.set(0.0, 0.0, 0.0, 0.0);
00044
00045 _has_texture = false;
00046 _projection_type = PT_off;
00047 _map_uvs = NULL;
00048
00049 _coverage.set(1.0, 1.0);
00050 _translate_frame.set(0.0, 0.0);
00051 _rotate_frame = 0.0;
00052
00053 _mirror = false;
00054 _stagger = false;
00055 _wrap_u = true;
00056 _wrap_v = true;
00057
00058 _repeat_uv.set(1.0, 1.0);
00059 _offset.set(0.0, 0.0);
00060 _rotate_uv = 0.0;
00061
00062 _color_object = (MObject *)NULL;
00063 }
00064
00065
00066
00067
00068
00069
00070 MayaShaderColorDef::
00071 ~MayaShaderColorDef() {
00072 if (_color_object != (MObject *)NULL) {
00073 delete _color_object;
00074 }
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 LMatrix3d MayaShaderColorDef::
00084 compute_texture_matrix() const {
00085 LVector2d scale(_repeat_uv[0] / _coverage[0],
00086 _repeat_uv[1] / _coverage[1]);
00087 LVector2d trans(_offset[0] - _translate_frame[0] / _coverage[0],
00088 _offset[1] - _translate_frame[1] / _coverage[1]);
00089
00090 return
00091 (LMatrix3d::translate_mat(LVector2d(-0.5, -0.5)) *
00092 LMatrix3d::rotate_mat(_rotate_frame) *
00093 LMatrix3d::translate_mat(LVector2d(0.5, 0.5))) *
00094 LMatrix3d::scale_mat(scale) *
00095 LMatrix3d::translate_mat(trans);
00096 }
00097
00098
00099
00100
00101
00102
00103 bool MayaShaderColorDef::
00104 has_projection() const {
00105 return (_projection_type != PT_off);
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 TexCoordd MayaShaderColorDef::
00119 project_uv(const LPoint3d &pos, const LPoint3d ¢roid) const {
00120 nassertr(_map_uvs != NULL, TexCoordd::zero());
00121 return (this->*_map_uvs)(pos * _projection_matrix, centroid * _projection_matrix);
00122 }
00123
00124
00125
00126
00127
00128
00129 void MayaShaderColorDef::
00130 write(ostream &out) const {
00131 if (_has_texture) {
00132 out << " texture is " << _texture << "\n"
00133 << " coverage is " << _coverage << "\n"
00134 << " translate_frame is " << _translate_frame << "\n"
00135 << " rotate_frame is " << _rotate_frame << "\n"
00136 << " mirror is " << _mirror << "\n"
00137 << " stagger is " << _stagger << "\n"
00138 << " wrap_u is " << _wrap_u << "\n"
00139 << " wrap_v is " << _wrap_v << "\n"
00140 << " repeat_uv is " << _repeat_uv << "\n"
00141 << " offset is " << _offset << "\n"
00142 << " rotate_uv is " << _rotate_uv << "\n"
00143 << " color_gain is " << _color_gain << "\n";
00144
00145 } else if (_has_flat_color) {
00146 out << " flat color is " << _flat_color << "\n";
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 bool MayaShaderColorDef::
00157 reset_maya_texture(const Filename &texture) {
00158 if (_color_object != (MObject *)NULL) {
00159 _has_texture = set_string_attribute(*_color_object, "fileTextureName",
00160 texture);
00161 _texture = texture;
00162
00163 if (!_has_texture) {
00164 maya_cat.error()
00165 << "Unable to reset texture filename.\n";
00166 }
00167
00168 return _has_texture;
00169 }
00170
00171 maya_cat.error()
00172 << "Attempt to reset texture on Maya object that has no color set.\n";
00173 return false;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 void MayaShaderColorDef::
00184 read_surface_color(MObject color) {
00185 RGBColorf color_gain;
00186 if (get_vec3f_attribute(color, "colorGain", color_gain)) {
00187 _color_gain[0] *= color_gain[0];
00188 _color_gain[1] *= color_gain[1];
00189 _color_gain[2] *= color_gain[2];
00190 }
00191
00192 if (color.hasFn(MFn::kFileTexture)) {
00193 _color_object = new MObject(color);
00194 string filename;
00195 _has_texture = get_string_attribute(color, "fileTextureName", filename);
00196 if (_has_texture) {
00197 _texture = Filename::from_os_specific(filename);
00198 }
00199
00200 get_vec2f_attribute(color, "coverage", _coverage);
00201 get_vec2f_attribute(color, "translateFrame", _translate_frame);
00202 get_angle_attribute(color, "rotateFrame", _rotate_frame);
00203
00204 get_bool_attribute(color, "mirror", _mirror);
00205 get_bool_attribute(color, "stagger", _stagger);
00206 get_bool_attribute(color, "wrapU", _wrap_u);
00207 get_bool_attribute(color, "wrapV", _wrap_v);
00208
00209 get_vec2f_attribute(color, "repeatUV", _repeat_uv);
00210 get_vec2f_attribute(color, "offset", _offset);
00211 get_angle_attribute(color, "rotateUV", _rotate_uv);
00212
00213 } else if (color.hasFn(MFn::kProjection)) {
00214
00215
00216 MFnDependencyNode projection_fn(color);
00217 MPlug image_plug = projection_fn.findPlug("image");
00218 if (!image_plug.isNull()) {
00219 MPlugArray image_pa;
00220 image_plug.connectedTo(image_pa, true, false);
00221
00222 for (size_t i = 0; i < image_pa.length(); i++) {
00223 read_surface_color(image_pa[0].node());
00224 }
00225 }
00226
00227 if (!get_mat4d_attribute(color, "placementMatrix", _projection_matrix)) {
00228 _projection_matrix = LMatrix4d::ident_mat();
00229 }
00230
00231
00232
00233 if (!get_angle_attribute(color, "uAngle", _u_angle)) {
00234 _u_angle = 360.0;
00235 }
00236 if (!get_angle_attribute(color, "vAngle", _v_angle)) {
00237 _v_angle = 180.0;
00238 }
00239
00240 string type;
00241 if (get_enum_attribute(color, "projType", type)) {
00242 set_projection_type(type);
00243 }
00244
00245 } else {
00246
00247 if (maya_cat.is_debug()) {
00248 maya_cat.info()
00249 << "**Don't know how to interpret color attribute type "
00250 << color.apiTypeStr() << "\n";
00251
00252 } else {
00253
00254
00255 static pset<MFn::Type> bad_types;
00256 if (bad_types.insert(color.apiType()).second) {
00257 maya_cat.info()
00258 << "**Don't know how to interpret color attribute type "
00259 << color.apiTypeStr() << "\n";
00260 }
00261 }
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 void MayaShaderColorDef::
00272 set_projection_type(const string &type) {
00273 if (cmp_nocase(type, "planar") == 0) {
00274 _projection_type = PT_planar;
00275 _map_uvs = &MayaShaderColorDef::map_planar;
00276
00277
00278
00279 _projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
00280 0.0, 0.5, 0.0, 0.0,
00281 0.0, 0.0, 1.0, 0.0,
00282 0.5, 0.5, 0.0, 1.0);
00283
00284 } else if (cmp_nocase(type, "cylindrical") == 0) {
00285 _projection_type = PT_cylindrical;
00286 _map_uvs = &MayaShaderColorDef::map_cylindrical;
00287
00288
00289
00290 _projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
00291 0.0, 0.5, 0.0, 0.0,
00292 0.0, 0.0, 1.0, 0.0,
00293 0.0, 0.5, 0.0, 1.0);
00294
00295 } else if (cmp_nocase(type, "spherical") == 0) {
00296 _projection_type = PT_spherical;
00297 _map_uvs = &MayaShaderColorDef::map_spherical;
00298
00299 } else {
00300
00301
00302 maya_cat.error()
00303 << "Don't know how to handle type " << type << " projections.\n";
00304 _projection_type = PT_off;
00305 _map_uvs = NULL;
00306 }
00307 }
00308
00309
00310
00311
00312
00313
00314
00315 LPoint2d MayaShaderColorDef::
00316 map_planar(const LPoint3d &pos, const LPoint3d &) const {
00317
00318
00319 return LPoint2d(pos[0], pos[1]);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328 LPoint2d MayaShaderColorDef::
00329 map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const {
00330
00331
00332
00333
00334 LVector2d xz(pos[0], pos[2]);
00335 double xz_length = xz.length();
00336
00337 if (xz_length < 0.01) {
00338
00339
00340
00341
00342
00343
00344
00345 xz.set(centroid[0], centroid[2]);
00346 }
00347
00348
00349
00350
00351 double u = rad_2_deg(atan2(xz[0], xz[1])) / (2.0 * _u_angle);
00352 double c = rad_2_deg(atan2(centroid[0], centroid[2])) / (2.0 * _u_angle);
00353
00354 if (u - c > 0.5) {
00355 u -= floor(u - c + 0.5);
00356 } else if (u - c < -0.5) {
00357 u += floor(c - u + 0.5);
00358 }
00359
00360
00361
00362 LVector2d yz(pos[1], xz_length);
00363 double v = rad_2_deg(atan2(yz[0], yz[1])) / (2.0 * _v_angle);
00364
00365 LPoint2d uv(u - 0.5, v - 0.5);
00366
00367 nassertr(fabs(u - c) <= 0.5, uv);
00368 return uv;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377 LPoint2d MayaShaderColorDef::
00378 map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const {
00379
00380
00381
00382 LVector2d xz(pos[0], pos[2]);
00383 double xz_length = xz.length();
00384
00385 if (xz_length < 0.01) {
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 xz.set(centroid[0], centroid[2]);
00397 }
00398
00399
00400 double u = rad_2_deg(atan2(xz[0], xz[1])) / _u_angle;
00401 double c = rad_2_deg(atan2(centroid[0], centroid[2])) / _u_angle;
00402
00403 if (u - c > 0.5) {
00404 u -= floor(u - c + 0.5);
00405 } else if (u - c < -0.5) {
00406 u += floor(c - u + 0.5);
00407 }
00408
00409
00410
00411 LPoint2d uv(u - 0.5, pos[1]);
00412
00413 nassertr(fabs(u - c) <= 0.5, uv);
00414 return uv;
00415 }