mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
respect maya's convention of separate textures for color and transparency
This commit is contained in:
parent
0387fd286f
commit
064955a02b
@ -14,6 +14,7 @@
|
|||||||
config_maya.cxx config_maya.h \
|
config_maya.cxx config_maya.h \
|
||||||
mayaApi.cxx mayaApi.h \
|
mayaApi.cxx mayaApi.h \
|
||||||
mayaShader.cxx mayaShader.h \
|
mayaShader.cxx mayaShader.h \
|
||||||
|
mayaShaderColorDef.cxx mayaShaderColorDef.h \
|
||||||
mayaShaders.cxx mayaShaders.h \
|
mayaShaders.cxx mayaShaders.h \
|
||||||
maya_funcs.I maya_funcs.cxx maya_funcs.h \
|
maya_funcs.I maya_funcs.cxx maya_funcs.h \
|
||||||
post_maya_include.h pre_maya_include.h
|
post_maya_include.h pre_maya_include.h
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "maya_funcs.h"
|
#include "maya_funcs.h"
|
||||||
#include "config_maya.h"
|
#include "config_maya.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
#include "pnmImageHeader.h" // for lumin_red, etc.
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
|
||||||
#include "pre_maya_include.h"
|
#include "pre_maya_include.h"
|
||||||
@ -40,35 +41,13 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
MayaShader::
|
MayaShader::
|
||||||
MayaShader(MObject engine) {
|
MayaShader(MObject engine) {
|
||||||
_has_color = false;
|
|
||||||
_transparency = 0.0;
|
|
||||||
|
|
||||||
_has_texture = false;
|
|
||||||
_projection_type = PT_off;
|
|
||||||
_map_uvs = NULL;
|
|
||||||
|
|
||||||
_coverage.set(1.0, 1.0);
|
|
||||||
_translate_frame.set(0.0, 0.0);
|
|
||||||
_rotate_frame = 0.0;
|
|
||||||
|
|
||||||
_mirror = false;
|
|
||||||
_stagger = false;
|
|
||||||
_wrap_u = true;
|
|
||||||
_wrap_v = true;
|
|
||||||
|
|
||||||
_repeat_uv.set(1.0, 1.0);
|
|
||||||
_offset.set(0.0, 0.0);
|
|
||||||
_rotate_uv = 0.0;
|
|
||||||
|
|
||||||
_color_object = (MObject *)NULL;
|
|
||||||
|
|
||||||
MFnDependencyNode engine_fn(engine);
|
MFnDependencyNode engine_fn(engine);
|
||||||
|
|
||||||
_name = engine_fn.name().asChar();
|
set_name(engine_fn.name().asChar());
|
||||||
|
|
||||||
if (maya_cat.is_debug()) {
|
if (maya_cat.is_debug()) {
|
||||||
maya_cat.debug()
|
maya_cat.debug()
|
||||||
<< "Reading shading engine " << _name << "\n";
|
<< "Reading shading engine " << get_name() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found_shader = false;
|
bool found_shader = false;
|
||||||
@ -91,56 +70,6 @@ MayaShader(MObject engine) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
MayaShader::
|
MayaShader::
|
||||||
~MayaShader() {
|
~MayaShader() {
|
||||||
if (_color_object != (MObject *)NULL) {
|
|
||||||
delete _color_object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::compute_texture_matrix
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns a texture matrix corresponding to the texture
|
|
||||||
// transforms indicated by the shader.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
LMatrix3d MayaShader::
|
|
||||||
compute_texture_matrix() const {
|
|
||||||
LVector2d scale(_repeat_uv[0] / _coverage[0],
|
|
||||||
_repeat_uv[1] / _coverage[1]);
|
|
||||||
LVector2d trans(_offset[0] - _translate_frame[0] / _coverage[0],
|
|
||||||
_offset[1] - _translate_frame[1] / _coverage[1]);
|
|
||||||
|
|
||||||
return
|
|
||||||
(LMatrix3d::translate_mat(LVector2d(-0.5, -0.5)) *
|
|
||||||
LMatrix3d::rotate_mat(_rotate_frame) *
|
|
||||||
LMatrix3d::translate_mat(LVector2d(0.5, 0.5))) *
|
|
||||||
LMatrix3d::scale_mat(scale) *
|
|
||||||
LMatrix3d::translate_mat(trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::has_projection
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns true if the shader has a projection in effect.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool MayaShader::
|
|
||||||
has_projection() const {
|
|
||||||
return (_projection_type != PT_off);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::project_uv
|
|
||||||
// Access: Public
|
|
||||||
// Description: If the shader has a projection (has_projection()
|
|
||||||
// returns true), this computes the appropriate UV
|
|
||||||
// corresponding to the indicated 3-d point. Seams that
|
|
||||||
// might be introduced on polygons that cross quadrants
|
|
||||||
// are closed up by ensuring the point is in the same
|
|
||||||
// quadrant as the indicated reference point.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
TexCoordd MayaShader::
|
|
||||||
project_uv(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
|
||||||
nassertr(_map_uvs != NULL, TexCoordd::zero());
|
|
||||||
return (this->*_map_uvs)(pos * _projection_matrix, centroid * _projection_matrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -150,49 +79,58 @@ project_uv(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaShader::
|
void MayaShader::
|
||||||
output(ostream &out) const {
|
output(ostream &out) const {
|
||||||
out << "Shader " << _name << ":\n";
|
out << "Shader " << get_name();
|
||||||
if (_has_texture) {
|
|
||||||
out << " texture is " << _texture << "\n"
|
|
||||||
<< " coverage is " << _coverage << "\n"
|
|
||||||
<< " translate_frame is " << _translate_frame << "\n"
|
|
||||||
<< " rotate_frame is " << _rotate_frame << "\n"
|
|
||||||
<< " mirror is " << _mirror << "\n"
|
|
||||||
<< " stagger is " << _stagger << "\n"
|
|
||||||
<< " wrap_u is " << _wrap_u << "\n"
|
|
||||||
<< " wrap_v is " << _wrap_v << "\n"
|
|
||||||
<< " repeat_uv is " << _repeat_uv << "\n"
|
|
||||||
<< " offset is " << _offset << "\n"
|
|
||||||
<< " rotate_uv is " << _rotate_uv << "\n";
|
|
||||||
|
|
||||||
} else if (_has_color) {
|
|
||||||
out << " color is " << _color << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaShader::reset_maya_texture
|
// Function: MayaShader::write
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Changes the texture filename stored in the Maya file
|
// Description:
|
||||||
// for this particular shader.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool MayaShader::
|
void MayaShader::
|
||||||
reset_maya_texture(const Filename &texture) {
|
write(ostream &out) const {
|
||||||
if (_color_object != (MObject *)NULL) {
|
out << "Shader " << get_name() << "\n"
|
||||||
_has_texture = set_string_attribute(*_color_object, "fileTextureName",
|
<< " color:\n";
|
||||||
texture);
|
_color.write(out);
|
||||||
_texture = texture;
|
out << " transparency:\n";
|
||||||
|
_transparency.write(out);
|
||||||
|
}
|
||||||
|
|
||||||
if (!_has_texture) {
|
////////////////////////////////////////////////////////////////////
|
||||||
maya_cat.error()
|
// Function: MayaShader::get_rgba
|
||||||
<< "Unable to reset texture filename.\n";
|
// Access: Public
|
||||||
|
// Description: Returns the overall color of the shader as a
|
||||||
|
// single-precision rgba value, where the alpha
|
||||||
|
// component represents transparency according to the
|
||||||
|
// Panda convention. If no overall color is specified
|
||||||
|
// (_has_flat_color is not true), this returns white.
|
||||||
|
//
|
||||||
|
// Normally, Maya makes texture color override the flat
|
||||||
|
// color, so if a texture is also applied (_has_texture
|
||||||
|
// is true), this value is not used by Maya.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Colorf MayaShader::
|
||||||
|
get_rgba() const {
|
||||||
|
Colorf rgba(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
if (_color._has_flat_color) {
|
||||||
|
rgba[0] = (float)_color._flat_color[0];
|
||||||
|
rgba[1] = (float)_color._flat_color[1];
|
||||||
|
rgba[2] = (float)_color._flat_color[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return _has_texture;
|
if (_transparency._has_flat_color) {
|
||||||
|
// Maya supports colored transparency, but we only support
|
||||||
|
// grayscale transparency. Use the pnmimage constants to
|
||||||
|
// convert color to grayscale.
|
||||||
|
double trans =
|
||||||
|
_transparency._flat_color[0] * lumin_red +
|
||||||
|
_transparency._flat_color[1] * lumin_grn +
|
||||||
|
_transparency._flat_color[2] * lumin_blu;
|
||||||
|
rgba[3] = 1.0f - (float)trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
maya_cat.error()
|
return rgba;
|
||||||
<< "Attempt to reset texture on Maya object that has no color set.\n";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -216,25 +154,34 @@ read_surface_shader(MObject shader) {
|
|||||||
// shader says for color.
|
// shader says for color.
|
||||||
|
|
||||||
MPlug color_plug = shader_fn.findPlug("color");
|
MPlug color_plug = shader_fn.findPlug("color");
|
||||||
|
if (color_plug.isNull()) {
|
||||||
|
// Or maybe a connection to outColor. Not sure how this differs
|
||||||
|
// from just color, but empirically it seems that either might be
|
||||||
|
// used.
|
||||||
|
color_plug = shader_fn.findPlug("outColor");
|
||||||
|
}
|
||||||
|
|
||||||
if (!color_plug.isNull()) {
|
if (!color_plug.isNull()) {
|
||||||
MPlugArray color_pa;
|
MPlugArray color_pa;
|
||||||
color_plug.connectedTo(color_pa, true, false);
|
color_plug.connectedTo(color_pa, true, false);
|
||||||
|
|
||||||
for (size_t i = 0; i < color_pa.length(); i++) {
|
for (size_t i = 0; i < color_pa.length(); i++) {
|
||||||
read_surface_color(color_pa[0].node());
|
_color.read_surface_color(color_pa[0].node());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Or maybe a connection to outColor. Not sure how this differs
|
// Transparency is stored separately.
|
||||||
// from just color, but empirically it seems that either might be
|
MPlug trans_plug = shader_fn.findPlug("transparency");
|
||||||
// used.
|
if (trans_plug.isNull()) {
|
||||||
MPlug out_color_plug = shader_fn.findPlug("outColor");
|
trans_plug = shader_fn.findPlug("outTransparency");
|
||||||
if (!out_color_plug.isNull()) {
|
}
|
||||||
MPlugArray color_pa;
|
|
||||||
out_color_plug.connectedTo(color_pa, true, false);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < color_pa.length(); i++) {
|
if (!trans_plug.isNull()) {
|
||||||
read_surface_color(color_pa[0].node());
|
MPlugArray trans_pa;
|
||||||
|
trans_plug.connectedTo(trans_pa, true, false);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < trans_pa.length(); i++) {
|
||||||
|
_transparency.read_surface_color(trans_pa[0].node());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,12 +191,22 @@ read_surface_shader(MObject shader) {
|
|||||||
MFnLambertShader lambert_fn(shader);
|
MFnLambertShader lambert_fn(shader);
|
||||||
MColor color = lambert_fn.color(&status);
|
MColor color = lambert_fn.color(&status);
|
||||||
if (status) {
|
if (status) {
|
||||||
_color.set(color.r, color.g, color.b, color.a);
|
// Warning! The alpha component of color doesn't mean
|
||||||
_has_color = true;
|
// transparency in Maya.
|
||||||
|
_color._has_flat_color = true;
|
||||||
|
_color._flat_color.set(color.r, color.g, color.b, color.a);
|
||||||
|
_transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
// Get the transparency separately.
|
||||||
|
color = lambert_fn.transparency(&status);
|
||||||
|
if (status) {
|
||||||
|
_transparency._has_flat_color = true;
|
||||||
|
_transparency._flat_color.set(color.r, color.g, color.b, color.a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_has_color && !_has_texture) {
|
if (!_color._has_flat_color && !_color._has_texture) {
|
||||||
if (maya_cat.is_spam()) {
|
if (maya_cat.is_spam()) {
|
||||||
maya_cat.spam()
|
maya_cat.spam()
|
||||||
<< " Color definition not found.\n";
|
<< " Color definition not found.\n";
|
||||||
@ -257,237 +214,3 @@ read_surface_shader(MObject shader) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::read_surface_color
|
|
||||||
// Access: Private
|
|
||||||
// Description: Determines the surface color specified by the shader.
|
|
||||||
// This includes texturing and other advanced shader
|
|
||||||
// properties.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void MayaShader::
|
|
||||||
read_surface_color(MObject color) {
|
|
||||||
if (color.hasFn(MFn::kFileTexture)) {
|
|
||||||
_color_object = new MObject(color);
|
|
||||||
string filename;
|
|
||||||
_has_texture = get_string_attribute(color, "fileTextureName", filename);
|
|
||||||
if (_has_texture) {
|
|
||||||
_texture = Filename::from_os_specific(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_vec2f_attribute(color, "coverage", _coverage);
|
|
||||||
get_vec2f_attribute(color, "translateFrame", _translate_frame);
|
|
||||||
get_angle_attribute(color, "rotateFrame", _rotate_frame);
|
|
||||||
|
|
||||||
get_bool_attribute(color, "mirror", _mirror);
|
|
||||||
get_bool_attribute(color, "stagger", _stagger);
|
|
||||||
get_bool_attribute(color, "wrapU", _wrap_u);
|
|
||||||
get_bool_attribute(color, "wrapV", _wrap_v);
|
|
||||||
|
|
||||||
get_vec2f_attribute(color, "repeatUV", _repeat_uv);
|
|
||||||
get_vec2f_attribute(color, "offset", _offset);
|
|
||||||
get_angle_attribute(color, "rotateUV", _rotate_uv);
|
|
||||||
|
|
||||||
} else if (color.hasFn(MFn::kProjection)) {
|
|
||||||
// This is a projected texture. We will have to step one level
|
|
||||||
// deeper to find the actual texture.
|
|
||||||
MFnDependencyNode projection_fn(color);
|
|
||||||
MPlug image_plug = projection_fn.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++) {
|
|
||||||
read_surface_color(image_pa[0].node());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!get_mat4d_attribute(color, "placementMatrix", _projection_matrix)) {
|
|
||||||
_projection_matrix = LMatrix4d::ident_mat();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The uAngle and vAngle might be used for certain kinds of
|
|
||||||
// projections.
|
|
||||||
if (!get_angle_attribute(color, "uAngle", _u_angle)) {
|
|
||||||
_u_angle = 360.0;
|
|
||||||
}
|
|
||||||
if (!get_angle_attribute(color, "vAngle", _v_angle)) {
|
|
||||||
_v_angle = 180.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
string type;
|
|
||||||
if (get_enum_attribute(color, "projType", type)) {
|
|
||||||
set_projection_type(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// This shader wasn't understood.
|
|
||||||
if (maya_cat.is_debug()) {
|
|
||||||
maya_cat.info()
|
|
||||||
<< "**Don't know how to interpret color attribute type "
|
|
||||||
<< color.apiTypeStr() << "\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// If we don't have a heavy verbose count, only report each type
|
|
||||||
// of unsupportted shader once.
|
|
||||||
static pset<MFn::Type> bad_types;
|
|
||||||
if (bad_types.insert(color.apiType()).second) {
|
|
||||||
maya_cat.info()
|
|
||||||
<< "**Don't know how to interpret color attribute type "
|
|
||||||
<< color.apiTypeStr() << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::set_projection_type
|
|
||||||
// Access: Private
|
|
||||||
// Description: Sets up the shader to apply UV's according to the
|
|
||||||
// indicated projection type.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void MayaShader::
|
|
||||||
set_projection_type(const string &type) {
|
|
||||||
if (cmp_nocase(type, "planar") == 0) {
|
|
||||||
_projection_type = PT_planar;
|
|
||||||
_map_uvs = &MayaShader::map_planar;
|
|
||||||
|
|
||||||
// The Planar projection normally projects to a range (-1, 1) in
|
|
||||||
// both axes. Scale this into our UV range of (0, 1).
|
|
||||||
_projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.5, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 1.0, 0.0,
|
|
||||||
0.5, 0.5, 0.0, 1.0);
|
|
||||||
|
|
||||||
} else if (cmp_nocase(type, "cylindrical") == 0) {
|
|
||||||
_projection_type = PT_cylindrical;
|
|
||||||
_map_uvs = &MayaShader::map_cylindrical;
|
|
||||||
|
|
||||||
// The cylindrical projection is orthographic in the Y axis; scale
|
|
||||||
// the range (-1, 1) in this axis into our UV range (0, 1).
|
|
||||||
_projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.5, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 1.0, 0.0,
|
|
||||||
0.0, 0.5, 0.0, 1.0);
|
|
||||||
|
|
||||||
} else if (cmp_nocase(type, "spherical") == 0) {
|
|
||||||
_projection_type = PT_spherical;
|
|
||||||
_map_uvs = &MayaShader::map_spherical;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Other projection types are currently unimplemented by the
|
|
||||||
// converter.
|
|
||||||
maya_cat.error()
|
|
||||||
<< "Don't know how to handle type " << type << " projections.\n";
|
|
||||||
_projection_type = PT_off;
|
|
||||||
_map_uvs = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::map_planar
|
|
||||||
// Access: Private
|
|
||||||
// Description: Computes a UV based on the given point in space,
|
|
||||||
// using a planar projection.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
LPoint2d MayaShader::
|
|
||||||
map_planar(const LPoint3d &pos, const LPoint3d &) const {
|
|
||||||
// A planar projection is about as easy as can be. We ignore the Z
|
|
||||||
// axis, and project the point into the XY plane. Done.
|
|
||||||
return LPoint2d(pos[0], pos[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::map_spherical
|
|
||||||
// Access: Private
|
|
||||||
// Description: Computes a UV based on the given point in space,
|
|
||||||
// using a spherical projection.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
LPoint2d MayaShader::
|
|
||||||
map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
|
||||||
// To compute the x position on the frame, we only need to consider
|
|
||||||
// the angle of the vector about the Y axis. Project the vector
|
|
||||||
// into the XZ plane to do this.
|
|
||||||
|
|
||||||
LVector2d xz(pos[0], pos[2]);
|
|
||||||
double xz_length = xz.length();
|
|
||||||
|
|
||||||
if (xz_length < 0.01) {
|
|
||||||
// If we have a point on or near either pole, we've got problems.
|
|
||||||
// This point maps to the entire bottom edge of the image, so
|
|
||||||
// which U value should we choose? It does make a difference,
|
|
||||||
// especially if we have a number of polygons around the south
|
|
||||||
// pole that all share the common vertex.
|
|
||||||
|
|
||||||
// We choose the U value based on the polygon's centroid.
|
|
||||||
xz.set(centroid[0], centroid[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, if the polygon crosses the seam, we also have problems.
|
|
||||||
// Make sure that the u value is in the same half of the texture as
|
|
||||||
// the centroid's u value.
|
|
||||||
double u = rad_2_deg(atan2(xz[0], xz[1])) / (2.0 * _u_angle);
|
|
||||||
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / (2.0 * _u_angle);
|
|
||||||
|
|
||||||
if (u - c > 0.5) {
|
|
||||||
u -= floor(u - c + 0.5);
|
|
||||||
} else if (u - c < -0.5) {
|
|
||||||
u += floor(c - u + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now rotate the vector into the YZ plane, and the V value is based
|
|
||||||
// on the latitude: the angle about the X axis.
|
|
||||||
LVector2d yz(pos[1], xz_length);
|
|
||||||
double v = rad_2_deg(atan2(yz[0], yz[1])) / (2.0 * _v_angle);
|
|
||||||
|
|
||||||
LPoint2d uv(u - 0.5, v - 0.5);
|
|
||||||
|
|
||||||
nassertr(fabs(u - c) <= 0.5, uv);
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaShader::map_cylindrical
|
|
||||||
// Access: Private
|
|
||||||
// Description: Computes a UV based on the given point in space,
|
|
||||||
// using a cylindrical projection.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
LPoint2d MayaShader::
|
|
||||||
map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
|
||||||
// This is almost identical to the spherical projection, except for
|
|
||||||
// the computation of V.
|
|
||||||
|
|
||||||
LVector2d xz(pos[0], pos[2]);
|
|
||||||
double xz_length = xz.length();
|
|
||||||
|
|
||||||
if (xz_length < 0.01) {
|
|
||||||
// A cylindrical mapping has the same singularity problem at the
|
|
||||||
// pole as a spherical mapping does: points at the pole do not map
|
|
||||||
// to a single point on the texture. (It's technically a slightly
|
|
||||||
// different problem: in a cylindrical mapping, points at the pole
|
|
||||||
// do not map to any point on the texture, while in a spherical
|
|
||||||
// mapping, points at the pole map to the top or bottom edge of
|
|
||||||
// the texture. But this is a technicality that doesn't really
|
|
||||||
// apply to us.) We still solve it the same way: if our point is
|
|
||||||
// at or near the pole, compute the angle based on the centroid of
|
|
||||||
// the polygon (which we assume is further from the pole).
|
|
||||||
xz.set(centroid[0], centroid[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// And cylinders do still have a seam at the back.
|
|
||||||
double u = rad_2_deg(atan2(xz[0], xz[1])) / _u_angle;
|
|
||||||
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / _u_angle;
|
|
||||||
|
|
||||||
if (u - c > 0.5) {
|
|
||||||
u -= floor(u - c + 0.5);
|
|
||||||
} else if (u - c < -0.5) {
|
|
||||||
u += floor(c - u + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For a cylindrical mapping, the V value comes directly from Y.
|
|
||||||
// Easy.
|
|
||||||
LPoint2d uv(u - 0.5, pos[1]);
|
|
||||||
|
|
||||||
nassertr(fabs(u - c) <= 0.5, uv);
|
|
||||||
return uv;
|
|
||||||
}
|
|
||||||
|
@ -20,9 +20,11 @@
|
|||||||
#define MAYASHADER_H
|
#define MAYASHADER_H
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
#include "pandatoolbase.h"
|
||||||
|
#include "mayaShaderColorDef.h"
|
||||||
|
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
#include "lmatrix.h"
|
#include "lmatrix.h"
|
||||||
|
#include "namable.h"
|
||||||
|
|
||||||
class MObject;
|
class MObject;
|
||||||
|
|
||||||
@ -34,69 +36,21 @@ class MObject;
|
|||||||
// that we don't care about or don't know enough to
|
// that we don't care about or don't know enough to
|
||||||
// extract.
|
// extract.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class MayaShader {
|
class MayaShader : public Namable {
|
||||||
public:
|
public:
|
||||||
MayaShader(MObject engine);
|
MayaShader(MObject engine);
|
||||||
~MayaShader();
|
~MayaShader();
|
||||||
|
|
||||||
LMatrix3d compute_texture_matrix() const;
|
|
||||||
bool has_projection() const;
|
|
||||||
TexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const;
|
|
||||||
|
|
||||||
void output(ostream &out) const;
|
void output(ostream &out) const;
|
||||||
bool reset_maya_texture(const Filename &texture);
|
void write(ostream &out) const;
|
||||||
|
|
||||||
string _name;
|
Colorf get_rgba() const;
|
||||||
|
|
||||||
bool _has_color;
|
MayaShaderColorDef _color;
|
||||||
Colord _color;
|
MayaShaderColorDef _transparency;
|
||||||
double _transparency;
|
|
||||||
|
|
||||||
bool _has_texture;
|
|
||||||
Filename _texture;
|
|
||||||
|
|
||||||
enum ProjectionType {
|
|
||||||
PT_off,
|
|
||||||
PT_planar,
|
|
||||||
PT_spherical,
|
|
||||||
PT_cylindrical,
|
|
||||||
PT_ball,
|
|
||||||
PT_cubic,
|
|
||||||
PT_triplanar,
|
|
||||||
PT_concentric,
|
|
||||||
PT_perspective,
|
|
||||||
};
|
|
||||||
ProjectionType _projection_type;
|
|
||||||
LMatrix4d _projection_matrix;
|
|
||||||
double _u_angle;
|
|
||||||
double _v_angle;
|
|
||||||
|
|
||||||
LVector2f _coverage;
|
|
||||||
LVector2f _translate_frame;
|
|
||||||
double _rotate_frame;
|
|
||||||
|
|
||||||
bool _mirror;
|
|
||||||
bool _stagger;
|
|
||||||
bool _wrap_u;
|
|
||||||
bool _wrap_v;
|
|
||||||
|
|
||||||
LVector2f _repeat_uv;
|
|
||||||
LVector2f _offset;
|
|
||||||
double _rotate_uv;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MObject *_color_object;
|
|
||||||
|
|
||||||
bool read_surface_shader(MObject shader);
|
bool read_surface_shader(MObject shader);
|
||||||
void read_surface_color(MObject color);
|
|
||||||
void set_projection_type(const string &type);
|
|
||||||
|
|
||||||
LPoint2d map_planar(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
|
||||||
LPoint2d map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
|
||||||
LPoint2d map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
|
||||||
|
|
||||||
// Define a pointer to one of the above member functions.
|
|
||||||
LPoint2d (MayaShader::*_map_uvs)(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
INLINE ostream &operator << (ostream &out, const MayaShader &shader) {
|
INLINE ostream &operator << (ostream &out, const MayaShader &shader) {
|
||||||
|
405
pandatool/src/maya/mayaShaderColorDef.cxx
Normal file
405
pandatool/src/maya/mayaShaderColorDef.cxx
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
// Filename: mayaShaderColorDef.cxx
|
||||||
|
// Created by: drose (12Apr03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "mayaShaderColorDef.h"
|
||||||
|
#include "maya_funcs.h"
|
||||||
|
#include "config_maya.h"
|
||||||
|
#include "string_utils.h"
|
||||||
|
#include "pset.h"
|
||||||
|
|
||||||
|
#include "pre_maya_include.h"
|
||||||
|
#include <maya/MFnDependencyNode.h>
|
||||||
|
#include <maya/MPlug.h>
|
||||||
|
#include <maya/MPlugArray.h>
|
||||||
|
#include <maya/MObject.h>
|
||||||
|
#include <maya/MStatus.h>
|
||||||
|
#include "post_maya_include.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaShaderColorDef::
|
||||||
|
MayaShaderColorDef() {
|
||||||
|
_has_flat_color = false;
|
||||||
|
_flat_color.set(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
_has_texture = false;
|
||||||
|
_projection_type = PT_off;
|
||||||
|
_map_uvs = NULL;
|
||||||
|
|
||||||
|
_coverage.set(1.0, 1.0);
|
||||||
|
_translate_frame.set(0.0, 0.0);
|
||||||
|
_rotate_frame = 0.0;
|
||||||
|
|
||||||
|
_mirror = false;
|
||||||
|
_stagger = false;
|
||||||
|
_wrap_u = true;
|
||||||
|
_wrap_v = true;
|
||||||
|
|
||||||
|
_repeat_uv.set(1.0, 1.0);
|
||||||
|
_offset.set(0.0, 0.0);
|
||||||
|
_rotate_uv = 0.0;
|
||||||
|
|
||||||
|
_color_object = (MObject *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaShaderColorDef::
|
||||||
|
~MayaShaderColorDef() {
|
||||||
|
if (_color_object != (MObject *)NULL) {
|
||||||
|
delete _color_object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::compute_texture_matrix
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns a texture matrix corresponding to the texture
|
||||||
|
// transforms indicated by the shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LMatrix3d MayaShaderColorDef::
|
||||||
|
compute_texture_matrix() const {
|
||||||
|
LVector2d scale(_repeat_uv[0] / _coverage[0],
|
||||||
|
_repeat_uv[1] / _coverage[1]);
|
||||||
|
LVector2d trans(_offset[0] - _translate_frame[0] / _coverage[0],
|
||||||
|
_offset[1] - _translate_frame[1] / _coverage[1]);
|
||||||
|
|
||||||
|
return
|
||||||
|
(LMatrix3d::translate_mat(LVector2d(-0.5, -0.5)) *
|
||||||
|
LMatrix3d::rotate_mat(_rotate_frame) *
|
||||||
|
LMatrix3d::translate_mat(LVector2d(0.5, 0.5))) *
|
||||||
|
LMatrix3d::scale_mat(scale) *
|
||||||
|
LMatrix3d::translate_mat(trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::has_projection
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the shader has a projection in effect.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaShaderColorDef::
|
||||||
|
has_projection() const {
|
||||||
|
return (_projection_type != PT_off);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::project_uv
|
||||||
|
// Access: Public
|
||||||
|
// Description: If the shader has a projection (has_projection()
|
||||||
|
// returns true), this computes the appropriate UV
|
||||||
|
// corresponding to the indicated 3-d point. Seams that
|
||||||
|
// might be introduced on polygons that cross quadrants
|
||||||
|
// are closed up by ensuring the point is in the same
|
||||||
|
// quadrant as the indicated reference point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TexCoordd MayaShaderColorDef::
|
||||||
|
project_uv(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
||||||
|
nassertr(_map_uvs != NULL, TexCoordd::zero());
|
||||||
|
return (this->*_map_uvs)(pos * _projection_matrix, centroid * _projection_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::write
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaShaderColorDef::
|
||||||
|
write(ostream &out) const {
|
||||||
|
if (_has_texture) {
|
||||||
|
out << " texture is " << _texture << "\n"
|
||||||
|
<< " coverage is " << _coverage << "\n"
|
||||||
|
<< " translate_frame is " << _translate_frame << "\n"
|
||||||
|
<< " rotate_frame is " << _rotate_frame << "\n"
|
||||||
|
<< " mirror is " << _mirror << "\n"
|
||||||
|
<< " stagger is " << _stagger << "\n"
|
||||||
|
<< " wrap_u is " << _wrap_u << "\n"
|
||||||
|
<< " wrap_v is " << _wrap_v << "\n"
|
||||||
|
<< " repeat_uv is " << _repeat_uv << "\n"
|
||||||
|
<< " offset is " << _offset << "\n"
|
||||||
|
<< " rotate_uv is " << _rotate_uv << "\n";
|
||||||
|
|
||||||
|
} else if (_has_flat_color) {
|
||||||
|
out << " flat color is " << _flat_color << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::reset_maya_texture
|
||||||
|
// Access: Public
|
||||||
|
// Description: Changes the texture filename stored in the Maya file
|
||||||
|
// for this particular shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaShaderColorDef::
|
||||||
|
reset_maya_texture(const Filename &texture) {
|
||||||
|
if (_color_object != (MObject *)NULL) {
|
||||||
|
_has_texture = set_string_attribute(*_color_object, "fileTextureName",
|
||||||
|
texture);
|
||||||
|
_texture = texture;
|
||||||
|
|
||||||
|
if (!_has_texture) {
|
||||||
|
maya_cat.error()
|
||||||
|
<< "Unable to reset texture filename.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return _has_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
maya_cat.error()
|
||||||
|
<< "Attempt to reset texture on Maya object that has no color set.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::read_surface_color
|
||||||
|
// Access: Private
|
||||||
|
// Description: Determines the surface color specified by the shader.
|
||||||
|
// This includes texturing and other advanced shader
|
||||||
|
// properties.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaShaderColorDef::
|
||||||
|
read_surface_color(MObject color) {
|
||||||
|
if (color.hasFn(MFn::kFileTexture)) {
|
||||||
|
_color_object = new MObject(color);
|
||||||
|
string filename;
|
||||||
|
_has_texture = get_string_attribute(color, "fileTextureName", filename);
|
||||||
|
if (_has_texture) {
|
||||||
|
_texture = Filename::from_os_specific(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_vec2f_attribute(color, "coverage", _coverage);
|
||||||
|
get_vec2f_attribute(color, "translateFrame", _translate_frame);
|
||||||
|
get_angle_attribute(color, "rotateFrame", _rotate_frame);
|
||||||
|
|
||||||
|
get_bool_attribute(color, "mirror", _mirror);
|
||||||
|
get_bool_attribute(color, "stagger", _stagger);
|
||||||
|
get_bool_attribute(color, "wrapU", _wrap_u);
|
||||||
|
get_bool_attribute(color, "wrapV", _wrap_v);
|
||||||
|
|
||||||
|
get_vec2f_attribute(color, "repeatUV", _repeat_uv);
|
||||||
|
get_vec2f_attribute(color, "offset", _offset);
|
||||||
|
get_angle_attribute(color, "rotateUV", _rotate_uv);
|
||||||
|
|
||||||
|
} else if (color.hasFn(MFn::kProjection)) {
|
||||||
|
// This is a projected texture. We will have to step one level
|
||||||
|
// deeper to find the actual texture.
|
||||||
|
MFnDependencyNode projection_fn(color);
|
||||||
|
MPlug image_plug = projection_fn.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++) {
|
||||||
|
read_surface_color(image_pa[0].node());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!get_mat4d_attribute(color, "placementMatrix", _projection_matrix)) {
|
||||||
|
_projection_matrix = LMatrix4d::ident_mat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The uAngle and vAngle might be used for certain kinds of
|
||||||
|
// projections.
|
||||||
|
if (!get_angle_attribute(color, "uAngle", _u_angle)) {
|
||||||
|
_u_angle = 360.0;
|
||||||
|
}
|
||||||
|
if (!get_angle_attribute(color, "vAngle", _v_angle)) {
|
||||||
|
_v_angle = 180.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string type;
|
||||||
|
if (get_enum_attribute(color, "projType", type)) {
|
||||||
|
set_projection_type(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// This shader wasn't understood.
|
||||||
|
if (maya_cat.is_debug()) {
|
||||||
|
maya_cat.info()
|
||||||
|
<< "**Don't know how to interpret color attribute type "
|
||||||
|
<< color.apiTypeStr() << "\n";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If we don't have a heavy verbose count, only report each type
|
||||||
|
// of unsupported shader once.
|
||||||
|
static pset<MFn::Type> bad_types;
|
||||||
|
if (bad_types.insert(color.apiType()).second) {
|
||||||
|
maya_cat.info()
|
||||||
|
<< "**Don't know how to interpret color attribute type "
|
||||||
|
<< color.apiTypeStr() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::set_projection_type
|
||||||
|
// Access: Private
|
||||||
|
// Description: Sets up the shader to apply UV's according to the
|
||||||
|
// indicated projection type.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaShaderColorDef::
|
||||||
|
set_projection_type(const string &type) {
|
||||||
|
if (cmp_nocase(type, "planar") == 0) {
|
||||||
|
_projection_type = PT_planar;
|
||||||
|
_map_uvs = &MayaShaderColorDef::map_planar;
|
||||||
|
|
||||||
|
// The Planar projection normally projects to a range (-1, 1) in
|
||||||
|
// both axes. Scale this into our UV range of (0, 1).
|
||||||
|
_projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 1.0, 0.0,
|
||||||
|
0.5, 0.5, 0.0, 1.0);
|
||||||
|
|
||||||
|
} else if (cmp_nocase(type, "cylindrical") == 0) {
|
||||||
|
_projection_type = PT_cylindrical;
|
||||||
|
_map_uvs = &MayaShaderColorDef::map_cylindrical;
|
||||||
|
|
||||||
|
// The cylindrical projection is orthographic in the Y axis; scale
|
||||||
|
// the range (-1, 1) in this axis into our UV range (0, 1).
|
||||||
|
_projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 1.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 1.0);
|
||||||
|
|
||||||
|
} else if (cmp_nocase(type, "spherical") == 0) {
|
||||||
|
_projection_type = PT_spherical;
|
||||||
|
_map_uvs = &MayaShaderColorDef::map_spherical;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Other projection types are currently unimplemented by the
|
||||||
|
// converter.
|
||||||
|
maya_cat.error()
|
||||||
|
<< "Don't know how to handle type " << type << " projections.\n";
|
||||||
|
_projection_type = PT_off;
|
||||||
|
_map_uvs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::map_planar
|
||||||
|
// Access: Private
|
||||||
|
// Description: Computes a UV based on the given point in space,
|
||||||
|
// using a planar projection.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LPoint2d MayaShaderColorDef::
|
||||||
|
map_planar(const LPoint3d &pos, const LPoint3d &) const {
|
||||||
|
// A planar projection is about as easy as can be. We ignore the Z
|
||||||
|
// axis, and project the point into the XY plane. Done.
|
||||||
|
return LPoint2d(pos[0], pos[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::map_spherical
|
||||||
|
// Access: Private
|
||||||
|
// Description: Computes a UV based on the given point in space,
|
||||||
|
// using a spherical projection.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LPoint2d MayaShaderColorDef::
|
||||||
|
map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
||||||
|
// To compute the x position on the frame, we only need to consider
|
||||||
|
// the angle of the vector about the Y axis. Project the vector
|
||||||
|
// into the XZ plane to do this.
|
||||||
|
|
||||||
|
LVector2d xz(pos[0], pos[2]);
|
||||||
|
double xz_length = xz.length();
|
||||||
|
|
||||||
|
if (xz_length < 0.01) {
|
||||||
|
// If we have a point on or near either pole, we've got problems.
|
||||||
|
// This point maps to the entire bottom edge of the image, so
|
||||||
|
// which U value should we choose? It does make a difference,
|
||||||
|
// especially if we have a number of polygons around the south
|
||||||
|
// pole that all share the common vertex.
|
||||||
|
|
||||||
|
// We choose the U value based on the polygon's centroid.
|
||||||
|
xz.set(centroid[0], centroid[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, if the polygon crosses the seam, we also have problems.
|
||||||
|
// Make sure that the u value is in the same half of the texture as
|
||||||
|
// the centroid's u value.
|
||||||
|
double u = rad_2_deg(atan2(xz[0], xz[1])) / (2.0 * _u_angle);
|
||||||
|
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / (2.0 * _u_angle);
|
||||||
|
|
||||||
|
if (u - c > 0.5) {
|
||||||
|
u -= floor(u - c + 0.5);
|
||||||
|
} else if (u - c < -0.5) {
|
||||||
|
u += floor(c - u + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now rotate the vector into the YZ plane, and the V value is based
|
||||||
|
// on the latitude: the angle about the X axis.
|
||||||
|
LVector2d yz(pos[1], xz_length);
|
||||||
|
double v = rad_2_deg(atan2(yz[0], yz[1])) / (2.0 * _v_angle);
|
||||||
|
|
||||||
|
LPoint2d uv(u - 0.5, v - 0.5);
|
||||||
|
|
||||||
|
nassertr(fabs(u - c) <= 0.5, uv);
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShaderColorDef::map_cylindrical
|
||||||
|
// Access: Private
|
||||||
|
// Description: Computes a UV based on the given point in space,
|
||||||
|
// using a cylindrical projection.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LPoint2d MayaShaderColorDef::
|
||||||
|
map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const {
|
||||||
|
// This is almost identical to the spherical projection, except for
|
||||||
|
// the computation of V.
|
||||||
|
|
||||||
|
LVector2d xz(pos[0], pos[2]);
|
||||||
|
double xz_length = xz.length();
|
||||||
|
|
||||||
|
if (xz_length < 0.01) {
|
||||||
|
// A cylindrical mapping has the same singularity problem at the
|
||||||
|
// pole as a spherical mapping does: points at the pole do not map
|
||||||
|
// to a single point on the texture. (It's technically a slightly
|
||||||
|
// different problem: in a cylindrical mapping, points at the pole
|
||||||
|
// do not map to any point on the texture, while in a spherical
|
||||||
|
// mapping, points at the pole map to the top or bottom edge of
|
||||||
|
// the texture. But this is a technicality that doesn't really
|
||||||
|
// apply to us.) We still solve it the same way: if our point is
|
||||||
|
// at or near the pole, compute the angle based on the centroid of
|
||||||
|
// the polygon (which we assume is further from the pole).
|
||||||
|
xz.set(centroid[0], centroid[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And cylinders do still have a seam at the back.
|
||||||
|
double u = rad_2_deg(atan2(xz[0], xz[1])) / _u_angle;
|
||||||
|
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / _u_angle;
|
||||||
|
|
||||||
|
if (u - c > 0.5) {
|
||||||
|
u -= floor(u - c + 0.5);
|
||||||
|
} else if (u - c < -0.5) {
|
||||||
|
u += floor(c - u + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For a cylindrical mapping, the V value comes directly from Y.
|
||||||
|
// Easy.
|
||||||
|
LPoint2d uv(u - 0.5, pos[1]);
|
||||||
|
|
||||||
|
nassertr(fabs(u - c) <= 0.5, uv);
|
||||||
|
return uv;
|
||||||
|
}
|
100
pandatool/src/maya/mayaShaderColorDef.h
Executable file
100
pandatool/src/maya/mayaShaderColorDef.h
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
// Filename: mayaShaderColorDef.h
|
||||||
|
// Created by: drose (12Apr03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MAYASHADERCOLORDEF_H
|
||||||
|
#define MAYASHADERCOLORDEF_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
|
#include "luse.h"
|
||||||
|
#include "lmatrix.h"
|
||||||
|
|
||||||
|
class MObject;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : MayaShaderColorDef
|
||||||
|
// Description : This defines the various attributes that Maya may
|
||||||
|
// associate with the "color" channel for a particular
|
||||||
|
// shader (as well as on the "transparency" channel).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class MayaShaderColorDef {
|
||||||
|
public:
|
||||||
|
MayaShaderColorDef();
|
||||||
|
~MayaShaderColorDef();
|
||||||
|
|
||||||
|
LMatrix3d compute_texture_matrix() const;
|
||||||
|
bool has_projection() const;
|
||||||
|
TexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const;
|
||||||
|
bool reset_maya_texture(const Filename &texture);
|
||||||
|
|
||||||
|
void write(ostream &out) const;
|
||||||
|
|
||||||
|
enum ProjectionType {
|
||||||
|
PT_off,
|
||||||
|
PT_planar,
|
||||||
|
PT_spherical,
|
||||||
|
PT_cylindrical,
|
||||||
|
PT_ball,
|
||||||
|
PT_cubic,
|
||||||
|
PT_triplanar,
|
||||||
|
PT_concentric,
|
||||||
|
PT_perspective,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool _has_texture;
|
||||||
|
Filename _texture;
|
||||||
|
|
||||||
|
bool _has_flat_color;
|
||||||
|
Colord _flat_color;
|
||||||
|
|
||||||
|
ProjectionType _projection_type;
|
||||||
|
LMatrix4d _projection_matrix;
|
||||||
|
double _u_angle;
|
||||||
|
double _v_angle;
|
||||||
|
|
||||||
|
LVector2f _coverage;
|
||||||
|
LVector2f _translate_frame;
|
||||||
|
double _rotate_frame;
|
||||||
|
|
||||||
|
bool _mirror;
|
||||||
|
bool _stagger;
|
||||||
|
bool _wrap_u;
|
||||||
|
bool _wrap_v;
|
||||||
|
|
||||||
|
LVector2f _repeat_uv;
|
||||||
|
LVector2f _offset;
|
||||||
|
double _rotate_uv;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void read_surface_color(MObject color);
|
||||||
|
void set_projection_type(const string &type);
|
||||||
|
|
||||||
|
LPoint2d map_planar(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
||||||
|
LPoint2d map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
||||||
|
LPoint2d map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1388,11 +1388,13 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
shader = default_shader;
|
shader = default_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MayaShaderColorDef &color_def = shader->_color;
|
||||||
|
|
||||||
// Since a texture completely replaces a polygon or vertex color,
|
// Since a texture completely replaces a polygon or vertex color,
|
||||||
// we need to know up front whether we have a texture.
|
// we need to know up front whether we have a texture.
|
||||||
bool has_texture = false;
|
bool has_texture = false;
|
||||||
if (shader != (MayaShader *)NULL) {
|
if (shader != (MayaShader *)NULL) {
|
||||||
has_texture = shader->_has_texture;
|
has_texture = color_def._has_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the vertices for the polygon.
|
// Get the vertices for the polygon.
|
||||||
@ -1400,7 +1402,7 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
long i;
|
long i;
|
||||||
LPoint3d centroid(0.0, 0.0, 0.0);
|
LPoint3d centroid(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
if (shader != (MayaShader *)NULL && shader->has_projection()) {
|
if (shader != (MayaShader *)NULL && color_def.has_projection()) {
|
||||||
// If the shader has a projection, we may need to compute the
|
// If the shader has a projection, we may need to compute the
|
||||||
// polygon's centroid to avoid seams at the edges.
|
// polygon's centroid to avoid seams at the edges.
|
||||||
for (i = 0; i < num_verts; i++) {
|
for (i = 0; i < num_verts; i++) {
|
||||||
@ -1430,10 +1432,10 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
vert.set_normal(n3d);
|
vert.set_normal(n3d);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader != (MayaShader *)NULL && shader->has_projection()) {
|
if (shader != (MayaShader *)NULL && color_def.has_projection()) {
|
||||||
// If the shader has a projection, use it instead of the
|
// If the shader has a projection, use it instead of the
|
||||||
// polygon's built-in UV's.
|
// polygon's built-in UV's.
|
||||||
vert.set_uv(shader->project_uv(p3d, centroid));
|
vert.set_uv(color_def.project_uv(p3d, centroid));
|
||||||
|
|
||||||
} else if (pi.hasUVs()) {
|
} else if (pi.hasUVs()) {
|
||||||
// Get the UV's from the polygon.
|
// Get the UV's from the polygon.
|
||||||
@ -1778,7 +1780,7 @@ get_egg_table(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaShader::set_shader_attributes
|
// Function: MayaShader::set_shader_attributes
|
||||||
// Access: Public
|
// Access: Private
|
||||||
// Description: Applies the known shader attributes to the indicated
|
// Description: Applies the known shader attributes to the indicated
|
||||||
// egg primitive.
|
// egg primitive.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1786,24 +1788,63 @@ void MayaToEggConverter::
|
|||||||
set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) {
|
set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) {
|
||||||
// In Maya, a polygon is either textured or colored. The texture,
|
// In Maya, a polygon is either textured or colored. The texture,
|
||||||
// if present, replaces the color.
|
// if present, replaces the color.
|
||||||
|
const MayaShaderColorDef &color_def = shader._color;
|
||||||
|
const MayaShaderColorDef &trans_def = shader._transparency;
|
||||||
|
if (color_def._has_texture || trans_def._has_texture) {
|
||||||
|
EggTexture tex(shader.get_name(), "");
|
||||||
|
|
||||||
if (shader._has_texture) {
|
if (color_def._has_texture) {
|
||||||
Filename filename = Filename::from_os_specific(shader._texture);
|
// If we have a texture on color, apply it as the filename.
|
||||||
|
Filename filename = Filename::from_os_specific(color_def._texture);
|
||||||
Filename fullpath =
|
Filename fullpath =
|
||||||
_path_replace->match_path(filename, get_texture_path());
|
_path_replace->match_path(filename, get_texture_path());
|
||||||
EggTexture tex(shader._name, _path_replace->store_path(fullpath));
|
tex.set_filename(_path_replace->store_path(fullpath));
|
||||||
tex.set_fullpath(fullpath);
|
tex.set_fullpath(fullpath);
|
||||||
|
apply_texture_properties(tex, color_def);
|
||||||
|
|
||||||
tex.set_wrap_u(shader._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp);
|
// If we also have a texture on transparency, apply it as the
|
||||||
tex.set_wrap_v(shader._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp);
|
// alpha filename.
|
||||||
|
if (trans_def._has_texture) {
|
||||||
|
if (color_def._wrap_u != trans_def._wrap_u ||
|
||||||
|
color_def._wrap_u != trans_def._wrap_u) {
|
||||||
|
mayaegg_cat.warning()
|
||||||
|
<< "Shader " << shader.get_name()
|
||||||
|
<< " has contradictory wrap modes on color and texture.\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Let's mipmap all textures by default.
|
filename = Filename::from_os_specific(trans_def._texture);
|
||||||
tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
|
fullpath = _path_replace->match_path(filename, get_texture_path());
|
||||||
tex.set_magfilter(EggTexture::FT_linear);
|
tex.set_alpha_filename(_path_replace->store_path(fullpath));
|
||||||
|
tex.set_alpha_fullpath(fullpath);
|
||||||
|
tex.set_format(EggTexture::F_rgba);
|
||||||
|
|
||||||
LMatrix3d mat = shader.compute_texture_matrix();
|
if (!compare_texture_properties(tex, trans_def)) {
|
||||||
if (!mat.almost_equal(LMatrix3d::ident_mat())) {
|
// Only report each broken shader once.
|
||||||
tex.set_transform(mat);
|
static pset<string> bad_shaders;
|
||||||
|
if (bad_shaders.insert(shader.get_name()).second) {
|
||||||
|
mayaegg_cat.error()
|
||||||
|
<< "Color and transparency texture properties differ on shader "
|
||||||
|
<< shader.get_name() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, we don't have any transparency, so tell the egg
|
||||||
|
// format to ignore any alpha channel that might be on the
|
||||||
|
// color texture.
|
||||||
|
tex.set_format(EggTexture::F_rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // trans_def._has_texture
|
||||||
|
// We have a texture on transparency only. Apply it as the
|
||||||
|
// primary filename, and set the format accordingly.
|
||||||
|
Filename filename = Filename::from_os_specific(trans_def._texture);
|
||||||
|
Filename fullpath =
|
||||||
|
_path_replace->match_path(filename, get_texture_path());
|
||||||
|
tex.set_filename(_path_replace->store_path(fullpath));
|
||||||
|
tex.set_fullpath(fullpath);
|
||||||
|
tex.set_format(EggTexture::F_alpha);
|
||||||
|
apply_texture_properties(tex, trans_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
EggTexture *new_tex =
|
EggTexture *new_tex =
|
||||||
@ -1811,15 +1852,98 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) {
|
|||||||
|
|
||||||
primitive.set_texture(new_tex);
|
primitive.set_texture(new_tex);
|
||||||
|
|
||||||
} else if (shader._has_color) {
|
}
|
||||||
primitive.set_color(Colorf(shader._color[0], shader._color[1],
|
|
||||||
shader._color[2], 1.0f));
|
// Also apply an overall color to the primitive.
|
||||||
|
Colorf rgba = shader.get_rgba();
|
||||||
|
|
||||||
|
// This is a placeholder for a parameter on the shader or group that
|
||||||
|
// we have yet to define.
|
||||||
|
static const bool modulate = false;
|
||||||
|
|
||||||
|
if (!modulate) {
|
||||||
|
// If modulate is not specified, the existence of a texture on
|
||||||
|
// either color channel completely replaces the flat color.
|
||||||
|
if (color_def._has_texture) {
|
||||||
|
rgba[0] = 1.0f;
|
||||||
|
rgba[1] = 1.0f;
|
||||||
|
rgba[2] = 1.0f;
|
||||||
|
}
|
||||||
|
if (trans_def._has_texture) {
|
||||||
|
rgba[3] = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primitive.set_color(rgba);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShader::apply_texture_properties
|
||||||
|
// Access: Private
|
||||||
|
// Description: Applies all the appropriate texture properties to the
|
||||||
|
// EggTexture object, including wrap modes and texture
|
||||||
|
// matrix.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaToEggConverter::
|
||||||
|
apply_texture_properties(EggTexture &tex, const MayaShaderColorDef &color_def) {
|
||||||
|
// Let's mipmap all textures by default.
|
||||||
|
tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
|
||||||
|
tex.set_magfilter(EggTexture::FT_linear);
|
||||||
|
|
||||||
|
EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
|
||||||
|
EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
|
||||||
|
|
||||||
|
tex.set_wrap_u(wrap_u);
|
||||||
|
tex.set_wrap_v(wrap_v);
|
||||||
|
|
||||||
|
LMatrix3d mat = color_def.compute_texture_matrix();
|
||||||
|
if (!mat.almost_equal(LMatrix3d::ident_mat())) {
|
||||||
|
tex.set_transform(mat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaShader::compare_texture_properties
|
||||||
|
// Access: Private
|
||||||
|
// Description: Compares the texture properties already on the
|
||||||
|
// texture (presumably set by a previous call to
|
||||||
|
// apply_texture_properties()) and returns false if they
|
||||||
|
// differ from that specified by the indicated color_def
|
||||||
|
// object, or true if they match.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaToEggConverter::
|
||||||
|
compare_texture_properties(EggTexture &tex,
|
||||||
|
const MayaShaderColorDef &color_def) {
|
||||||
|
bool okflag = true;
|
||||||
|
|
||||||
|
EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
|
||||||
|
EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
|
||||||
|
|
||||||
|
if (wrap_u != tex.determine_wrap_u()) {
|
||||||
|
// Choose the more general of the two.
|
||||||
|
if (wrap_u == EggTexture::WM_repeat) {
|
||||||
|
tex.set_wrap_u(wrap_u);
|
||||||
|
}
|
||||||
|
okflag = false;
|
||||||
|
}
|
||||||
|
if (wrap_v != tex.determine_wrap_v()) {
|
||||||
|
if (wrap_v == EggTexture::WM_repeat) {
|
||||||
|
tex.set_wrap_v(wrap_v);
|
||||||
|
}
|
||||||
|
okflag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LMatrix3d mat = color_def.compute_texture_matrix();
|
||||||
|
if (!mat.almost_equal(tex.get_transform())) {
|
||||||
|
okflag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return okflag;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaShader::reparent_decals
|
// Function: MayaShader::reparent_decals
|
||||||
// Access: Public
|
// Access: Private
|
||||||
// Description: Recursively walks the egg hierarchy, reparenting
|
// Description: Recursively walks the egg hierarchy, reparenting
|
||||||
// "decal" type nodes below their corresponding
|
// "decal" type nodes below their corresponding
|
||||||
// "decalbase" type nodes, and setting the flags.
|
// "decalbase" type nodes, and setting the flags.
|
||||||
@ -1876,13 +2000,10 @@ reparent_decals(EggGroupNode *egg_parent) {
|
|||||||
// All the decal children get moved to be a child of decal base.
|
// All the decal children get moved to be a child of decal base.
|
||||||
// This usually will not affect the vertex positions, but it
|
// This usually will not affect the vertex positions, but it
|
||||||
// could if the decal base has a transform and the decal child
|
// could if the decal base has a transform and the decal child
|
||||||
// is an instance node. So don't do that. Also, we assume it's
|
// is an instance node. So don't do that.
|
||||||
// undesired to have a transform on a decal, so we flatten those
|
|
||||||
// out here--there's no real requirement to do this, however.
|
|
||||||
pvector<EggGroup *>::iterator di;
|
pvector<EggGroup *>::iterator di;
|
||||||
for (di = decal_children.begin(); di != decal_children.end(); ++di) {
|
for (di = decal_children.begin(); di != decal_children.end(); ++di) {
|
||||||
EggGroup *child_group = (*di);
|
EggGroup *child_group = (*di);
|
||||||
child_group->flatten_transforms();
|
|
||||||
decal_base->add_child(child_group);
|
decal_base->add_child(child_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ class EggVertexPool;
|
|||||||
class EggNurbsCurve;
|
class EggNurbsCurve;
|
||||||
class EggPrimitive;
|
class EggPrimitive;
|
||||||
class EggXfmSAnim;
|
class EggXfmSAnim;
|
||||||
|
class MayaShaderColorDef;
|
||||||
|
|
||||||
class MDagPath;
|
class MDagPath;
|
||||||
class MFnNurbsSurface;
|
class MFnNurbsSurface;
|
||||||
@ -119,6 +120,10 @@ private:
|
|||||||
JointAnim *get_egg_table(const string &name, EggGroupNode *egg_root);
|
JointAnim *get_egg_table(const string &name, EggGroupNode *egg_root);
|
||||||
void set_shader_attributes(EggPrimitive &primitive,
|
void set_shader_attributes(EggPrimitive &primitive,
|
||||||
const MayaShader &shader);
|
const MayaShader &shader);
|
||||||
|
void apply_texture_properties(EggTexture &tex,
|
||||||
|
const MayaShaderColorDef &color_def);
|
||||||
|
bool compare_texture_properties(EggTexture &tex,
|
||||||
|
const MayaShaderColorDef &color_def);
|
||||||
|
|
||||||
bool reparent_decals(EggGroupNode *egg_parent);
|
bool reparent_decals(EggGroupNode *egg_parent);
|
||||||
|
|
||||||
|
@ -167,32 +167,11 @@ copy_maya_file(const Filename &source, const Filename &dest,
|
|||||||
int num_shaders = _shaders.get_num_shaders();
|
int num_shaders = _shaders.get_num_shaders();
|
||||||
for (int i = 0; i < num_shaders; i++) {
|
for (int i = 0; i < num_shaders; i++) {
|
||||||
MayaShader *shader = _shaders.get_shader(i);
|
MayaShader *shader = _shaders.get_shader(i);
|
||||||
if (shader->_has_texture) {
|
if (!extract_texture(shader->_color, dir)) {
|
||||||
Filename texture_filename =
|
|
||||||
_path_replace->convert_path(shader->_texture);
|
|
||||||
if (!texture_filename.exists()) {
|
|
||||||
nout << "*** Warning: texture " << texture_filename
|
|
||||||
<< " does not exist.\n";
|
|
||||||
} else if (!texture_filename.is_regular_file()) {
|
|
||||||
nout << "*** Warning: texture " << texture_filename
|
|
||||||
<< " is not a regular file.\n";
|
|
||||||
} else {
|
|
||||||
ExtraData ed;
|
|
||||||
ed._type = FT_texture;
|
|
||||||
|
|
||||||
CVSSourceDirectory *texture_dir =
|
|
||||||
import(texture_filename, &ed, _map_dir);
|
|
||||||
if (texture_dir == (CVSSourceDirectory *)NULL) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!extract_texture(shader->_transparency, dir)) {
|
||||||
// Update the texture reference to point to the new texture
|
return false;
|
||||||
// filename, relative to the flt file. Not sure how to do
|
|
||||||
// this right now.
|
|
||||||
Filename new_filename = dir->get_rel_to(texture_dir) + "/" +
|
|
||||||
texture_filename.get_basename();
|
|
||||||
shader->reset_maya_texture(new_filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +215,46 @@ copy_maya_file(const Filename &source, const Filename &dest,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaCopy::extract_texture
|
||||||
|
// Access: Private
|
||||||
|
// Description: Gets the texture out of the indicated color channel
|
||||||
|
// and copies it in, updating the channel with the new
|
||||||
|
// texture filename. Returns true on success, false on
|
||||||
|
// failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaCopy::
|
||||||
|
extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir) {
|
||||||
|
if (color_def._has_texture) {
|
||||||
|
Filename texture_filename =
|
||||||
|
_path_replace->convert_path(color_def._texture);
|
||||||
|
if (!texture_filename.exists()) {
|
||||||
|
nout << "*** Warning: texture " << texture_filename
|
||||||
|
<< " does not exist.\n";
|
||||||
|
} else if (!texture_filename.is_regular_file()) {
|
||||||
|
nout << "*** Warning: texture " << texture_filename
|
||||||
|
<< " is not a regular file.\n";
|
||||||
|
} else {
|
||||||
|
ExtraData ed;
|
||||||
|
ed._type = FT_texture;
|
||||||
|
|
||||||
|
CVSSourceDirectory *texture_dir =
|
||||||
|
import(texture_filename, &ed, _map_dir);
|
||||||
|
if (texture_dir == (CVSSourceDirectory *)NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the texture reference to point to the new texture
|
||||||
|
// filename, relative to the maya file.
|
||||||
|
Filename new_filename = dir->get_rel_to(texture_dir) + "/" +
|
||||||
|
texture_filename.get_basename();
|
||||||
|
color_def.reset_maya_texture(new_filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaCopy::copy_texture
|
// Function: MayaCopy::copy_texture
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
|
||||||
class MayaShader;
|
class MayaShader;
|
||||||
|
class MayaShaderColorDef;
|
||||||
class MDagPath;
|
class MDagPath;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -63,6 +64,7 @@ private:
|
|||||||
|
|
||||||
bool copy_maya_file(const Filename &source, const Filename &dest,
|
bool copy_maya_file(const Filename &source, const Filename &dest,
|
||||||
CVSSourceDirectory *dir);
|
CVSSourceDirectory *dir);
|
||||||
|
bool extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir);
|
||||||
bool copy_texture(const Filename &source, const Filename &dest,
|
bool copy_texture(const Filename &source, const Filename &dest,
|
||||||
CVSSourceDirectory *dir);
|
CVSSourceDirectory *dir);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user