Panda3D
|
00001 // Filename: perspectiveLens.cxx 00002 // Created by: drose (18Feb99) 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 "perspectiveLens.h" 00016 #include "bamReader.h" 00017 00018 TypeHandle PerspectiveLens::_type_handle; 00019 00020 00021 //////////////////////////////////////////////////////////////////// 00022 // Function: PerspectiveLens::make_copy 00023 // Access: Public, Virtual 00024 // Description: Allocates a new Lens just like this one. 00025 //////////////////////////////////////////////////////////////////// 00026 PT(Lens) PerspectiveLens:: 00027 make_copy() const { 00028 return new PerspectiveLens(*this); 00029 } 00030 00031 //////////////////////////////////////////////////////////////////// 00032 // Function: PerspectiveLens::is_linear 00033 // Access: Published, Virtual 00034 // Description: Returns true if the lens represents a linear 00035 // projection (e.g. PerspectiveLens, OrthographicLens), 00036 // and therefore there is a valid matrix returned by 00037 // get_projection_mat(), or false otherwise. 00038 //////////////////////////////////////////////////////////////////// 00039 bool PerspectiveLens:: 00040 is_linear() const { 00041 return true; 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: PerspectiveLens::is_perspective 00046 // Access: Published, Virtual 00047 // Description: Returns true if the lens represents a perspective 00048 // projection (i.e. it is a PerspectiveLens), false 00049 // otherwise. 00050 //////////////////////////////////////////////////////////////////// 00051 bool PerspectiveLens:: 00052 is_perspective() const { 00053 return true; 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: PerspectiveLens::do_compute_projection_mat 00058 // Access: Protected, Virtual 00059 // Description: Computes the complete transformation matrix from 3-d 00060 // point to 2-d point, if the lens is linear. 00061 //////////////////////////////////////////////////////////////////// 00062 void PerspectiveLens:: 00063 do_compute_projection_mat(Lens::CData *lens_cdata) { 00064 CoordinateSystem cs = lens_cdata->_cs; 00065 if (cs == CS_default) { 00066 cs = get_default_coordinate_system(); 00067 } 00068 00069 PN_stdfloat fl = do_get_focal_length(lens_cdata); 00070 PN_stdfloat fFar = do_get_far(lens_cdata); 00071 PN_stdfloat fNear = do_get_near(lens_cdata); 00072 PN_stdfloat far_minus_near = fFar-fNear; 00073 PN_stdfloat a = (fFar + fNear); 00074 PN_stdfloat b = -2.0f * fFar * fNear; 00075 00076 a /= far_minus_near; 00077 b /= far_minus_near; 00078 00079 LMatrix4 canonical; 00080 switch (cs) { 00081 case CS_zup_right: 00082 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00083 0.0f, 0.0f, a, 1.0f, 00084 0.0f, fl, 0.0f, 0.0f, 00085 0.0f, 0.0f, b, 0.0f); 00086 break; 00087 00088 case CS_yup_right: 00089 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00090 0.0f, fl, 0.0f, 0.0f, 00091 0.0f, 0.0f, -a, -1.0f, 00092 0.0f, 0.0f, b, 0.0f); 00093 break; 00094 00095 case CS_zup_left: 00096 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00097 0.0f, 0.0f, -a, -1.0f, 00098 0.0f, fl, 0.0f, 0.0f, 00099 0.0f, 0.0f, b, 0.0f); 00100 break; 00101 00102 case CS_yup_left: 00103 canonical.set( fl, 0.0f, 0.0f, 0.0f, 00104 0.0f, fl, 0.0f, 0.0f, 00105 0.0f, 0.0f, a, 1.0f, 00106 0.0f, 0.0f, b, 0.0f); 00107 break; 00108 00109 default: 00110 gobj_cat.error() 00111 << "Invalid coordinate system " << (int)cs << " in PerspectiveLens!\n"; 00112 canonical = LMatrix4::ident_mat(); 00113 } 00114 00115 lens_cdata->_projection_mat = do_get_lens_mat_inv(lens_cdata) * canonical * do_get_film_mat(lens_cdata); 00116 00117 if ((lens_cdata->_user_flags & UF_interocular_distance) == 0) { 00118 lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat; 00119 00120 } else { 00121 // Compute the left and right projection matrices in case this 00122 // lens is assigned to a stereo DisplayRegion. 00123 00124 LVector3 iod = lens_cdata->_interocular_distance * 0.5f * LVector3::left(lens_cdata->_cs); 00125 lens_cdata->_projection_mat_left = do_get_lens_mat_inv(lens_cdata) * LMatrix4::translate_mat(-iod) * canonical * do_get_film_mat(lens_cdata); 00126 lens_cdata->_projection_mat_right = do_get_lens_mat_inv(lens_cdata) * LMatrix4::translate_mat(iod) * canonical * do_get_film_mat(lens_cdata); 00127 00128 if (lens_cdata->_user_flags & UF_convergence_distance) { 00129 nassertv(lens_cdata->_convergence_distance != 0.0f); 00130 LVector3 cd = (0.25f / lens_cdata->_convergence_distance) * LVector3::left(lens_cdata->_cs); 00131 lens_cdata->_projection_mat_left *= LMatrix4::translate_mat(cd); 00132 lens_cdata->_projection_mat_right *= LMatrix4::translate_mat(-cd); 00133 } 00134 } 00135 00136 do_adjust_comp_flags(lens_cdata, 00137 CF_projection_mat_inv | CF_projection_mat_left_inv | CF_projection_mat_right_inv, 00138 CF_projection_mat); 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: PerspectiveLens::fov_to_film 00143 // Access: Protected, Virtual 00144 // Description: Given a field of view in degrees and a focal length, 00145 // compute the correspdonding width (or height) on the 00146 // film. If horiz is true, this is in the horizontal 00147 // direction; otherwise, it is in the vertical direction 00148 // (some lenses behave differently in each direction). 00149 //////////////////////////////////////////////////////////////////// 00150 PN_stdfloat PerspectiveLens:: 00151 fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool) const { 00152 return (ctan(deg_2_rad(fov * 0.5f)) * focal_length) * 2.0f; 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: PerspectiveLens::fov_to_focal_length 00157 // Access: Protected, Virtual 00158 // Description: Given a field of view in degrees and a width (or 00159 // height) on the film, compute the focal length of the 00160 // lens. If horiz is true, this is in the horizontal 00161 // direction; otherwise, it is in the vertical direction 00162 // (some lenses behave differently in each direction). 00163 //////////////////////////////////////////////////////////////////// 00164 PN_stdfloat PerspectiveLens:: 00165 fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool) const { 00166 return film_size * 0.5f / ctan(deg_2_rad(fov * 0.5f)); 00167 } 00168 00169 //////////////////////////////////////////////////////////////////// 00170 // Function: PerspectiveLens::film_to_fov 00171 // Access: Protected, Virtual 00172 // Description: Given a width (or height) on the film and a focal 00173 // length, compute the field of view in degrees. If 00174 // horiz is true, this is in the horizontal direction; 00175 // otherwise, it is in the vertical direction (some 00176 // lenses behave differently in each direction). 00177 //////////////////////////////////////////////////////////////////// 00178 PN_stdfloat PerspectiveLens:: 00179 film_to_fov(PN_stdfloat film_size, PN_stdfloat focal_length, bool) const { 00180 return rad_2_deg(catan(film_size * 0.5f / focal_length)) * 2.0f; 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: PerspectiveLens::register_with_read_factory 00185 // Access: Public, Static 00186 // Description: Tells the BamReader how to create objects of type 00187 // Lens. 00188 //////////////////////////////////////////////////////////////////// 00189 void PerspectiveLens:: 00190 register_with_read_factory() { 00191 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00192 } 00193 00194 //////////////////////////////////////////////////////////////////// 00195 // Function: PerspectiveLens::make_from_bam 00196 // Access: Protected, Static 00197 // Description: This function is called by the BamReader's factory 00198 // when a new object of type Lens is encountered 00199 // in the Bam file. It should create the Lens 00200 // and extract its information from the file. 00201 //////////////////////////////////////////////////////////////////// 00202 TypedWritable *PerspectiveLens:: 00203 make_from_bam(const FactoryParams ¶ms) { 00204 PerspectiveLens *lens = new PerspectiveLens; 00205 DatagramIterator scan; 00206 BamReader *manager; 00207 00208 parse_params(params, scan, manager); 00209 lens->fillin(scan, manager); 00210 00211 return lens; 00212 }