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
// end of the day.
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;
far_point = (v * do_get_far(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)) * proj_inv_mat * lens_mat;
return true;
}
@ -106,7 +107,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
PN_stdfloat 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;
}
@ -131,7 +132,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
bool CylindricalLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// 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
// 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
// end of the day.
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;
far_point = (v * do_get_far(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)) * proj_inv_mat * lens_mat;
return true;
}
@ -159,7 +160,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
bool FisheyeLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// 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
// 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
// end of the day.
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;
far_point = far_point * lens_mat;
near_point = near_point * proj_inv_mat * lens_mat;
far_point = far_point * proj_inv_mat * lens_mat;
return true;
}
@ -100,7 +101,7 @@ do_extrude(const Lens::CData *lens_cdata,
bool OSphereLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// 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();
if (dist == 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
// end of the day.
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;
far_point = (v * do_get_far(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)) * proj_inv_mat * lens_mat;
return true;
}
@ -93,7 +94,7 @@ do_extrude(const Lens::CData *lens_cdata,
bool PSphereLens::
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
// 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();
if (dist == 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.
////////////////////////////////////////////////////////////////////
void Lens::
do_compute_projection_mat(CData *cdata) {
cdata->_projection_mat =
cdata->_projection_mat_left =
cdata->_projection_mat_right =
cdata->_projection_mat_inv =
cdata->_projection_mat_left_inv =
cdata->_projection_mat_right_inv =
LMatrix4::ident_mat();
do_adjust_comp_flags(cdata, 0, CF_projection_mat | CF_projection_mat_inv |
CF_projection_mat_left_inv |CF_projection_mat_right_inv);
do_compute_projection_mat(CData *lens_cdata) {
// This is the implementation used by non-linear lenses. The linear
// lenses (PerspectiveLens and OrthographicLens) will customize this
// method appropriate for themselves.
// By convention, the coordinate-system conversion is baked into the
// projection mat. Our non-linear lenses are implemented with code
// that assumes CS_zup_right, so we bake the appropriate rotation in
// here.
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
(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));
PT(BoundingHexahedron) bounds;
// We create a BoundingHexahedron with the points in a particular
// well-defined order, based on the current coordinate system.
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
// screen.
@ -885,6 +918,12 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
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
// GeomTriangles. (We might actually add fewer than this due to
// omitting the occasional missing data point.)
@ -1025,7 +1064,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
}
n.normalize();
nassertv(!n.is_nan());
if (inverted) {
if (reverse_normals) {
n = -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 vi3 = ((xi0 + 1) + (yi0) * x_size);
if (inverted) {
if (reverse_faces) {
tris->add_vertices(vi2, vi0, vi1);
tris->close_primitive();

View File

@ -102,7 +102,11 @@ set_hpr(const FLOATNAME(LVecBase3) &hpr, CoordinateSystem cs) {
csincos(a, &s, &c);
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) {
// 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:
vy = -fwd_v;
vz = up_v;
break;
default:
linmath_cat.error()