00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "perspectiveLens.h"
00016 #include "bamReader.h"
00017
00018 TypeHandle PerspectiveLens::_type_handle;
00019
00020
00021
00022
00023
00024
00025
00026 PT(Lens) PerspectiveLens::
00027 make_copy() const {
00028 return new PerspectiveLens(*this);
00029 }
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 bool PerspectiveLens::
00040 is_linear() const {
00041 return true;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051 bool PerspectiveLens::
00052 is_perspective() const {
00053 return true;
00054 }
00055
00056
00057
00058
00059
00060
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
00122
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
00143
00144
00145
00146
00147
00148
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
00157
00158
00159
00160
00161
00162
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
00171
00172
00173
00174
00175
00176
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
00185
00186
00187
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
00196
00197
00198
00199
00200
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 }