fix several coordinate system issues

This commit is contained in:
David Rose 2012-03-14 16:29:05 +00:00
parent ea3b967f8a
commit 19ddfa1ba2
8 changed files with 93 additions and 32 deletions

View File

@ -69,9 +69,10 @@ do_extrude(const Lens::CData *lens_cdata,
// And we'll need to account for the lens's rotations, etc. at the // And we'll need to account for the lens's rotations, etc. at the
// end of the day. // end of the day.
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
near_point = (v * do_get_near(lens_cdata)) * lens_mat; near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
far_point = (v * do_get_far(lens_cdata)) * lens_mat; far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
return true; return true;
} }
@ -106,7 +107,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
PN_stdfloat sinAngle, cosAngle; PN_stdfloat sinAngle, cosAngle;
csincos(deg_2_rad(angle), &sinAngle, &cosAngle); csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
vec = LVector3(sinAngle, cosAngle, 0.0f) * do_get_lens_mat(lens_cdata); vec = LVector3(sinAngle, cosAngle, 0.0f) * do_get_projection_mat_inv(lens_cdata) * do_get_lens_mat(lens_cdata);
return true; return true;
} }
@ -131,7 +132,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
bool CylindricalLens:: bool CylindricalLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// First, account for any rotations, etc. on the lens. // First, account for any rotations, etc. on the lens.
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata); LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
// To compute the x position on the frame, we only need to consider // To compute the x position on the frame, we only need to consider
// the angle of the vector about the Z axis. Project the vector // the angle of the vector about the Z axis. Project the vector

View File

@ -101,9 +101,10 @@ do_extrude(const Lens::CData *lens_cdata,
// And we'll need to account for the lens's rotations, etc. at the // And we'll need to account for the lens's rotations, etc. at the
// end of the day. // end of the day.
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
near_point = (v * do_get_near(lens_cdata)) * lens_mat; near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
far_point = (v * do_get_far(lens_cdata)) * lens_mat; far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
return true; return true;
} }
@ -159,7 +160,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
bool FisheyeLens:: bool FisheyeLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// First, account for any rotations, etc. on the lens. // First, account for any rotations, etc. on the lens.
LVector3 v2 = point3d * do_get_lens_mat_inv(lens_cdata); LVector3 v2 = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
// A fisheye lens projection has the property that the distance from // A fisheye lens projection has the property that the distance from
// the center point to any other point on the projection is // the center point to any other point on the projection is

View File

