00001 // Filename: perspectiveLens.cxx 00002 // Created by: drose (18Feb99) 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 "perspectiveLens.h" 00020 00021 TypeHandle PerspectiveLens::_type_handle; 00022 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: PerspectiveLens::make_copy 00026 // Access: Public, Virtual 00027 // Description: Allocates a new Lens just like this one. 00028 //////////////////////////////////////////////////////////////////// 00029 PT(Lens) PerspectiveLens:: 00030 make_copy() const { 00031 return new PerspectiveLens(*this); 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: PerspectiveLens::is_linear 00036 // Access: Published, Virtual 00037 // Description: Returns true if the lens represents a linear 00038 // projection (e.g. PerspectiveLens, OrthographicLens), 00039 // and therefore there is a valid matrix returned by 00040 // get_projection_mat(), or false otherwise. 00041 //////////////////////////////////////////////////////////////////// 00042 bool PerspectiveLens:: 00043 is_linear() const { 00044 return true; 00045 } 00046 00047 //////////////////////////////////////////////////////////////////// 00048 // Function: PerspectiveLens::compute_projection_mat 00049 // Access: Protected, Virtual 00050 // Description: Computes the complete transformation matrix from 3-d 00051 // point to 2-d point, if the lens is linear. 00052 //////////////////////////////////////////////////////////////////// 00053 void PerspectiveLens:: 00054 compute_projection_mat() { 00055 CoordinateSystem cs = _cs; 00056 if (cs == CS_default) { 00057 cs = default_coordinate_system; 00058 } 00059 00060 float fl = get_focal_length(); 00061 float fFar = get_far(); 00062 float fNear = get_near(); 00063 float far_minus_near = fFar-fNear; 00064 float a = (fFar + fNear); 00065 float b = -2.0f * fFar * fNear; 00066 00067 a/=far_minus_near; 00068 b/=far_minus_near; 00069 00070 LMatrix4f canonical; 00071 switch (cs) { 00072 case CS_zup_right: 00073 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00074 0.0f, 0.0f, a, 1.0f, 00075 0.0f, fl, 0.0f, 0.0f, 00076 0.0f, 0.0f, b, 0.0f); 00077 break; 00078 00079 case CS_yup_right: 00080 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00081 0.0f, fl, 0.0f, 0.0f, 00082 0.0f, 0.0f, -a, -1.0f, 00083 0.0f, 0.0f, b, 0.0f); 00084 break; 00085 00086 case CS_zup_left: 00087 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00088 0.0f, 0.0f, -a, -1.0f, 00089 0.0f, fl, 0.0f, 0.0f, 00090 0.0f, 0.0f, b, 0.0f); 00091 break; 00092 00093 case CS_yup_left: 00094 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00095 0.0f, fl, 0.0f, 0.0f, 00096 0.0f, 0.0f, a, 1.0f, 00097 0.0f, 0.0f, b, 0.0f); 00098 break; 00099 00100 default: 00101 gobj_cat.error() 00102 << "Invalid coordinate system " << (int)cs << " in PerspectiveLens!\n"; 00103 canonical = LMatrix4f::ident_mat(); 00104 } 00105 00106 00107 _projection_mat = get_lens_mat_inv() * canonical * get_film_mat(); 00108 adjust_comp_flags(CF_projection_mat_inv, 00109 CF_projection_mat); 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: PerspectiveLens::fov_to_film 00114 // Access: Protected, Virtual 00115 // Description: Given a field of view in degrees and a focal length, 00116 // compute the correspdonding width (or height) on the 00117 // film. If horiz is true, this is in the horizontal 00118 // direction; otherwise, it is in the vertical direction 00119 // (some lenses behave differently in each direction). 00120 //////////////////////////////////////////////////////////////////// 00121 float PerspectiveLens:: 00122 fov_to_film(float fov, float focal_length, bool) const { 00123 return (ctan(deg_2_rad(fov * 0.5f)) * focal_length) * 2.0f; 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: PerspectiveLens::fov_to_focal_length 00128 // Access: Protected, Virtual 00129 // Description: Given a field of view in degrees and a width (or 00130 // height) on the film, compute the focal length of the 00131 // lens. If horiz is true, this is in the horizontal 00132 // direction; otherwise, it is in the vertical direction 00133 // (some lenses behave differently in each direction). 00134 //////////////////////////////////////////////////////////////////// 00135 float PerspectiveLens:: 00136 fov_to_focal_length(float fov, float film_size, bool) const { 00137 return film_size * 0.5f / ctan(deg_2_rad(fov * 0.5f)); 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: PerspectiveLens::film_to_fov 00142 // Access: Protected, Virtual 00143 // Description: Given a width (or height) on the film and a focal 00144 // length, compute the field of view in degrees. If 00145 // horiz is true, this is in the horizontal direction; 00146 // otherwise, it is in the vertical direction (some 00147 // lenses behave differently in each direction). 00148 //////////////////////////////////////////////////////////////////// 00149 float PerspectiveLens:: 00150 film_to_fov(float film_size, float focal_length, bool) const { 00151 return rad_2_deg(catan(film_size * 0.5f / focal_length)) * 2.0f; 00152 }