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