Browse Source

fix several coordinate system issues

David Rose 13 years ago
parent
commit
19ddfa1ba2

+ 5 - 4
panda/src/distort/cylindricalLens.cxx

@@ -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;
-  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;
   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

+ 4 - 3
panda/src/distort/fisheyeLens.cxx

@@ -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;
-  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;
   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

+ 4 - 3
panda/src/distort/oSphereLens.cxx

@@ -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;
-  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;
   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);

+ 4 - 3
panda/src/distort/pSphereLens.cxx

@@ -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;
-  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;
   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);

+ 23 - 10
panda/src/gobj/lens.cxx

@@ -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) {
-  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);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 47 - 8
panda/src/grutil/pfmFile.cxx

@@ -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
   // 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();
             
             

+ 5 - 1
panda/src/linmath/lquaternion_src.cxx

@@ -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.

+ 1 - 0
panda/src/linmath/lvector3_src.I

@@ -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()