Skip to content

Commit 19ddfa1

Browse files
committed
fix several coordinate system issues
1 parent ea3b967 commit 19ddfa1

File tree

8 files changed

+93
-32
lines changed

8 files changed

+93
-32
lines changed

panda/src/distort/cylindricalLens.cxx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ do_extrude(const Lens::CData *lens_cdata,
6969
// And we'll need to account for the lens's rotations, etc. at the
7070
// end of the day.
7171
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
72+
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
7273

73-
near_point = (v * do_get_near(lens_cdata)) * lens_mat;
74-
far_point = (v * do_get_far(lens_cdata)) * lens_mat;
74+
near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
75+
far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
7576
return true;
7677
}
7778

@@ -106,7 +107,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
106107
PN_stdfloat sinAngle, cosAngle;
107108
csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
108109

109-
vec = LVector3(sinAngle, cosAngle, 0.0f) * do_get_lens_mat(lens_cdata);
110+
vec = LVector3(sinAngle, cosAngle, 0.0f) * do_get_projection_mat_inv(lens_cdata) * do_get_lens_mat(lens_cdata);
110111

111112
return true;
112113
}
@@ -131,7 +132,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
131132
bool CylindricalLens::
132133
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
133134
// First, account for any rotations, etc. on the lens.
134-
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata);
135+
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
135136

136137
// To compute the x position on the frame, we only need to consider
137138
// the angle of the vector about the Z axis. Project the vector

panda/src/distort/fisheyeLens.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ do_extrude(const Lens::CData *lens_cdata,
101101
// And we'll need to account for the lens's rotations, etc. at the
102102
// end of the day.
103103
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
104+
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
104105

105-
near_point = (v * do_get_near(lens_cdata)) * lens_mat;
106-
far_point = (v * do_get_far(lens_cdata)) * lens_mat;
106+
near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
107+
far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
107108
return true;
108109
}
109110

@@ -159,7 +160,7 @@ do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &
159160
bool FisheyeLens::
160161
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
161162
// First, account for any rotations, etc. on the lens.
162-
LVector3 v2 = point3d * do_get_lens_mat_inv(lens_cdata);
163+
LVector3 v2 = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
163164

164165
// A fisheye lens projection has the property that the distance from
165166
// the center point to any other point on the projection is

panda/src/distort/oSphereLens.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ do_extrude(const Lens::CData *lens_cdata,
7474
// And we'll need to account for the lens's rotations, etc. at the
7575
// end of the day.
7676
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
77+
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
7778

78-
near_point = near_point * lens_mat;
79-
far_point = far_point * lens_mat;
79+
near_point = near_point * proj_inv_mat * lens_mat;
80+
far_point = far_point * proj_inv_mat * lens_mat;
8081
return true;
8182
}
8283

@@ -100,7 +101,7 @@ do_extrude(const Lens::CData *lens_cdata,
100101
bool OSphereLens::
101102
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
102103
// First, account for any rotations, etc. on the lens.
103-
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata);
104+
LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
104105
PN_stdfloat dist = p.length();
105106
if (dist == 0.0f) {
106107
point2d.set(0.0f, 0.0f, 0.0f);

panda/src/distort/pSphereLens.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ do_extrude(const Lens::CData *lens_cdata,
6767
// And we'll need to account for the lens's rotations, etc. at the
6868
// end of the day.
6969
const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata);
70+
const LMatrix4 &proj_inv_mat = do_get_projection_mat_inv(lens_cdata);
7071

71-
near_point = (v * do_get_near(lens_cdata)) * lens_mat;
72-
far_point = (v * do_get_far(lens_cdata)) * lens_mat;
72+
near_point = (v * do_get_near(lens_cdata)) * proj_inv_mat * lens_mat;
73+
far_point = (v * do_get_far(lens_cdata)) * proj_inv_mat * lens_mat;
7374
return true;
7475
}
7576

