Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/distort/cylindricalLens.cxx

Go to the documentation of this file.
00001 // Filename: cylindricalLens.cxx
00002 // Created by:  drose (12Dec01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "cylindricalLens.h"
00020 #include "deg_2_rad.h"
00021 
00022 TypeHandle CylindricalLens::_type_handle;
00023 
00024 // This is the focal-length constant for fisheye lenses.  See
00025 // fisheyeLens.cxx.
00026 static const float cylindrical_k = 60.0f;
00027 // focal_length = film_size * cylindrical_k / fov;
00028 
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: CylindricalLens::make_copy
00032 //       Access: Public, Virtual
00033 //  Description: Allocates a new Lens just like this one.
00034 ////////////////////////////////////////////////////////////////////
00035 PT(Lens) CylindricalLens::
00036 make_copy() const {
00037   return new CylindricalLens(*this);
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: CylindricalLens::extrude_impl
00042 //       Access: Protected, Virtual
00043 //  Description: Given a 2-d point in the range (-1,1) in both
00044 //               dimensions, where (0,0) is the center of the
00045 //               lens and (-1,-1) is the lower-left corner,
00046 //               compute the corresponding vector in space that maps
00047 //               to this point, if such a vector can be determined.
00048 //               The vector is returned by indicating the points on
00049 //               the near plane and far plane that both map to the
00050 //               indicated 2-d point.
00051 //
00052 //               The z coordinate of the 2-d point is ignored.
00053 //
00054 //               Returns true if the vector is defined, or false
00055 //               otherwise.
00056 ////////////////////////////////////////////////////////////////////
00057 bool CylindricalLens::
00058 extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) const {
00059   // Undo the shifting from film offsets, etc.  This puts the point
00060   // into the range [-film_size/2, film_size/2] in x and y.
00061   LPoint3f f = point2d * get_film_mat_inv();
00062 
00063   float focal_length = get_focal_length();
00064   float angle = f[0] * cylindrical_k / focal_length;
00065   float sinAngle, cosAngle;
00066   csincos(deg_2_rad(angle), &sinAngle, &cosAngle);
00067 
00068   // Define a unit vector (well, a unit vector in the XY plane, at
00069   // least) that reprents the vector corresponding to this point.
00070   LPoint3f v(sinAngle, cosAngle, f[1] / focal_length);
00071 
00072   // And we'll need to account for the lens's rotations, etc. at the
00073   // end of the day.
00074   const LMatrix4f &lens_mat = get_lens_mat();
00075 
00076   near_point = (v * get_near()) * lens_mat;
00077   far_point = (v * get_far()) * lens_mat;
00078   return true;
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: CylindricalLens::project_impl
00083 //       Access: Protected, Virtual
00084 //  Description: Given a 3-d point in space, determine the 2-d point
00085 //               this maps to, in the range (-1,1) in both dimensions,
00086 //               where (0,0) is the center of the lens and
00087 //               (-1,-1) is the lower-left corner.
00088 //
00089 //               Some lens types also set the z coordinate of the 2-d
00090 //               point to a value in the range (-1, 1), where 1
00091 //               represents a point on the near plane, and -1
00092 //               represents a point on the far plane.
00093 //
00094 //               Returns true if the 3-d point is in front of the lens
00095 //               and within the viewing frustum (in which case point2d
00096 //               is filled in), or false otherwise.
00097 ////////////////////////////////////////////////////////////////////
00098 bool CylindricalLens::
00099 project_impl(const LPoint3f &point3d, LPoint3f &point2d) const {
00100   // First, account for any rotations, etc. on the lens.
00101   LPoint3f p = point3d * get_lens_mat_inv();
00102 
00103   // To compute the x position on the frame, we only need to consider
00104   // the angle of the vector about the Z axis.  Project the vector
00105   // into the XY plane to do this.
00106   LVector2f xy(p[0], p[1]);
00107 
00108   // The perspective distance is the length of this vector in the XY
00109   // plane.
00110   float pdist = xy.length();
00111   if (pdist == 0.0f) {
00112     point2d.set(0.0f, 0.0f, 0.0f);
00113     return false;
00114   }
00115 
00116   float focal_length = get_focal_length();
00117 
00118   point2d.set
00119     (
00120      // The x position is the angle about the Z axis.
00121      rad_2_deg(catan2(xy[0], xy[1])) * focal_length / cylindrical_k,
00122      // The y position is the Z height divided by the perspective
00123      // distance.
00124      p[2] * focal_length / pdist,
00125      // Z is the perspective distance scaled into the range (1, -1).
00126      (get_near() - pdist) / (get_far() - get_near())
00127      );
00128 
00129   // Now we have to transform the point according to the film
00130   // adjustments.
00131   point2d = point2d * get_film_mat();
00132 
00133   return
00134     point2d[0] >= -1.0f && point2d[0] <= 1.0f && 
00135     point2d[1] >= -1.0f && point2d[1] <= 1.0f;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: CylindricalLens::fov_to_film
00140 //       Access: Protected, Virtual
00141 //  Description: Given a field of view in degrees and a focal length,
00142 //               compute the correspdonding width (or height) on the
00143 //               film.  If horiz is true, this is in the horizontal
00144 //               direction; otherwise, it is in the vertical direction
00145 //               (some lenses behave differently in each direction).
00146 ////////////////////////////////////////////////////////////////////
00147 float CylindricalLens::
00148 fov_to_film(float fov, float focal_length, bool horiz) const {
00149   if (horiz) {
00150     return focal_length * fov / cylindrical_k;
00151   } else {
00152     return (ctan(deg_2_rad(fov * 0.5f)) * focal_length) * 2.0f;
00153   }
00154 }
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 //     Function: CylindricalLens::fov_to_focal_length
00158 //       Access: Protected, Virtual
00159 //  Description: Given a field of view in degrees and a width (or
00160 //               height) on the film, compute the focal length of the
00161 //               lens.  If horiz is true, this is in the horizontal
00162 //               direction; otherwise, it is in the vertical direction
00163 //               (some lenses behave differently in each direction).
00164 ////////////////////////////////////////////////////////////////////
00165 float CylindricalLens::
00166 fov_to_focal_length(float fov, float film_size, bool horiz) const {
00167   if (horiz) {
00168     return film_size * cylindrical_k / fov;
00169   } else {
00170     return film_size * 0.5f / ctan(deg_2_rad(fov * 0.5f));
00171   }
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: CylindricalLens::film_to_fov
00176 //       Access: Protected, Virtual
00177 //  Description: Given a width (or height) on the film and a focal
00178 //               length, compute the field of view in degrees.  If
00179 //               horiz is true, this is in the horizontal direction;
00180 //               otherwise, it is in the vertical direction (some
00181 //               lenses behave differently in each direction).
00182 ////////////////////////////////////////////////////////////////////
00183 float CylindricalLens::
00184 film_to_fov(float film_size, float focal_length, bool horiz) const {
00185   if (horiz) {
00186     return film_size * cylindrical_k / focal_length;
00187   } else {
00188     return rad_2_deg(catan(film_size * 0.5f / focal_length)) * 2.0f;
00189   }
00190 }

Generated on Fri May 2 00:36:37 2003 for Panda by doxygen1.3