Browse Source

add OSphereLens

David Rose 14 years ago
parent
commit
0316dc67e3

+ 2 - 1
panda/src/distort/Sources.pp

@@ -14,11 +14,12 @@
     cylindricalLens.h cylindricalLens.I \
     fisheyeLens.h fisheyeLens.I \
     nonlinearImager.h nonlinearImager.I \
+    oSphereLens.h oSphereLens.I \
     pSphereLens.h pSphereLens.I
 
   #define INCLUDED_SOURCES \
     config_distort.cxx cylindricalLens.cxx fisheyeLens.cxx nonlinearImager.cxx \
-    projectionScreen.cxx pSphereLens.cxx 
+    projectionScreen.cxx oSphereLens.cxx pSphereLens.cxx
 
   #define INSTALL_HEADERS
 

+ 2 - 0
panda/src/distort/config_distort.cxx

@@ -16,6 +16,7 @@
 #include "cylindricalLens.h"
 #include "fisheyeLens.h"
 #include "pSphereLens.h"
+#include "oSphereLens.h"
 #include "projectionScreen.h"
 
 #include "dconfig.h"
@@ -55,5 +56,6 @@ init_libdistort() {
   CylindricalLens::init_type();
   FisheyeLens::init_type();
   PSphereLens::init_type();
+  OSphereLens::init_type();
   ProjectionScreen::init_type();
 }

+ 1 - 0
panda/src/distort/distort_composite1.cxx

@@ -2,6 +2,7 @@
 #include "config_distort.cxx"
 #include "cylindricalLens.cxx" 
 #include "fisheyeLens.cxx"
+#include "oSphereLens.cxx"
 #include "pSphereLens.cxx"
 #include "nonlinearImager.cxx"
 #include "projectionScreen.cxx"

+ 42 - 0
panda/src/distort/oSphereLens.I

@@ -0,0 +1,42 @@
+// Filename: oSphereLens.I
+// Created by:  drose (25Feb11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE OSphereLens::
+OSphereLens() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE OSphereLens::
+OSphereLens(const OSphereLens &copy) : Lens(copy) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::Copy Assignment Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE void OSphereLens::
+operator = (const OSphereLens &copy) {
+  Lens::operator = (copy);
+}
+

+ 178 - 0
panda/src/distort/oSphereLens.cxx

