mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
implement cylindrical projections
This commit is contained in:
parent
aba3ea8430
commit
38057f46b2
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user