Panda3D
|
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 00078 near_point = near_point * lens_mat; 00079 far_point = far_point * lens_mat; 00080 return true; 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: OSphereLens::do_project 00085 // Access: Protected, Virtual 00086 // Description: Given a 3-d point in space, determine the 2-d point 00087 // this maps to, in the range (-1,1) in both dimensions, 00088 // where (0,0) is the center of the lens and 00089 // (-1,-1) is the lower-left corner. 00090 // 00091 // Some lens types also set the z coordinate of the 2-d 00092 // point to a value in the range (-1, 1), where 1 00093 // represents a point on the near plane, and -1 00094 // represents a point on the far plane. 00095 // 00096 // Returns true if the 3-d point is in front of the lens 00097 // and within the viewing frustum (in which case point2d 00098 // is filled in), or false otherwise. 00099 //////////////////////////////////////////////////////////////////// 00100 bool OSphereLens:: 00101 do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { 00102 // First, account for any rotations, etc. on the lens. 00103 LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata); 00104 PN_stdfloat dist = p.length(); 00105 if (dist == 0.0f) { 00106 point2d.set(0.0f, 0.0f, 0.0f); 00107 return false; 00108 } 00109 00110 LPoint3 v3 = p / dist; 00111 00112 PN_stdfloat focal_length = do_get_focal_length(lens_cdata); 00113 00114 // To compute the x position on the frame, we only need to consider 00115 // the angle of the vector about the Z axis. Project the vector 00116 // into the XY plane to do this. 00117 LVector2 xy(v3[0], v3[1]); 00118 00119 point2d.set 00120 ( 00121 // The x position is the angle about the Z axis. 00122 rad_2_deg(catan2(xy[0], xy[1])) * focal_length / ospherical_k, 00123 // The y position is the Z height. 00124 p[2], 00125 // Z is the distance scaled into the range (1, -1). 00126 (do_get_near(lens_cdata) - dist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata)) 00127 ); 00128 00129 // Now we have to transform the point according to the film 00130 // adjustments. 00131 point2d = point2d * do_get_film_mat(lens_cdata); 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: OSphereLens::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 PN_stdfloat OSphereLens:: 00148 fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool) const { 00149 return focal_length * fov / ospherical_k; 00150 } 00151 00152 //////////////////////////////////////////////////////////////////// 00153 // Function: OSphereLens::fov_to_focal_length 00154 // Access: Protected, Virtual 00155 // Description: Given a field of view in degrees and a width (or 00156 // height) on the film, compute the focal length of the 00157 // lens. If horiz is true, this is in the horizontal 00158 // direction; otherwise, it is in the vertical direction 00159 // (some lenses behave differently in each direction). 00160 //////////////////////////////////////////////////////////////////// 00161 PN_stdfloat OSphereLens:: 00162 fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool) const { 00163 return film_size * ospherical_k / fov; 00164 } 00165 00166 //////////////////////////////////////////////////////////////////// 00167 // Function: OSphereLens::film_to_fov 00168 // Access: Protected, Virtual 00169 // Description: Given a width (or height) on the film and a focal 00170 // length, compute the field of view in degrees. If 00171 // horiz is true, this is in the horizontal direction; 00172 // otherwise, it is in the vertical direction (some 00173 // lenses behave differently in each direction). 00174 //////////////////////////////////////////////////////////////////// 00175 PN_stdfloat OSphereLens:: 00176 film_to_fov(PN_stdfloat film_size, PN_stdfloat focal_length, bool) const { 00177 return film_size * ospherical_k / focal_length; 00178 }