mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 00:32:57 -04:00
support projected textures
This commit is contained in:
parent
d72425f45d
commit
81006f1eb4
@ -43,6 +43,9 @@ MayaApi::
|
||||
MayaApi(const string &program_name) {
|
||||
// Beginning with Maya4.5, the call to initialize seems to change
|
||||
// the current directory! Yikes!
|
||||
|
||||
// Furthermore, the current directory may change during the call to
|
||||
// any Maya function! Egad!
|
||||
Filename cwd = ExecutionEnvironment::get_cwd();
|
||||
MStatus stat = MLibrary::initialize((char *)program_name.c_str());
|
||||
|
||||
@ -52,6 +55,11 @@ MayaApi(const string &program_name) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to restore current directory to " << cwd
|
||||
<< " after initializing Maya.\n";
|
||||
} else {
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug()
|
||||
<< "Restored current directory to " << cwd << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!stat) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "mayaShader.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "config_maya.h"
|
||||
#include "string_utils.h"
|
||||
#include "pset.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
@ -43,6 +44,7 @@ MayaShader(MObject engine) {
|
||||
_transparency = 0.0;
|
||||
|
||||
_has_texture = false;
|
||||
_projection_type = PT_off;
|
||||
|
||||
_coverage.set(1.0, 1.0);
|
||||
_translate_frame.set(0.0, 0.0);
|
||||
@ -114,6 +116,38 @@ compute_texture_matrix() const {
|
||||
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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexCoordd MayaShader::
|
||||
project_uv(const LPoint3d &point) const {
|
||||
switch (_projection_type) {
|
||||
case PT_planar:
|
||||
{
|
||||
LPoint3d p2d = point * _projection_matrix;
|
||||
return TexCoordd(p2d[0], p2d[1]);
|
||||
//return TexCoordd((p2d[0] + 1.0) / 2.0, (p2d[1] + 1.0) / 2.0);
|
||||
}
|
||||
|
||||
default:
|
||||
return TexCoordd(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MayaShader::output
|
||||
// Access: Public
|
||||
@ -168,7 +202,7 @@ reset_maya_texture(const Filename &texture) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MayaShader::read_surface_shader
|
||||
// Access: Public
|
||||
// Access: Private
|
||||
// Description: Extracts out the shading information from the Maya
|
||||
// surface shader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -196,6 +230,19 @@ read_surface_shader(MObject shader) {
|
||||
}
|
||||
}
|
||||
|
||||
// Or maybe a connection to outColor. Not sure how this differs
|
||||
// from just color, but empirically it seems that either might be
|
||||
// used.
|
||||
MPlug out_color_plug = shader_fn.findPlug("outColor");
|
||||
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++) {
|
||||
read_surface_color(color_pa[0].node());
|
||||
}
|
||||
}
|
||||
|
||||
// Also try to get the ordinary color directly from the surface
|
||||
// shader.
|
||||
if (shader.hasFn(MFn::kLambert)) {
|
||||
@ -218,16 +265,15 @@ read_surface_shader(MObject shader) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MayaShader::read_surface_color
|
||||
// Access: Public
|
||||
// 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) {
|
||||
_color_object = new 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) {
|
||||
@ -247,6 +293,29 @@ read_surface_color(MObject color) {
|
||||
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();
|
||||
}
|
||||
|
||||
string type;
|
||||
if (get_enum_attribute(color, "projType", type)) {
|
||||
set_projection_type(type);
|
||||
}
|
||||
|
||||
} else {
|
||||
// This shader wasn't understood.
|
||||
if (maya_cat.is_debug()) {
|
||||
@ -266,3 +335,29 @@ read_surface_color(MObject color) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
|
||||
// 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, 0.5, 0.0,
|
||||
0.5, 0.5, 0.0, 1.0);
|
||||
|
||||
} else {
|
||||
// Other projection types are currently unimplemented by the
|
||||
// converter.
|
||||
maya_cat.error()
|
||||
<< "Don't know how to handle type " << type << " projections.\n";
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
~MayaShader();
|
||||
|
||||
LMatrix3d compute_texture_matrix() const;
|
||||
bool has_projection() const;
|
||||
TexCoordd project_uv(const LPoint3d &point) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
bool reset_maya_texture(const Filename &texture);
|
||||
@ -53,6 +55,20 @@ public:
|
||||
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;
|
||||
|
||||
LVector2f _coverage;
|
||||
LVector2f _translate_frame;
|
||||
double _rotate_frame;
|
||||
@ -71,6 +87,7 @@ private:
|
||||
|
||||
bool read_surface_shader(MObject shader);
|
||||
void read_surface_color(MObject color);
|
||||
void set_projection_type(const string &type);
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const MayaShader &shader) {
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <maya/MFnAttribute.h>
|
||||
#include <maya/MFnTypedAttribute.h>
|
||||
#include <maya/MFnEnumAttribute.h>
|
||||
#include <maya/MFnMatrixData.h>
|
||||
#include <maya/MMatrix.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -66,6 +68,29 @@ get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: has_attribute
|
||||
// Description: Returns true if the node has the indicated attribute,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
has_attribute(MObject &node, const string &attribute_name) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
node_fn.attribute(attribute_name.c_str(), &status);
|
||||
if (!status) {
|
||||
// No such attribute.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_bool_attribute
|
||||
// Description: Extracts the named boolean attribute from the
|
||||
@ -74,6 +99,12 @@ get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
|
||||
bool
|
||||
get_bool_attribute(MObject &node, const string &attribute_name,
|
||||
bool &value) {
|
||||
if (!has_attribute(node, attribute_name)) {
|
||||
// For bool attributes only, we assume if the attribute is absent
|
||||
// it's the same thing as being false.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!get_maya_attribute(node, attribute_name, value)) {
|
||||
maya_cat.error()
|
||||
<< "Attribute " << attribute_name
|
||||
@ -178,6 +209,36 @@ get_vec2d_attribute(MObject &node, const string &attribute_name,
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_mat4d_attribute
|
||||
// Description: Extracts the named 4x4 matrix from the MObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
get_mat4d_attribute(MObject &node, const string &attribute_name,
|
||||
LMatrix4d &value) {
|
||||
MStatus status;
|
||||
MObject matrix;
|
||||
if (!get_maya_attribute(node, attribute_name, matrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnMatrixData matrix_data(matrix, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< node.apiTypeStr() << ", not a Matrix.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const MMatrix &mat = matrix_data.matrix();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
value(i, j) = mat(i, j);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_enum_attribute
|
||||
// Description: Extracts the enum attribute from the MObject as a
|
||||
|
@ -48,6 +48,9 @@ bool
|
||||
set_maya_attribute(MObject &node, const string &attribute_name,
|
||||
ValueType &value);
|
||||
|
||||
bool
|
||||
has_attribute(MObject &node, const string &attribute_name);
|
||||
|
||||
bool
|
||||
get_bool_attribute(MObject &node, const string &attribute_name,
|
||||
bool &value);
|
||||
@ -64,6 +67,10 @@ bool
|
||||
get_vec2d_attribute(MObject &node, const string &attribute_name,
|
||||
LVecBase2d &value);
|
||||
|
||||
bool
|
||||
get_mat4d_attribute(MObject &node, const string &attribute_name,
|
||||
LMatrix4d &value);
|
||||
|
||||
bool
|
||||
get_enum_attribute(MObject &node, const string &attribute_name,
|
||||
string &value);
|
||||
|
@ -1209,12 +1209,29 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||
|
||||
egg_poly->set_bface_flag(double_sided);
|
||||
|
||||
// Determine the shader for this particular polygon.
|
||||
MayaShader *shader = NULL;
|
||||
int index = pi.index();
|
||||
nassertv(index >= 0 && index < (int)poly_shader_indices.length());
|
||||
int shader_index = poly_shader_indices[index];
|
||||
if (shader_index != -1) {
|
||||
nassertv(shader_index >= 0 && shader_index < (int)shaders.length());
|
||||
MObject engine = shaders[shader_index];
|
||||
shader =
|
||||
_shaders.find_shader_for_shading_engine(engine);
|
||||
|
||||
} else if (default_shader != (MayaShader *)NULL) {
|
||||
shader = default_shader;
|
||||
}
|
||||
|
||||
// Get the vertices for the polygon.
|
||||
long num_verts = pi.polygonVertexCount();
|
||||
for (long i = 0; i < num_verts; i++) {
|
||||
EggVertex vert;
|
||||
|
||||
MPoint p = pi.point(i, MSpace::kWorld);
|
||||
vert.set_pos(LPoint3d(p[0], p[1], p[2]));
|
||||
LPoint3d p3d(p[0], p[1], p[2]);
|
||||
vert.set_pos(p3d);
|
||||
|
||||
MVector n;
|
||||
status = pi.getNormal(i, n, MSpace::kWorld);
|
||||
@ -1224,7 +1241,13 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||
vert.set_normal(LVector3d(n[0], n[1], n[2]));
|
||||
}
|
||||
|
||||
if (pi.hasUVs()) {
|
||||
if (shader->has_projection()) {
|
||||
// If the shader has a projection, use it instead of the
|
||||
// polygon's built-in UV's.
|
||||
vert.set_uv(shader->project_uv(p3d));
|
||||
|
||||
} else if (pi.hasUVs()) {
|
||||
// Get the UV's from the polygon.
|
||||
float2 uvs;
|
||||
status = pi.getUV(i, uvs);
|
||||
if (!status) {
|
||||
@ -1249,21 +1272,9 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||
egg_poly->add_vertex(vpool->create_unique_vertex(vert));
|
||||
}
|
||||
|
||||
// Determine the shader for this particular polygon.
|
||||
int index = pi.index();
|
||||
nassertv(index >= 0 && index < (int)poly_shader_indices.length());
|
||||
int shader_index = poly_shader_indices[index];
|
||||
if (shader_index != -1) {
|
||||
nassertv(shader_index >= 0 && shader_index < (int)shaders.length());
|
||||
MObject engine = shaders[shader_index];
|
||||
MayaShader *shader =
|
||||
_shaders.find_shader_for_shading_engine(engine);
|
||||
if (shader != (MayaShader *)NULL) {
|
||||
set_shader_attributes(*egg_poly, *shader);
|
||||
}
|
||||
|
||||
} else if (default_shader != (MayaShader *)NULL) {
|
||||
set_shader_attributes(*egg_poly, *default_shader);
|
||||
// Now apply the shader.
|
||||
if (shader != (MayaShader *)NULL) {
|
||||
set_shader_attributes(*egg_poly, *shader);
|
||||
}
|
||||
|
||||
pi.next();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "mayaToEgg.h"
|
||||
#include "mayaToEggConverter.h"
|
||||
#include "config_mayaegg.h"
|
||||
#include "config_maya.h" // for maya_cat
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MayaToEgg::Constructor
|
||||
@ -78,13 +79,20 @@ void MayaToEgg::
|
||||
run() {
|
||||
// Set the verbose level by using Notify.
|
||||
if (_verbose >= 3) {
|
||||
maya_cat->set_severity(NS_spam);
|
||||
mayaegg_cat->set_severity(NS_spam);
|
||||
} else if (_verbose >= 2) {
|
||||
maya_cat->set_severity(NS_debug);
|
||||
mayaegg_cat->set_severity(NS_debug);
|
||||
} else if (_verbose >= 1) {
|
||||
maya_cat->set_severity(NS_info);
|
||||
mayaegg_cat->set_severity(NS_info);
|
||||
}
|
||||
|
||||
// Let's open the output file before we initialize Maya, since Maya
|
||||
// now has a nasty habit of changing the current directory.
|
||||
get_output();
|
||||
|
||||
nout << "Initializing Maya.\n";
|
||||
MayaToEggConverter converter(_program_name);
|
||||
if (!converter.open_api()) {
|
||||
|
@ -17,8 +17,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "withOutputFile.h"
|
||||
#include "executionEnvironment.h"
|
||||
|
||||
#include <notify.h>
|
||||
#include "notify.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WithOutputFile::Constructor
|
||||
|
Loading…
x
Reference in New Issue
Block a user