@@ -93,7 +94,7 @@ do_extrude(const Lens::CData *lens_cdata,
9394
bool PSphereLens::
9495
do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const {
9596
// First, account for any rotations, etc. on the lens.
96-
LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata);
97+
LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata) * do_get_projection_mat(lens_cdata);
9798
PN_stdfloat dist = v3.length();
9899
if (dist == 0.0f) {
99100
point2d.set(0.0f, 0.0f, 0.0f);

panda/src/gobj/lens.cxx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,16 +1527,29 @@ do_compute_view_vector(CData *cdata) {
15271527
// point to 2-d point, if the lens is linear.
15281528
////////////////////////////////////////////////////////////////////
15291529
void Lens::
1530-
do_compute_projection_mat(CData *cdata) {
1531-
cdata->_projection_mat =
1532-
cdata->_projection_mat_left =
1533-
cdata->_projection_mat_right =
1534-
cdata->_projection_mat_inv =
1535-
cdata->_projection_mat_left_inv =
1536-
cdata->_projection_mat_right_inv =
1537-
LMatrix4::ident_mat();
1538-
do_adjust_comp_flags(cdata, 0, CF_projection_mat | CF_projection_mat_inv |
1539-
CF_projection_mat_left_inv |CF_projection_mat_right_inv);
1530+
do_compute_projection_mat(CData *lens_cdata) {
1531+
// This is the implementation used by non-linear lenses. The linear
1532+
// lenses (PerspectiveLens and OrthographicLens) will customize this
1533+
// method appropriate for themselves.
1534+
1535+
// By convention, the coordinate-system conversion is baked into the
1536+
// projection mat. Our non-linear lenses are implemented with code
1537+
// that assumes CS_zup_right, so we bake the appropriate rotation in
1538+
// here.
1539+
CoordinateSystem cs = lens_cdata->_cs;
1540+
if (cs == CS_default) {
1541+
cs = get_default_coordinate_system();
1542+
}
1543+
lens_cdata->_projection_mat = LMatrix4::convert_mat(cs, CS_zup_right);
1544+
lens_cdata->_projection_mat_inv = LMatrix4::convert_mat(CS_zup_right, cs);
1545+
1546+
// We don't apply any left/right offsets for non-linear lenses by
1547+
// default, at least not here in the projection matrix.
1548+
lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat;
1549+
lens_cdata->_projection_mat_left_inv = lens_cdata->_projection_mat_right_inv = lens_cdata->_projection_mat_inv;
1550+
1551+
do_adjust_comp_flags(lens_cdata, 0, CF_projection_mat | CF_projection_mat_inv |
1552+
CF_projection_mat_left_inv | CF_projection_mat_right_inv);
15401553
}
15411554

15421555
////////////////////////////////////////////////////////////////////

panda/src/grutil/pfmFile.cxx

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -726,12 +726,45 @@ compute_planar_bounds(const LPoint2 &center, PN_stdfloat point_dist, PN_stdfloat
726726
}
727727
}
728728
}
729-
730-
PT(BoundingHexahedron) bounds = new BoundingHexahedron
731-
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
732-
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
733-
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
734-
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
729+
730+
PT(BoundingHexahedron) bounds;
731+
732+
// We create a BoundingHexahedron with the points in a particular
733+
// well-defined order, based on the current coordinate system.
734+
CoordinateSystem cs = get_default_coordinate_system();
735+
switch (cs) {
736+
case CS_yup_right:
737+
bounds = new BoundingHexahedron
738+
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
739+
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
740+
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
741+
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
742+
break;
743+
744+
case CS_zup_right:
745+
bounds = new BoundingHexahedron
746+
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
747+
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
748+
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
749+
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
750+
break;
751+
752+
case CS_yup_left:
753+
bounds = new BoundingHexahedron
754+
(LPoint3(max_x, min_y, max_z), LPoint3(min_x, min_y, max_z),
755+
LPoint3(max_x, max_y, max_z), LPoint3(min_x, max_y, max_z),
756+
LPoint3(max_x, min_y, min_z), LPoint3(min_x, min_y, min_z),
757+
LPoint3(max_x, max_y, min_z), LPoint3(min_x, max_y, min_z));
758+
break;
759+
760+
case CS_zup_left:
761+
bounds = new BoundingHexahedron
762+
(LPoint3(max_x, max_y, min_z), LPoint3(min_x, max_y, min_z),
763+
LPoint3(max_x, max_y, max_z), LPoint3(min_x, max_y, max_z),
764+
LPoint3(max_x, min_y, min_z), LPoint3(min_x, min_y, min_z),
765+
LPoint3(max_x, min_y, max_z), LPoint3(min_x, min_y, max_z));
766+
break;
767+
}
735768

736769
// Rotate the bounding volume back into the original space of the
737770
// screen.
@@ -885,6 +918,12 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
885918
return;
886919
}
887920

921+
bool reverse_normals = inverted;
922+
bool reverse_faces = inverted;
923+
if (!is_right_handed(get_default_coordinate_system())) {
924+
reverse_faces = !reverse_faces;
925+
}
926+
888927
// This is the max number of vertex indices we might add to the
889928
// GeomTriangles. (We might actually add fewer than this due to
890929
// omitting the occasional missing data point.)
@@ -1025,7 +1064,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
10251064
}
10261065
n.normalize();
10271066
nassertv(!n.is_nan());
1028-
if (inverted) {
1067+
if (reverse_normals) {
10291068
n = -n;
10301069
}
10311070
normal.add_data3(n);
@@ -1062,7 +1101,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
10621101
int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
10631102
int vi3 = ((xi0 + 1) + (yi0) * x_size);
10641103

1065-
if (inverted) {
1104+
if (reverse_faces) {
10661105
tris->add_vertices(vi2, vi0, vi1);
10671106
tris->close_primitive();
10681107

panda/src/linmath/lquaternion_src.cxx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ set_hpr(const FLOATNAME(LVecBase3) &hpr, CoordinateSystem cs) {
102102
csincos(a, &s, &c);
103103
quat_r.set(c, v[0] * s, v[1] * s, v[2] * s);
104104

105-
(*this) = quat_r * quat_p * quat_h;
105+
if (is_right_handed(cs)) {
106+
(*this) = quat_r * quat_p * quat_h;
107+
} else {
108+
(*this) = invert(quat_h * quat_p * quat_r);
109+
}
106110

107111
if (!temp_hpr_fix) {
108112
// Compute the old, broken hpr.

panda/src/linmath/lvector3_src.I

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ rfu(FLOATTYPE right_v, FLOATTYPE fwd_v, FLOATTYPE up_v,
474474
case CS_zup_left:
475475
vy = -fwd_v;
476476
vz = up_v;
477+
break;
477478

478479
default:
479480
linmath_cat.error()

0 commit comments

Comments
 (0)