@@ -0,0 +1,178 @@
+// Filename: oSphereLens.cxx
+// Created by:  drose (25Feb11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "oSphereLens.h"
+#include "deg_2_rad.h"
+
+TypeHandle OSphereLens::_type_handle;
+
+// This is the focal-length constant for fisheye lenses.  See
+// fisheyeLens.cxx.
+static const float ospherical_k = 60.0f;
+// focal_length = film_size * ospherical_k / fov;
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::make_copy
+//       Access: Public, Virtual
+//  Description: Allocates a new Lens just like this one.
+////////////////////////////////////////////////////////////////////
+PT(Lens) OSphereLens::
+make_copy() const {
+  return new OSphereLens(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::extrude_impl
+//       Access: Protected, Virtual
+//  Description: Given a 2-d point in the range (-1,1) in both
+//               dimensions, where (0,0) is the center of the
+//               lens and (-1,-1) is the lower-left corner,
+//               compute the corresponding vector in space that maps
+//               to this point, if such a vector can be determined.
+//               The vector is returned by indicating the points on
+//               the near plane and far plane that both map to the
+//               indicated 2-d point.
+//
+//               The z coordinate of the 2-d point is ignored.
+//
+//               Returns true if the vector is defined, or false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool OSphereLens::
+extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) const {
+  // Undo the shifting from film offsets, etc.  This puts the point
+  // into the range [-film_size/2, film_size/2] in x and y.
+  LPoint3f f = point2d * get_film_mat_inv();
+
+  float focal_length = get_focal_length();
+  float angle = f[0] * cylindrical_k / focal_length;
+  float sinAngle, cosAngle;
+  csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
+
+  // Define a unit vector that represents the vector corresponding to
+  // this point.
+  LPoint3f v(sinAngle, cosAngle, 0.0f);
+
+  near_point = (v * get_near());
+  far_point = (v * get_far());
+  near_point[2] = f[1] / focal_length;
+  far_point[2] = f[1] / focal_length;
+
+  // And we'll need to account for the lens's rotations, etc. at the
+  // end of the day.
+  const LMatrix4f &lens_mat = get_lens_mat();
+
+  near_point = near_point * lens_mat;
+  far_point = far_point * lens_mat;
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::project_impl
+//       Access: Protected, Virtual
+//  Description: Given a 3-d point in space, determine the 2-d point
+//               this maps to, in the range (-1,1) in both dimensions,
+//               where (0,0) is the center of the lens and
+//               (-1,-1) is the lower-left corner.
+//
+//               Some lens types also set the z coordinate of the 2-d
+//               point to a value in the range (-1, 1), where 1
+//               represents a point on the near plane, and -1
+//               represents a point on the far plane.
+//
+//               Returns true if the 3-d point is in front of the lens
+//               and within the viewing frustum (in which case point2d
+//               is filled in), or false otherwise.
+////////////////////////////////////////////////////////////////////
+bool OSphereLens::
+project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
+  // First, account for any rotations, etc. on the lens.
+  LPoint3f p = point3d * get_lens_mat_inv();
+  float dist = p.length();
+  if (dist == 0.0f) {
+    point2d.set(0.0f, 0.0f, 0.0f);
+    return false;
+  }
+
+  LPoint3f v3 = p / dist;
+
+  float focal_length = get_focal_length();
+
+  // 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
+  // into the XY plane to do this.
+  LVector2f xy(v3[0], v3[1]);
+
+  point2d.set
+    (
+     // The x position is the angle about the Z axis.
+     rad_2_deg(catan2(xy[0], xy[1])) * focal_length / ospherical_k,
+     // The y position is the Z height.
+     // distance.
+     p[2] * focal_length,
+     // Z is the distance scaled into the range (1, -1).
+     (get_near() - dist) / (get_far() - get_near())
+     );
+
+  // Now we have to transform the point according to the film
+  // adjustments.
+  point2d = point2d * get_film_mat();
+
+  return
+    point2d[0] >= -1.0f && point2d[0] <= 1.0f && 
+    point2d[1] >= -1.0f && point2d[1] <= 1.0f;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::fov_to_film
+//       Access: Protected, Virtual
+//  Description: Given a field of view in degrees and a focal length,
+//               compute the correspdonding width (or height) on the
+//               film.  If horiz is true, this is in the horizontal
+//               direction; otherwise, it is in the vertical direction
+//               (some lenses behave differently in each direction).
+////////////////////////////////////////////////////////////////////
+float OSphereLens::
+fov_to_film(float fov, float focal_length, bool) const {
+  return focal_length * fov / ospherical_k;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::fov_to_focal_length
+//       Access: Protected, Virtual
+//  Description: Given a field of view in degrees and a width (or
+//               height) on the film, compute the focal length of the
+//               lens.  If horiz is true, this is in the horizontal
+//               direction; otherwise, it is in the vertical direction
+//               (some lenses behave differently in each direction).
+////////////////////////////////////////////////////////////////////
+float OSphereLens::
+fov_to_focal_length(float fov, float film_size, bool) const {
+  return film_size * ospherical_k / fov;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: OSphereLens::film_to_fov
+//       Access: Protected, Virtual
+//  Description: Given a width (or height) on the film and a focal
+//               length, compute the field of view in degrees.  If
+//               horiz is true, this is in the horizontal direction;
+//               otherwise, it is in the vertical direction (some
+//               lenses behave differently in each direction).
+////////////////////////////////////////////////////////////////////
+float OSphereLens::
+film_to_fov(float film_size, float focal_length, bool) const {
+  return film_size * ospherical_k / focal_length;
+}

+ 74 - 0
panda/src/distort/oSphereLens.h

@@ -0,0 +1,74 @@
+// Filename: oSphereLens.h
+// Created by:  drose (25Feb11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OSPHERELENS_H
+#define OSPHERELENS_H
+
+#include "pandabase.h"
+
+#include "lens.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : OSphereLens
+// Description : A OSphereLens is a special nonlinear lens that
+//               doesn't correspond to any real physical lenses.  It's
+//               primarily useful for generating 360-degree wraparound
+//               images while avoiding the distortion associated with
+//               fisheye images.
+//
+//               A OSphereLens is similar to a Cylindrical lens and
+//               PSphereLens, except that it is orthographic in the
+//               vertical direction.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDAFX OSphereLens : public Lens {
+PUBLISHED:
+  INLINE OSphereLens();
+
+public:
+  INLINE OSphereLens(const OSphereLens &copy);
+  INLINE void operator = (const OSphereLens &copy);
+
+public:
+  virtual PT(Lens) make_copy() const;
+
+protected:
+  virtual bool extrude_impl(const LPoint3f &point2d,
+                            LPoint3f &near_point, LPoint3f &far_point) const;
+  virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
+
+  virtual float fov_to_film(float fov, float focal_length, bool horiz) const;
+  virtual float fov_to_focal_length(float fov, float film_size, bool horiz) const;
+  virtual float film_to_fov(float film_size, float focal_length, bool horiz) const;
+
+public:
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Lens::init_type();
+    register_type(_type_handle, "OSphereLens",
+                  Lens::get_class_type());
+  }
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "oSphereLens.I"
+
+#endif

+ 8 - 9
panda/src/distort/pSphereLens.cxx

@@ -19,8 +19,7 @@ TypeHandle PSphereLens::_type_handle;
 
 // This is the focal-length constant for fisheye lenses.  See
 // fisheyeLens.cxx.
-static const float spherical_k = 60.0f;
-// focal_length = film_size * spherical_k / fov;
+static const float pspherical_k = 60.0f;
 
 
 ////////////////////////////////////////////////////////////////////
@@ -61,8 +60,8 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
   // Rotate the forward vector through the rotation angles
   // corresponding to this point.
   LPoint3f v = LPoint3f(0.0f, 1.0f, 0.0f) *
-    LMatrix3f::rotate_mat(f[1] * spherical_k / focal_length, LVector3f(1.0f, 0.0f, 0.0f)) *
-    LMatrix3f::rotate_mat(f[0] * spherical_k / focal_length, LVector3f(0.0f, 0.0f, -1.0f));
+    LMatrix3f::rotate_mat(f[1] * pspherical_k / focal_length, LVector3f(1.0f, 0.0f, 0.0f)) *
+    LMatrix3f::rotate_mat(f[0] * pspherical_k / focal_length, LVector3f(0.0f, 0.0f, -1.0f));
 
   // And we'll need to account for the lens's rotations, etc. at the
   // end of the day.
@@ -117,9 +116,9 @@ project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
   point2d.set
     (
      // The x position is the angle about the Z axis.
-     rad_2_deg(catan2(xy[0], xy[1])) * focal_length / spherical_k,
+     rad_2_deg(catan2(xy[0], xy[1])) * focal_length / pspherical_k,
      // The y position is the angle about the X axis.
-     rad_2_deg(catan2(yz[1], yz[0])) * focal_length / spherical_k,
+     rad_2_deg(catan2(yz[1], yz[0])) * focal_length / pspherical_k,
      // Z is the distance scaled into the range (1, -1).
      (get_near() - dist) / (get_far() - get_near())
      );
@@ -144,7 +143,7 @@ project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
 ////////////////////////////////////////////////////////////////////
 float PSphereLens::
 fov_to_film(float fov, float focal_length, bool) const {
-  return focal_length * fov / spherical_k;
+  return focal_length * fov / pspherical_k;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -158,7 +157,7 @@ fov_to_film(float fov, float focal_length, bool) const {
 ////////////////////////////////////////////////////////////////////
 float PSphereLens::
 fov_to_focal_length(float fov, float film_size, bool) const {
-  return film_size * spherical_k / fov;
+  return film_size * pspherical_k / fov;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -172,5 +171,5 @@ fov_to_focal_length(float fov, float film_size, bool) const {
 ////////////////////////////////////////////////////////////////////
 float PSphereLens::
 film_to_fov(float film_size, float focal_length, bool) const {
-  return film_size * spherical_k / focal_length;
+  return film_size * pspherical_k / focal_length;
 }