implement cylindrical projections

This commit is contained in:
David Rose 2003-03-13 17:29:41 +00:00
parent aba3ea8430
commit 38057f46b2
3 changed files with 50 additions and 8 deletions

View File

@ -131,16 +131,39 @@ has_projection() const {
// 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.
// 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 &point) const {
project_uv(const LPoint3d &point, const LPoint3d &ref_point) const {
LPoint3d p = point * _projection_matrix;
switch (_projection_type) {
case PT_planar:
return TexCoordd(p[0], p[1]);
case PT_cylindrical:
{
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);
LPoint3d rp = ref_point * _projection_matrix;
TexCoordd uv
(// The u position is the angle about the Y axis, scaled to 0 .. 1.
catan2(p[0], p[2]) / (2.0 * MathNumbers::pi) + 0.5,
// The v position is the Y height.
p[1]);
// Also convert the reference point, so we can adjust the
// quadrant if necessary; each single polygon should only go the
// short way around the cylinder.
double ref_u = catan2(rp[0], rp[1]) / (2.0 * MathNumbers::pi) + 0.5;
if (uv[0] - ref_u > 0.5) {
uv[0] -= 1.0;
} else if (uv[0] - ref_u < -0.5) {
uv[0] += 1.0;
}
return uv;
}
default:
@ -351,9 +374,19 @@ set_projection_type(const string &type) {
// 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.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;
// 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 {
// Other projection types are currently unimplemented by the
// converter.

View File

@ -41,7 +41,7 @@ public:
LMatrix3d compute_texture_matrix() const;
bool has_projection() const;
TexCoordd project_uv(const LPoint3d &point) const;
TexCoordd project_uv(const LPoint3d &point, const LPoint3d &ref_point) const;
void output(ostream &out) const;
bool reset_maya_texture(const Filename &texture);

View File

@ -1309,11 +1309,20 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
// Get the vertices for the polygon.
long num_verts = pi.polygonVertexCount();
LPoint3d ref_p3d;
for (long i = 0; i < num_verts; i++) {
EggVertex vert;
MPoint p = pi.point(i, MSpace::kWorld);
LPoint3d p3d(p[0], p[1], p[2]);
if (i == 0) {
// Save the first vertex of the polygon as a reference point
// for sealing up seams that might be introduced by a UV
// projection, so we can ensure that all the vertices are
// projected into the same quadrant.
ref_p3d = p3d;
}
vert.set_pos(p3d);
MVector n;
@ -1327,7 +1336,7 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
if (shader != (MayaShader *)NULL && 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));
vert.set_uv(shader->project_uv(p3d, ref_p3d));
} else if (pi.hasUVs()) {
// Get the UV's from the polygon.