@ -74,9 +74,10 @@ do_extrude(const Lens::CData *lens_cdata,
// And we'll need to account for the lens's rotations, etc. at the // And we'll need to account for the lens's rotations, etc. at the
// end of the day. // end of the day.
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
near_point = near_point * lens_mat; near_point = near_point * proj_inv_mat * lens_mat;
far_point = far_point * lens_mat; far_point = far_point * proj_inv_mat * lens_mat;
return true; return true;
} }
@ -100,7 +101,7 @@ do_extrude(const Lens::CData *lens_cdata,
bool OSphereLens:: bool OSphereLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// First, account for any rotations, etc. on the lens. // First, account for any rotations, etc. on the lens.
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata); LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
PN_stdfloat dist = p.length(); PN_stdfloat dist = p.length();
if (dist == 0.0f) { if (dist == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f); point2d.set(0.0f, 0.0f, 0.0f);

View File

@ -67,9 +67,10 @@ do_extrude(const Lens::CData *lens_cdata,
// And we'll need to account for the lens's rotations, etc. at the // And we'll need to account for the lens's rotations, etc. at the
// end of the day. // end of the day.
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
near_point = (v * do_get_near(lens_cdata)) * lens_mat; near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
far_point = (v * do_get_far(lens_cdata)) * lens_mat; far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
return true; return true;
} }
@ -93,7 +94,7 @@ do_extrude(const Lens::CData *lens_cdata,
bool PSphereLens:: bool PSphereLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// First, account for any rotations, etc. on the lens. // First, account for any rotations, etc. on the lens.
LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata); LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
PN_stdfloat dist = v3.length(); PN_stdfloat dist = v3.length();
if (dist == 0.0f) { if (dist == 0.0f) {
point2d.set(0.0f, 0.0f, 0.0f); point2d.set(0.0f, 0.0f, 0.0f);

View File

@ -1527,16 +1527,29 @@ do_compute_view_vector(CData *cdata) {
// point to 2-d point, if the lens is linear. // point to 2-d point, if the lens is linear.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Lens:: void Lens::
do_compute_projection_mat(CData *cdata) { do_compute_projection_mat(CData *lens_cdata) {
cdata->_projection_mat = // This is the implementation used by non-linear lenses. The linear
cdata->_projection_mat_left = // lenses (PerspectiveLens and OrthographicLens) will customize this
cdata->_projection_mat_right = // method appropriate for themselves.
cdata->_projection_mat_inv =
cdata->_projection_mat_left_inv = // By convention, the coordinate-system conversion is baked into the
cdata->_projection_mat_right_inv = // projection mat. Our non-linear lenses are implemented with code
LMatrix4::ident_mat(); // that assumes CS_zup_right, so we bake the appropriate rotation in
do_adjust_comp_flags(cdata, 0, CF_projection_mat | CF_projection_mat_inv | // here.
CF_projection_mat_left_inv |CF_projection_mat_right_inv); CoordinateSystem cs = lens_cdata->_cs;
if (cs == CS_default) {
cs = get_default_coordinate_system();
}
lens_cdata->_projection_mat = LMatrix4::convert_mat(cs, CS_zup_right);
lens_cdata->_projection_mat_inv = LMatrix4::convert_mat(CS_zup_right, cs);
// We don't apply any left/right offsets for non-linear lenses by
// default, at least not here in the projection matrix.
lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat;
lens_cdata->_projection_mat_left_inv = lens_cdata->_projection_mat_right_inv = lens_cdata->_projection_mat_inv;
do_adjust_comp_flags(lens_cdata, 0, CF_projection_mat | CF_projection_mat_inv |
CF_projection_mat_left_inv | CF_projection_mat_right_inv);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -726,12 +726,45 @@ compute_planar_bounds(const LPoint2 &center, PN_stdfloat point_dist, PN_stdfloat
} }
} }
} }
PT(BoundingHexahedron) bounds = new BoundingHexahedron PT(BoundingHexahedron) bounds;
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z), // We create a BoundingHexahedron with the points in a particular
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z), // well-defined order, based on the current coordinate system.
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z)); CoordinateSystem cs = get_default_coordinate_system();
switch (cs) {
case CS_yup_right:
bounds = new BoundingHexahedron
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
break;
case CS_zup_right:
bounds = new BoundingHexahedron
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
break;
case CS_yup_left:
bounds = new BoundingHexahedron
(LPoint3(max_x, min_y, max_z), LPoint3(min_x, min_y, max_z),
LPoint3(max_x, max_y, max_z), LPoint3(min_x, max_y, max_z),
LPoint3(max_x, min_y, min_z), LPoint3(min_x, min_y, min_z),
LPoint3(max_x, max_y, min_z), LPoint3(min_x, max_y, min_z));
break;
case CS_zup_left:
bounds = new BoundingHexahedron
(LPoint3(max_x, max_y, min_z), LPoint3(min_x, max_y, min_z),
LPoint3(max_x, max_y, max_z), LPoint3(min_x, max_y, max_z),
LPoint3(max_x, min_y, min_z), LPoint3(min_x, min_y, min_z),
LPoint3(max_x, min_y, max_z), LPoint3(min_x, min_y, max_z));
break;
}
// Rotate the bounding volume back into the original space of the // Rotate the bounding volume back into the original space of the
// screen. // screen.
@ -885,6 +918,12 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
return; return;
} }
bool reverse_normals = inverted;
bool reverse_faces = inverted;
if (!is_right_handed(get_default_coordinate_system())) {
reverse_faces = !reverse_faces;
}
// This is the max number of vertex indices we might add to the // This is the max number of vertex indices we might add to the
// GeomTriangles. (We might actually add fewer than this due to // GeomTriangles. (We might actually add fewer than this due to
// omitting the occasional missing data point.) // omitting the occasional missing data point.)
@ -1025,7 +1064,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
} }
n.normalize(); n.normalize();
nassertv(!n.is_nan()); nassertv(!n.is_nan());
if (inverted) { if (reverse_normals) {
n = -n; n = -n;
} }
normal.add_data3(n); normal.add_data3(n);
@ -1062,7 +1101,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size); int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
int vi3 = ((xi0 + 1) + (yi0) * x_size); int vi3 = ((xi0 + 1) + (yi0) * x_size);
if (inverted) { if (reverse_faces) {
tris->add_vertices(vi2, vi0, vi1); tris->add_vertices(vi2, vi0, vi1);
tris->close_primitive(); tris->close_primitive();

View File

@ -102,7 +102,11 @@ set_hpr(const FLOATNAME(LVecBase3) &hpr, CoordinateSystem cs) {
csincos(a, &s, &c); csincos(a, &s, &c);
quat_r.set(c, v[0] * s, v[1] * s, v[2] * s); quat_r.set(c, v[0] * s, v[1] * s, v[2] * s);
(*this) = quat_r * quat_p * quat_h; if (is_right_handed(cs)) {
(*this) = quat_r * quat_p * quat_h;
} else {
(*this) = invert(quat_h * quat_p * quat_r);
}
if (!temp_hpr_fix) { if (!temp_hpr_fix) {
// Compute the old, broken hpr. // Compute the old, broken hpr.

View File

@ -474,6 +474,7 @@ rfu(FLOATTYPE right_v, FLOATTYPE fwd_v, FLOATTYPE up_v,
case CS_zup_left: case CS_zup_left:
vy = -fwd_v; vy = -fwd_v;
vz = up_v; vz = up_v;
break;
default: default:
linmath_cat.error() linmath_cat.error()