44Lens(
const Lens ©) : _cycler(copy._cycler) {
46 CDWriter cdata(_cycler,
true);
47 cdata->_geom_data =
nullptr;
54operator = (
const Lens ©) {
55 _cycler = copy._cycler;
58 CDWriter cdata(_cycler,
true);
59 cdata->_geom_data =
nullptr;
68 CDWriter cdata(_cycler,
true);
70 do_adjust_comp_flags(cdata, CF_mat | CF_view_hpr | CF_view_vector, 0);
71 do_throw_change_event(cdata);
82 do_set_interocular_distance(cdata, default_iod);
83 do_set_convergence_distance(cdata, default_converge);
84 do_throw_change_event(cdata);
100 nassertv(!cnan(min_fov));
101 CDWriter cdata(_cycler,
true);
102 cdata->_min_fov = min_fov;
106 do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq);
108 if (cdata->_focal_length_seq == 0) {
110 do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_hfov,
114 nassertv(cdata->_film_size_seq == 0);
117 do_compute_aspect_ratio(cdata);
118 do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_vfov | UF_hfov,
121 do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_film_size,
126 do_throw_change_event(cdata);
135 CDReader cdata(_cycler);
137 if ((cdata->_comp_flags & CF_fov) == 0) {
138 ((
Lens *)
this)->do_compute_fov((CData *)cdata.p());
140 return cdata->_min_fov;
169 nassertv(!view_hpr.is_nan());
170 CDWriter cdata(_cycler,
true);
171 cdata->_view_hpr = view_hpr;
172 do_adjust_user_flags(cdata, UF_view_vector | UF_view_mat,
174 do_adjust_comp_flags(cdata, CF_mat | CF_view_vector,
176 do_throw_change_event(cdata);
184 CDReader cdata(_cycler);
185 if ((cdata->_comp_flags & CF_view_hpr) == 0) {
186 ((
Lens *)
this)->do_compute_view_hpr((CData *)cdata.p());
188 return cdata->_view_hpr;
198set_view_vector(
const LVector3 &view_vector,
const LVector3 &up_vector) {
199 nassertv(!view_vector.is_nan());
201 cdata->_view_vector = view_vector;
202 cdata->_up_vector = up_vector;
203 do_adjust_user_flags(cdata, UF_view_hpr | UF_view_mat,
205 do_adjust_comp_flags(cdata, CF_mat | CF_view_hpr,
207 do_throw_change_event(cdata);
216 if ((cdata->_comp_flags & CF_view_vector) == 0) {
217 ((
Lens *)
this)->do_compute_view_vector((CData *)cdata.
p());
219 return cdata->_view_vector;
229 if ((cdata->_comp_flags & CF_view_vector) == 0) {
230 ((
Lens *)
this)->do_compute_view_vector((CData *)cdata.
p());
232 return cdata->_up_vector;
250 cdata->_lens_mat = LMatrix4::ident_mat();
251 do_adjust_user_flags(cdata, 0, UF_view_vector | UF_view_hpr | UF_view_mat);
252 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
253 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
254 CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
256 do_throw_change_event(cdata);
273 nassertv(!keystone.is_nan());
274 CDWriter cdata(_cycler,
true);
275 cdata->_keystone = keystone;
276 do_adjust_user_flags(cdata, 0, UF_keystone);
277 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
278 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
279 CF_film_mat | CF_film_mat_inv, 0);
280 do_throw_change_event(cdata);
289 cdata->_keystone.set(0.0f, 0.0f);
290 do_adjust_user_flags(cdata, UF_keystone, 0);
291 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
292 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
293 CF_film_mat | CF_film_mat_inv, 0);
294 do_throw_change_event(cdata);
307 nassertv(!custom_film_mat.is_nan());
309 cdata->_custom_film_mat = custom_film_mat;
310 do_adjust_user_flags(cdata, 0, UF_custom_film_mat);
311 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
312 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
313 CF_film_mat | CF_film_mat_inv, 0);
314 do_throw_change_event(cdata);
323 cdata->_custom_film_mat = LMatrix4::ident_mat();
324 do_adjust_user_flags(cdata, UF_custom_film_mat, 0);
325 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
326 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
327 CF_film_mat | CF_film_mat_inv, 0);
328 do_throw_change_event(cdata);
376 const LVecBase3 &ll,
const LVecBase3 &lr,
378 nassertv(!ul.is_nan() && !ur.is_nan() && !ll.is_nan() && !lr.is_nan());
384 const LMatrix4 &lens_mat_inv = do_get_lens_mat_inv(cdata);
386 lens_mat_inv.get_row3(eye_offset, 3);
391 LVector3 view_vector;
392 if ((flags & FC_camera_plane) != 0) {
393 view_vector = (ul + ur + ll + lr) * 0.25;
395 LPlane plane(ll, ul, ur);
396 view_vector = plane.get_normal();
397 nassertv(!view_vector.is_nan() && view_vector.length_squared() != 0.0f);
403 LVector3 up_vector = LVector3::up(cdata->_cs);
404 if (view_vector == up_vector || ((flags & FC_roll) != 0)) {
405 LVector3 top = ul - ur;
406 up_vector = view_vector.cross(top);
407 nassertv(!up_vector.is_nan() && up_vector.length_squared() != 0.0f);
412 look_at(rot_mat, view_vector, up_vector, CS_zup_right);
415 LMatrix4 inv_rot_mat;
416 inv_rot_mat.invert_affine_from(rot_mat);
420 LPoint3 cul = inv_rot_mat.xform_point(ul);
421 LPoint3 cur = inv_rot_mat.xform_point(ur);
422 LPoint3 cll = inv_rot_mat.xform_point(ll);
423 LPoint3 clr = inv_rot_mat.xform_point(lr);
427 nassertv(cul[1] != 0.0f && cur[1] != 0.0f && cll[1] != 0.0f && clr[1] != 0.0f);
433 LMatrix4 shear_mat = LMatrix4::ident_mat();
434 LMatrix4 inv_shear_mat = LMatrix4::ident_mat();
437 if ((flags & FC_shear) != 0) {
438 build_shear_mat(shear_mat, cul, cur, cll, clr);
439 inv_shear_mat.invert_from(shear_mat);
443 LMatrix4 inv_view_mat =
448 inv_view_mat.set_row(3, eye_offset);
451 view_mat.invert_from(inv_view_mat);
452 do_set_view_mat(cdata, view_mat);
454 LPoint3 ful = inv_view_mat.xform_point(ul);
455 LPoint3 fur = inv_view_mat.xform_point(ur);
456 LPoint3 fll = inv_view_mat.xform_point(ll);
457 LPoint3 flr = inv_view_mat.xform_point(lr);
460 nassertv(ful[1] != 0.0f && fur[1] != 0.0f && fll[1] != 0.0f && flr[1] != 0.0f);
468 PN_stdfloat min_x = min(min(ful[0], fur[0]), min(fll[0], flr[0]));
469 PN_stdfloat max_x = max(max(ful[0], fur[0]), max(fll[0], flr[0]));
470 PN_stdfloat min_z = min(min(ful[2], fur[2]), min(fll[2], flr[2]));
471 PN_stdfloat max_z = max(max(ful[2], fur[2]), max(fll[2], flr[2]));
473 PN_stdfloat x_spread, x_center, z_spread, z_center;
475 if ((flags & FC_off_axis) != 0) {
478 x_center = (max_x + min_x) * 0.5f;
479 z_center = (max_z + min_z) * 0.5f;
480 x_spread = x_center - min_x;
481 z_spread = z_center - min_z;
486 x_spread = max(cabs(max_x), cabs(min_x));
487 z_spread = max(cabs(max_z), cabs(min_z));
490 PN_stdfloat aspect_ratio = do_get_aspect_ratio(cdata);
491 nassertv(aspect_ratio != 0.0f);
492 if ((flags & FC_aspect_ratio) == 0) {
495 if (x_spread < z_spread * aspect_ratio) {
497 x_spread = z_spread * aspect_ratio;
498 }
else if (z_spread < x_spread / aspect_ratio) {
500 z_spread = x_spread / aspect_ratio;
504 PN_stdfloat hfov = rad_2_deg(catan(x_spread)) * 2.0f;
505 PN_stdfloat vfov = rad_2_deg(catan(z_spread)) * 2.0f;
507 do_set_fov(cdata, LVecBase2(hfov, vfov));
509 if ((flags & FC_aspect_ratio) == 0) {
513 do_set_aspect_ratio(cdata, aspect_ratio);
516 const LVecBase2 &film_size = do_get_film_size(cdata);
517 nassertv(x_spread != 0.0f && z_spread != 0.0f);
518 do_set_film_offset(cdata, LVecBase2(film_size[0] * x_center / (x_spread * 2.0f),
519 film_size[1] * z_center / (z_spread * 2.0f)));
531 cdata->_comp_flags = 0;
569 CDWriter cdata(_cycler,
true);
579 int num_segments = do_define_geom_data(cdata);
580 if (num_segments == 0) {
582 cdata->_geom_data.clear();
591 for (i = 0; i < 4; ++i) {
592 for (si = 0; si < num_segments; ++si) {
593 line->add_vertex(i * 2 + si * (4 * 2) + 0);
597 line->close_primitive();
600 for (i = 0; i < 4; ++i) {
601 for (si = 0; si < num_segments; ++si) {
602 line->add_vertex(i * 2 + si * (4 * 2) + 1);
606 line->close_primitive();
609 line->add_vertex(0 * 2 + 0);
610 line->add_vertex(0 * 2 + 1);
611 line->close_primitive();
613 line->add_vertex(1 * 2 + 0);
614 line->add_vertex(1 * 2 + 1);
615 line->close_primitive();
617 line->add_vertex(2 * 2 + 0);
618 line->add_vertex(2 * 2 + 1);
619 line->close_primitive();
621 line->add_vertex(3 * 2 + 0);
622 line->add_vertex(3 * 2 + 1);
623 line->close_primitive();
626 line->add_vertex(num_segments * (4 * 2) + 0);
627 line->add_vertex(num_segments * (4 * 2) + 1);
628 line->close_primitive();
630 PT(
Geom) geom =
new Geom(cdata->_geom_data);
631 geom->add_primitive(line);
643 CDReader cdata(_cycler);
647 LPoint3 fll, flr, ful, fur;
648 LPoint3 nll, nlr, nul, nur;
652 corner.set(-1.0f, 1.0f, 0.0f);
653 if (!do_extrude(cdata, corner, nul, ful)) {
658 corner.set(1.0f, 1.0f, 0.0f);
659 if (!do_extrude(cdata, corner, nur, fur)) {
664 corner.set(1.0f, -1.0f, 0.0f);
665 if (!do_extrude(cdata, corner, nlr, flr)) {
670 corner.set(-1.0f, -1.0f, 0.0f);
671 if (!do_extrude(cdata, corner, nll, fll)) {
682output(std::ostream &out)
const {
690write(std::ostream &out,
int indent_level)
const {
691 indent(out, indent_level) << get_type() <<
" fov = " <<
get_fov() <<
"\n";
698do_set_film_size(CData *cdata, PN_stdfloat width) {
699 nassertv(!cnan(width));
700 cdata->_film_size.set(width, width / do_get_aspect_ratio(cdata));
704 do_resequence_fov_triad(cdata, cdata->_film_size_seq, cdata->_focal_length_seq, cdata->_fov_seq);
706 if (cdata->_fov_seq == 0) {
708 do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov | UF_film_height,
712 nassertv(cdata->_focal_length_seq == 0);
713 do_adjust_user_flags(cdata, UF_focal_length | UF_film_height,
716 do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov,
718 do_throw_change_event(cdata);
725do_set_film_size(CData *cdata,
const LVecBase2 &film_size) {
726 nassertv(!film_size.is_nan());
727 cdata->_film_size = film_size;
731 do_resequence_fov_triad(cdata, cdata->_film_size_seq, cdata->_focal_length_seq, cdata->_fov_seq);
733 if (cdata->_fov_seq == 0) {
735 do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov | UF_aspect_ratio,
736 UF_film_width | UF_film_height);
739 nassertv(cdata->_focal_length_seq == 0);
740 do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_aspect_ratio,
741 UF_film_width | UF_film_height);
743 do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_aspect_ratio,
748 do_compute_aspect_ratio(cdata);
749 do_adjust_user_flags(cdata, 0, UF_aspect_ratio);
751 do_throw_change_event(cdata);
757const LVecBase2 &Lens::
758do_get_film_size(
const CData *cdata)
const {
759 if ((cdata->_comp_flags & CF_film_size) == 0) {
763 ((
Lens *)
this)->do_compute_film_size((CData *)cdata);
765 return cdata->_film_size;
772do_set_focal_length(CData *cdata, PN_stdfloat focal_length) {
773 nassertv(!cnan(focal_length));
774 cdata->_focal_length = focal_length;
778 do_resequence_fov_triad(cdata, cdata->_focal_length_seq, cdata->_film_size_seq, cdata->_fov_seq);
780 if (cdata->_film_size_seq == 0) {
782 do_adjust_user_flags(cdata, UF_film_width | UF_film_height,
786 nassertv(cdata->_fov_seq == 0);
787 do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov,
791 do_adjust_comp_flags(cdata, CF_mat | CF_fov | CF_film_size,
793 do_throw_change_event(cdata);
800do_get_focal_length(
const CData *cdata)
const {
801 if ((cdata->_comp_flags & CF_focal_length) == 0) {
802 ((
Lens *)
this)->do_compute_focal_length((CData *)cdata);
804 return cdata->_focal_length;
811do_set_fov(CData *cdata, PN_stdfloat hfov) {
812 nassertv(!cnan(hfov));
813 cdata->_fov[0] = hfov;
817 do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq);
819 if (cdata->_focal_length_seq == 0) {
821 do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_min_fov,
825 nassertv(cdata->_film_size_seq == 0);
828 do_compute_aspect_ratio(cdata);
829 do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_vfov | UF_min_fov,
832 do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_film_size,
837 do_throw_change_event(cdata);
844do_set_fov(CData *cdata,
const LVecBase2 &fov) {
845 nassertv(!fov.is_nan());
850 do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq);
852 if (cdata->_focal_length_seq == 0) {
854 do_adjust_user_flags(cdata, UF_focal_length | UF_film_height | UF_min_fov | UF_aspect_ratio,
858 nassertv(cdata->_film_size_seq == 0);
859 do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_min_fov | UF_aspect_ratio,
862 do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_film_size | CF_aspect_ratio,
867 do_compute_aspect_ratio(cdata);
868 do_adjust_user_flags(cdata, 0, UF_aspect_ratio);
870 do_throw_change_event(cdata);
876const LVecBase2 &Lens::
877do_get_fov(
const CData *cdata)
const {
878 if ((cdata->_comp_flags & CF_fov) == 0) {
879 ((
Lens *)
this)->do_compute_fov((CData *)cdata);
888do_set_aspect_ratio(CData *cdata, PN_stdfloat aspect_ratio) {
889 nassertv(!cnan(aspect_ratio));
890 cdata->_aspect_ratio = aspect_ratio;
891 do_adjust_user_flags(cdata, UF_film_height | UF_vfov,
893 do_adjust_comp_flags(cdata, CF_mat | CF_film_size | CF_fov | CF_focal_length,
895 do_throw_change_event(cdata);
902do_get_aspect_ratio(
const CData *cdata)
const {
903 if ((cdata->_comp_flags & CF_aspect_ratio) == 0) {
904 ((
Lens *)
this)->do_compute_aspect_ratio((CData *)cdata);
906 return cdata->_aspect_ratio;
912const LMatrix4 &Lens::
913do_get_projection_mat(
const CData *cdata, StereoChannel channel)
const {
914 if ((cdata->_comp_flags & CF_projection_mat) == 0) {
915 ((
Lens *)
this)->do_compute_projection_mat((CData *)cdata);
920 return cdata->_projection_mat_left;
922 return cdata->_projection_mat_right;
925 return cdata->_projection_mat;
928 return cdata->_projection_mat;
934const LMatrix4 &Lens::
935do_get_projection_mat_inv(
const CData *cdata, StereoChannel stereo_channel)
const {
936 switch (stereo_channel) {
939 if ((cdata->_comp_flags & CF_projection_mat_left_inv) == 0) {
940 const LMatrix4 &projection_mat_left = do_get_projection_mat(cdata, SC_left);
941 ((CData *)cdata)->_projection_mat_left_inv.invert_from(projection_mat_left);
942 ((
Lens *)
this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_left_inv);
945 return cdata->_projection_mat_left_inv;
949 if ((cdata->_comp_flags & CF_projection_mat_right_inv) == 0) {
950 const LMatrix4 &projection_mat_right = do_get_projection_mat(cdata, SC_right);
951 ((CData *)cdata)->_projection_mat_right_inv.invert_from(projection_mat_right);
952 ((
Lens *)
this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_right_inv);
955 return cdata->_projection_mat_right_inv;
962 if ((cdata->_comp_flags & CF_projection_mat_inv) == 0) {
963 const LMatrix4 &projection_mat = do_get_projection_mat(cdata);
964 ((CData *)cdata)->_projection_mat_inv.invert_from(projection_mat);
965 ((
Lens *)
this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_inv);
967 return cdata->_projection_mat_inv;
973const LMatrix4 &Lens::
974do_get_film_mat(
const CData *cdata)
const {
975 if ((cdata->_comp_flags & CF_film_mat) == 0) {
976 ((
Lens *)
this)->do_compute_film_mat((CData *)cdata);
978 return cdata->_film_mat;
984const LMatrix4 &Lens::
985do_get_film_mat_inv(
const CData *cdata)
const {
986 if ((cdata->_comp_flags & CF_film_mat_inv) == 0) {
987 const LMatrix4 &film_mat = do_get_film_mat(cdata);
988 ((CData *)cdata)->_film_mat_inv.invert_from(film_mat);
989 ((
Lens *)
this)->do_adjust_comp_flags((CData *)cdata, 0, CF_film_mat_inv);
991 return cdata->_film_mat_inv;
997const LMatrix4 &Lens::
998do_get_lens_mat(
const CData *cdata)
const {
999 if ((cdata->_comp_flags & CF_lens_mat) == 0) {
1000 ((
Lens *)
this)->do_compute_lens_mat((CData *)cdata);
1002 return cdata->_lens_mat;
1008const LMatrix4 &Lens::
1009do_get_lens_mat_inv(
const CData *cdata)
const {
1010 if ((cdata->_comp_flags & CF_lens_mat_inv) == 0) {
1011 const LMatrix4 &lens_mat = do_get_lens_mat(cdata);
1012 ((CData *)cdata)->_lens_mat_inv.invert_from(lens_mat);
1013 ((
Lens *)
this)->do_adjust_comp_flags((CData *)cdata, 0, CF_lens_mat_inv);
1015 return cdata->_lens_mat_inv;
1022do_set_interocular_distance(CData *cdata, PN_stdfloat interocular_distance) {
1023 nassertv(!cnan(interocular_distance));
1024 cdata->_interocular_distance = interocular_distance;
1025 if (cdata->_interocular_distance == 0.0f) {
1026 do_adjust_user_flags(cdata, UF_interocular_distance, 0);
1028 do_adjust_user_flags(cdata, 0, UF_interocular_distance);
1031 do_adjust_comp_flags(cdata, CF_mat, 0);
1038do_set_convergence_distance(CData *cdata, PN_stdfloat convergence_distance) {
1039 nassertv(!cnan(convergence_distance));
1040 cdata->_convergence_distance = convergence_distance;
1041 if (cdata->_convergence_distance == 0.0f) {
1042 do_adjust_user_flags(cdata, UF_convergence_distance, 0);
1044 do_adjust_user_flags(cdata, 0, UF_convergence_distance);
1047 do_adjust_comp_flags(cdata, CF_mat, 0);
1054do_set_view_mat(CData *cdata,
const LMatrix4 &view_mat) {
1055 nassertv(!view_mat.is_nan());
1056 cdata->_lens_mat = view_mat;
1057 do_adjust_user_flags(cdata, UF_view_vector | UF_view_hpr,
1059 do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv |
1060 CF_projection_mat_left_inv | CF_projection_mat_right_inv |
1061 CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
1063 do_throw_change_event(cdata);
1069const LMatrix4 &Lens::
1070do_get_view_mat(
const CData *cdata)
const {
1071 if ((cdata->_comp_flags & CF_lens_mat) == 0) {
1072 ((
Lens *)
this)->do_compute_lens_mat((CData *)cdata);
1074 return cdata->_lens_mat;
1081do_throw_change_event(CData *cdata) {
1082 ++(cdata->_last_change);
1084 if (!cdata->_change_event.empty()) {
1085 throw_event(cdata->_change_event,
this);
1088 if (!cdata->_geom_data.is_null()) {
1089 if (cdata->_geom_data->get_ref_count() == 1) {
1092 cdata->_geom_data.clear();
1095 do_define_geom_data(cdata);
1112do_extrude(
const CData *cdata,
1113 const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point)
const {
1114 const LMatrix4 &projection_mat_inv = do_get_projection_mat_inv(cdata);
1116 LVecBase4 full(point2d[0], point2d[1], -1.0f, 1.0f);
1117 full = projection_mat_inv.xform(full);
1119 PN_stdfloat recip_full3 = 1.0 / max((
double)full[3], (
double)lens_far_limit);
1120 near_point.set(full[0] * recip_full3,
1121 full[1] * recip_full3,
1122 full[2] * recip_full3);
1125 LVecBase4 full(point2d[0], point2d[1], 1.0f, 1.0f);
1126 full = projection_mat_inv.xform(full);
1132 PN_stdfloat recip_full3 = 1.0 / max((
double)full[3], (
double)lens_far_limit);
1133 far_point.set(full[0] * recip_full3,
1134 full[1] * recip_full3,
1135 full[2] * recip_full3);
1146do_extrude_depth(
const CData *cdata,
1147 const LPoint3 &point2d, LPoint3 &point3d)
const {
1148 LPoint3 near_point, far_point;
1149 bool result =
extrude(point2d, near_point, far_point);
1153 PN_stdfloat t = point2d[2] * 0.5 + 0.5;
1154 point3d = near_point + (far_point - near_point) * t;
1163do_extrude_depth_with_mat(
const CData *cdata,
1164 const LPoint3 &point2d, LPoint3 &point3d)
const {
1165 const LMatrix4 &projection_mat_inv = do_get_projection_mat_inv(cdata);
1166 point3d = projection_mat_inv.xform_point_general(point2d);
1192do_extrude_vec(
const CData *cdata,
const LPoint3 &point2d, LVector3 &vec)
const {
1193 vec = LVector3::forward(cdata->_cs) * do_get_lens_mat(cdata);
1212do_project(
const CData *cdata,
const LPoint3 &point3d, LPoint3 &point2d)
const {
1213 const LMatrix4 &projection_mat = do_get_projection_mat(cdata);
1214 LVecBase4 full(point3d[0], point3d[1], point3d[2], 1.0f);
1215 full = projection_mat.xform(full);
1216 if (full[3] == 0.0f) {
1217 point2d.set(0.0f, 0.0f, 0.0f);
1220 PN_stdfloat recip_full3 = 1.0f/full[3];
1221 point2d.set(full[0] * recip_full3, full[1] * recip_full3, full[2] * recip_full3);
1224 (point2d[0] >= -1.0f - NEARLY_ZERO(PN_stdfloat)) && (point2d[0] <= 1.0f + NEARLY_ZERO(PN_stdfloat)) &&
1225 (point2d[1] >= -1.0f - NEARLY_ZERO(PN_stdfloat)) && (point2d[1] <= 1.0f + NEARLY_ZERO(PN_stdfloat));
1233do_compute_film_size(CData *cdata) {
1234 if ((cdata->_user_flags & (UF_min_fov | UF_focal_length)) == (UF_min_fov | UF_focal_length)) {
1238 PN_stdfloat fs = fov_to_film(cdata->_min_fov, cdata->_focal_length,
true);
1239 nassertv((cdata->_user_flags & UF_aspect_ratio) != 0 ||
1240 (cdata->_comp_flags & CF_aspect_ratio) != 0);
1242 if (cdata->_aspect_ratio < 1.0f) {
1243 cdata->_film_size[1] = fs / cdata->_aspect_ratio;
1244 cdata->_film_size[0] = fs;
1247 cdata->_film_size[0] = fs * cdata->_aspect_ratio;
1248 cdata->_film_size[1] = fs;
1252 if ((cdata->_user_flags & UF_film_width) == 0) {
1253 if ((cdata->_user_flags & (UF_hfov | UF_focal_length)) == (UF_hfov | UF_focal_length)) {
1254 cdata->_film_size[0] = fov_to_film(cdata->_fov[0], cdata->_focal_length,
true);
1256 cdata->_film_size[0] = 1.0f;
1260 if ((cdata->_user_flags & UF_film_height) == 0) {
1261 if ((cdata->_user_flags & (UF_vfov | UF_focal_length)) == (UF_vfov | UF_focal_length)) {
1262 cdata->_film_size[1] = fov_to_film(cdata->_fov[1], cdata->_focal_length,
false);
1264 }
else if ((cdata->_user_flags & (UF_hfov | UF_vfov)) == (UF_hfov | UF_vfov)) {
1268 if ((cdata->_comp_flags & CF_focal_length) == 0) {
1269 cdata->_focal_length = fov_to_focal_length(cdata->_fov[0], cdata->_film_size[0],
true);
1270 do_adjust_comp_flags(cdata, 0, CF_focal_length);
1272 cdata->_film_size[1] = fov_to_film(cdata->_fov[1], cdata->_focal_length,
false);
1274 }
else if ((cdata->_user_flags & UF_aspect_ratio) != 0 ||
1275 (cdata->_comp_flags & CF_aspect_ratio) != 0) {
1276 cdata->_film_size[1] = cdata->_film_size[0] / cdata->_aspect_ratio;
1280 cdata->_film_size[1] = cdata->_film_size[0];
1285 do_adjust_comp_flags(cdata, 0, CF_film_size);
1293do_compute_focal_length(CData *cdata) {
1294 if ((cdata->_user_flags & UF_focal_length) == 0) {
1295 const LVecBase2 &film_size = do_get_film_size(cdata);
1296 const LVecBase2 &fov = do_get_fov(cdata);
1297 cdata->_focal_length = fov_to_focal_length(fov[0], film_size[0],
true);
1300 do_adjust_comp_flags(cdata, 0, CF_focal_length);
1308do_compute_fov(CData *cdata) {
1309 const LVecBase2 &film_size = do_get_film_size(cdata);
1311 bool got_hfov = ((cdata->_user_flags & UF_hfov) != 0);
1312 bool got_vfov = ((cdata->_user_flags & UF_vfov) != 0);
1313 bool got_min_fov = ((cdata->_user_flags & UF_min_fov) != 0);
1315 if (!got_hfov && !got_vfov && !got_min_fov) {
1317 if ((cdata->_user_flags & UF_focal_length) != 0) {
1319 cdata->_fov[0] = film_to_fov(film_size[0], cdata->_focal_length,
true);
1320 cdata->_fov[1] = film_to_fov(film_size[1], cdata->_focal_length,
true);
1326 cdata->_min_fov = default_fov;
1333 if (film_size[0] < film_size[1]) {
1334 cdata->_fov[0] = cdata->_min_fov;
1337 cdata->_fov[1] = cdata->_min_fov;
1344 if ((cdata->_user_flags & UF_focal_length) == 0 &&
1345 (cdata->_comp_flags & CF_focal_length) == 0) {
1349 cdata->_focal_length = fov_to_focal_length(cdata->_fov[1], film_size[1],
true);
1350 do_adjust_comp_flags(cdata, 0, CF_focal_length);
1352 cdata->_fov[0] = film_to_fov(film_size[0], cdata->_focal_length,
false);
1357 if ((cdata->_user_flags & UF_focal_length) == 0 &&
1358 (cdata->_comp_flags & CF_focal_length) == 0) {
1362 cdata->_focal_length = fov_to_focal_length(cdata->_fov[0], film_size[0],
true);
1363 do_adjust_comp_flags(cdata, 0, CF_focal_length);
1365 cdata->_fov[1] = film_to_fov(film_size[1], cdata->_focal_length,
false);
1370 cdata->_min_fov = film_size[0] < film_size[1] ? cdata->_fov[0] : cdata->_fov[1];
1374 nassertv(got_hfov && got_vfov && got_min_fov);
1375 do_adjust_comp_flags(cdata, 0, CF_fov);
1383do_compute_aspect_ratio(CData *cdata) {
1384 if ((cdata->_user_flags & UF_aspect_ratio) == 0) {
1385 const LVecBase2 &film_size = do_get_film_size(cdata);
1386 if (film_size[1] == 0.0f) {
1387 cdata->_aspect_ratio = 1.0f;
1389 cdata->_aspect_ratio = film_size[0] / film_size[1];
1392 do_adjust_comp_flags(cdata, 0, CF_aspect_ratio);
1399do_compute_view_hpr(CData *cdata) {
1400 if ((cdata->_user_flags & UF_view_hpr) == 0) {
1401 const LMatrix4 &view_mat = do_get_view_mat(cdata);
1402 LVecBase3 scale, shear, translate;
1403 decompose_matrix(view_mat, scale, shear, cdata->_view_hpr, translate, cdata->_cs);
1405 do_adjust_comp_flags(cdata, 0, CF_view_hpr);
1412do_compute_view_vector(CData *cdata) {
1413 if ((cdata->_user_flags & UF_view_vector) == 0) {
1414 const LMatrix4 &view_mat = do_get_view_mat(cdata);
1415 cdata->_view_vector = LVector3::forward(cdata->_cs) * view_mat;
1416 cdata->_up_vector = LVector3::up(cdata->_cs) * view_mat;
1418 do_adjust_comp_flags(cdata, 0, CF_view_vector);
1426do_compute_projection_mat(CData *lens_cdata) {
1434 CoordinateSystem cs = lens_cdata->_cs;
1435 if (cs == CS_default) {
1436 cs = get_default_coordinate_system();
1438 lens_cdata->_projection_mat = LMatrix4::convert_mat(cs, CS_zup_right);
1439 lens_cdata->_projection_mat_inv = LMatrix4::convert_mat(CS_zup_right, cs);
1443 lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat;
1444 lens_cdata->_projection_mat_left_inv = lens_cdata->_projection_mat_right_inv = lens_cdata->_projection_mat_inv;
1446 do_adjust_comp_flags(lens_cdata, 0, CF_projection_mat | CF_projection_mat_inv |
1447 CF_projection_mat_left_inv | CF_projection_mat_right_inv);
1455do_compute_film_mat(CData *cdata) {
1461 LVecBase2 film_size = do_get_film_size(cdata);
1462 LVector2 film_offset = do_get_film_offset(cdata);
1464 PN_stdfloat scale_x = 2.0f / film_size[0];
1465 PN_stdfloat scale_y = 2.0f / film_size[1];
1466 cdata->_film_mat.set(scale_x, 0.0f, 0.0f, 0.0f,
1467 0.0f, scale_y, 0.0f, 0.0f,
1468 0.0f, 0.0f, 1.0f, 0.0f,
1469 -film_offset[0] * scale_x, -film_offset[1] * scale_y, 0.0f, 1.0f);
1471 if ((cdata->_user_flags & UF_keystone) != 0) {
1472 cdata->_film_mat = LMatrix4(1.0f, 0.0f, cdata->_keystone[0], cdata->_keystone[0],
1473 0.0f, 1.0f, cdata->_keystone[1], cdata->_keystone[1],
1474 0.0f, 0.0f, 1.0f, 0.0f,
1475 0.0f, 0.0f, 0.0f, 1.0f) * cdata->_film_mat;
1478 if ((cdata->_user_flags & UF_custom_film_mat) != 0) {
1479 cdata->_film_mat = cdata->_film_mat * cdata->_custom_film_mat;
1482 do_adjust_comp_flags(cdata, CF_film_mat_inv, CF_film_mat);
1490do_compute_lens_mat(CData *cdata) {
1491 if ((cdata->_user_flags & UF_view_mat) == 0) {
1492 if ((cdata->_user_flags & UF_view_hpr) != 0) {
1493 compose_matrix(cdata->_lens_mat,
1494 LVecBase3(1.0f, 1.0f, 1.0f),
1495 LVecBase3(0.0f, 0.0f, 0.0f),
1497 LVecBase3(0.0f, 0.0f, 0.0f), cdata->_cs);
1499 }
else if ((cdata->_user_flags & UF_view_vector) != 0) {
1500 look_at(cdata->_lens_mat, cdata->_view_vector, cdata->_up_vector, cdata->_cs);
1503 cdata->_lens_mat = LMatrix4::ident_mat();
1506 do_adjust_comp_flags(cdata, CF_lens_mat_inv, CF_lens_mat);
1516fov_to_film(PN_stdfloat, PN_stdfloat,
bool)
const {
1527fov_to_focal_length(PN_stdfloat, PN_stdfloat,
bool)
const {
1538film_to_fov(PN_stdfloat, PN_stdfloat,
bool)
const {
1553do_resequence_fov_triad(
const CData *cdata,
char &newest,
char &older_a,
char &older_b)
const {
1554 nassertv(newest + older_a + older_b == 3);
1560 nassertv(older_a + older_b == 1);
1566 nassertv(older_b == 0);
1569 nassertv(older_a == 0 && older_b == 2);
1575 nassertv(older_a + older_b == 1);
1580 <<
"Invalid fov sequence numbers in lens: "
1581 << (int)newest <<
", " << (
int)older_a <<
", " << (int)older_b <<
"\n";
1586 if (gobj_cat.is_debug()) {
1588 <<
"Lens.do_resequence_fov_triad():";
1589 for (
int i = 2; i >= 0; --i) {
1590 if (cdata->_fov_seq == i) {
1591 gobj_cat.debug(
false)
1593 }
else if (cdata->_focal_length_seq == i) {
1594 gobj_cat.debug(
false)
1596 }
else if (cdata->_film_size_seq == i) {
1597 gobj_cat.debug(
false)
1601 gobj_cat.debug(
false)
1613do_define_geom_data(CData *cdata) {
1614 int num_segments = 1;
1616 num_segments = lens_geom_segments;
1619 if (cdata->_geom_data ==
nullptr) {
1624 cdata->_geom_data->unclean_set_num_rows(num_segments * 8 + 2);
1627 LPoint3 near_point, far_point;
1628 for (
int si = 0; si < num_segments; si++) {
1629 PN_stdfloat t = 2.0f * (PN_stdfloat)si / (PN_stdfloat)num_segments;
1632 LPoint3 p1(-1.0f + t, 1.0f, 0.0f);
1633 if (!do_extrude(cdata, p1, near_point, far_point)) {
1637 vertex.set_data3(near_point);
1638 vertex.set_data3(far_point);
1641 LPoint3 p2(1.0f, 1.0f - t, 0.0f);
1642 if (!do_extrude(cdata, p2, near_point, far_point)) {
1646 vertex.set_data3(near_point);
1647 vertex.set_data3(far_point);
1650 LPoint3 p3(1.0f - t, -1.0f, 0.0f);
1651 if (!do_extrude(cdata, p3, near_point, far_point)) {
1655 vertex.set_data3(near_point);
1656 vertex.set_data3(far_point);
1659 LPoint3 p4(-1.0f, -1.0f + t, 0.0f);
1660 if (!do_extrude(cdata, p4, near_point, far_point)) {
1664 vertex.set_data3(near_point);
1665 vertex.set_data3(far_point);
1672 if (!do_extrude(cdata, pc, near_point, far_point)) {
1673 vertex.set_data3(0.0f, 0.0f, 0.0f);
1674 vertex.set_data3(0.0f, 0.0f, 0.0f);
1676 vertex.set_data3(near_point);
1677 vertex.set_data3(far_point);
1680 return num_segments;
1688build_shear_mat(LMatrix4 &shear_mat,
1689 const LPoint3 &cul,
const LPoint3 &cur,
1690 const LPoint3 &cll,
const LPoint3 &clr) {
1695 LPoint3 points[4] = {
1699 PN_stdfloat max_edge_length = -1.0f;
1701 for (
int i = 0; i < 4; i++) {
1702 LVector3 edge = points[(i + 1) % 4] - points[i];
1703 PN_stdfloat length = edge.length_squared();
1704 if (length > max_edge_length) {
1706 max_edge_length = length;
1710 const LPoint3 &base_origin = points[base_edge];
1711 LVector3 base_vec = points[(base_edge + 1) % 4] - base_origin;
1713 PN_stdfloat base_edge_length = csqrt(max_edge_length);
1718 int a = (base_edge + 2) % 4;
1719 int b = (base_edge + 3) % 4;
1721 PN_stdfloat a_dist = sqr_dist_to_line(points[a], base_origin, base_vec);
1722 PN_stdfloat b_dist = sqr_dist_to_line(points[b], base_origin, base_vec);
1726 if (a_dist > b_dist) {
1728 dist = csqrt(a_dist);
1731 dist = csqrt(b_dist);
1736 LVector3 perpendic = base_vec.cross(LVector3(0.0f, -1.0f, 0.0f));
1737 perpendic.normalize();
1739 LPoint3 parallel_origin = points[base_edge] + perpendic;
1743 LVector3 base_norm_vec = base_vec / base_edge_length;
1745 LVector3 far_point_delta = points[far_point] - parallel_origin;
1746 PN_stdfloat far_point_pos = far_point_delta.dot(base_norm_vec);
1748 if (far_point_pos < 0.0f) {
1750 parallel_origin += base_norm_vec * far_point_pos;
1752 }
else if (far_point_pos > base_edge_length) {
1754 parallel_origin += base_norm_vec * (far_point_pos - base_edge_length);
1759 PN_stdfloat Ox = parallel_origin[0];
1760 PN_stdfloat Oy = parallel_origin[2];
1761 PN_stdfloat Vx = base_vec[0];
1762 PN_stdfloat Vy = base_vec[2];
1763 PN_stdfloat Ax, Ay, Bx, By;
1765 if (far_point == a) {
1767 LVector3 v = points[b] - base_origin;
1774 LVector3 v = points[a] - (base_origin + base_vec);
1780 t = ((Ox - Ax) * By + (Ay - Oy) * Bx) / (Bx * Vy - By * Vx);
1784 parallel_origin += base_vec * t;
1785 }
else if (t > 1.0f) {
1787 parallel_origin += base_vec * (1.0f - t);
1790 LVector3 adjacent_norm_vec = parallel_origin - base_origin;
1791 adjacent_norm_vec.normalize();
1795 shear_mat = LMatrix4::ident_mat();
1798 switch (base_edge) {
1802 shear_mat.set_row(0, base_norm_vec);
1803 shear_mat.set_row(2, -adjacent_norm_vec);
1809 shear_mat.set_row(0, -adjacent_norm_vec);
1810 shear_mat.set_row(2, -base_norm_vec);
1816 shear_mat.set_row(0, -base_norm_vec);
1817 shear_mat.set_row(2, adjacent_norm_vec);
1823 shear_mat.set_row(0, adjacent_norm_vec);
1824 shear_mat.set_row(2, base_norm_vec);
1837sqr_dist_to_line(
const LPoint3 &point,
const LPoint3 &origin,
1838 const LVector3 &vec) {
1839 LVector3 norm = vec;
1841 LVector3 d = point - origin;
1842 PN_stdfloat hyp_2 = d.length_squared();
1843 PN_stdfloat leg = d.dot(norm);
1844 return hyp_2 - leg * leg;
1879CData(
const Lens::CData ©) {
1880 _change_event = copy._change_event;
1882 _film_size = copy._film_size;
1883 _film_offset = copy._film_offset;
1884 _focal_length = copy._focal_length;
1886 _min_fov = copy._min_fov;
1887 _aspect_ratio = copy._aspect_ratio;
1888 _near_distance = copy._near_distance;
1889 _far_distance = copy._far_distance;
1891 _view_hpr = copy._view_hpr;
1892 _view_vector = copy._view_vector;
1893 _interocular_distance = copy._interocular_distance;
1894 _convergence_distance = copy._convergence_distance;
1895 _keystone = copy._keystone;
1900 _lens_mat = copy._lens_mat;
1902 _user_flags = copy._user_flags;
1905 _focal_length_seq = copy._focal_length_seq;
1906 _fov_seq = copy._fov_seq;
1907 _film_size_seq = copy._film_size_seq;
1909 _geom_data = copy._geom_data;
1917 return new CData(*
this);
1928 _film_size.write_datagram(dg);
1929 _film_offset.write_datagram(dg);
1931 _fov.write_datagram(dg);
1945 if (_user_flags & UF_view_hpr) {
1946 _view_hpr.write_datagram(dg);
1949 if (_user_flags & UF_view_vector) {
1950 _view_vector.write_datagram(dg);
1951 _up_vector.write_datagram(dg);
1954 if (_user_flags & UF_view_mat) {
1955 _lens_mat.write_datagram(dg);
1958 if (_user_flags & UF_keystone) {
1959 _keystone.write_datagram(dg);
1962 if (_user_flags & UF_custom_film_mat) {
1963 _custom_film_mat.write_datagram(dg);
1974 _cs = (CoordinateSystem)scan.
get_uint8();
1975 _film_size.read_datagram(scan);
1976 _film_offset.read_datagram(scan);
1978 _fov.read_datagram(scan);
1989 if (_user_flags & UF_view_hpr) {
1990 _view_hpr.read_datagram(scan);
1993 if (_user_flags & UF_view_vector) {
1994 _view_vector.read_datagram(scan);
1995 _up_vector.read_datagram(scan);
1998 if (_user_flags & UF_view_mat) {
1999 _lens_mat.read_datagram(scan);
2002 if (_user_flags & UF_keystone) {
2003 _keystone.read_datagram(scan);
2006 if (_user_flags & UF_custom_film_mat) {
2007 _custom_film_mat.read_datagram(scan);
2021 _film_size.set(1.0f, 1.0f);
2022 _film_offset.set(0.0f, 0.0f);
2023 _focal_length = 1.0f;
2024 _fov.set(default_fov, default_fov);
2025 _aspect_ratio = 1.0f;
2026 _near_distance = default_near;
2027 _far_distance = default_far;
2028 _view_hpr.set(0.0f, 0.0f, 0.0f);
2029 _view_vector.set(0.0f, 1.0f, 0.0f);
2030 _up_vector.set(0.0f, 0.0f, 1.0f);
2031 _keystone.set(0.0f, 0.0f);
2032 _custom_film_mat = LMatrix4::ident_mat();
2035 _comp_flags = CF_fov;
2037 _interocular_distance = 0.0;
2038 _convergence_distance = 0.0;
2041 _keystone.set(default_keystone[0], default_keystone[1]);
2042 _user_flags |= UF_keystone;
2047 _focal_length_seq = 1;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
This defines a bounding convex hexahedron.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
bool has_value() const
Returns true if this variable has an explicit value, either from a prc file or locally set,...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
const CycleDataType * p() const
This allows the CycleDataReader to be passed to any function that expects a const CycleDataType point...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
A class to retrieve the individual data elements previously stored in a Datagram.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
std::string get_string()
Extracts a variable-length string.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Defines a series of line strips.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
A base class for any number of different kinds of lenses, linear and otherwise.
get_view_hpr
Returns the direction in which the lens is facing.
static PN_stdfloat get_default_near()
Returns the default near plane distance that will be assigned to each newly-created lens.
static PN_stdfloat get_default_far()
Returns the default far plane distance that will be assigned to each newly- created lens.
bool extrude(const LPoint2 &point2d, LPoint3 &near_point, LPoint3 &far_point) const
Given a 2-d point in the range (-1,1) in both dimensions, where (0,0) is the center of the lens and (...
get_view_mat
Returns the direction in which the lens is facing.
void set_custom_film_mat(const LMatrix4 &custom_film_mat)
Specifies a custom matrix to transform the points on the film after they have been converted into nom...
void clear()
Resets all lens parameters to their initial default settings.
void set_view_vector(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat i, PN_stdfloat j, PN_stdfloat k)
Specifies the direction in which the lens is facing by giving an axis to look along,...
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
void set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, const LVecBase3 &ll, const LVecBase3 &lr, int flags)
Sets up the lens to use the frustum defined by the four indicated points.
void clear_keystone()
Disables the lens keystone correction.
set_view_hpr
Sets the direction in which the lens is facing.
set_keystone
Indicates the ratio of keystone correction to perform on the lens, in each of three axes.
get_min_fov
Returns the field of view of the narrowest dimension of the window.
void recompute_all()
Forces all internal parameters of the Lens to be recomputed.
set_coordinate_system
Specifies the coordinate system that all 3-d computations are performed within for this Lens.
virtual bool is_orthographic() const
Returns true if the lens represents a orthographic projection (i.e.
const LVector3 & get_up_vector() const
Returns the axis perpendicular to the camera's view vector that indicates the "up" direction.
virtual bool is_perspective() const
Returns true if the lens represents a perspective projection (i.e.
set_min_fov
Sets the field of view of the smallest dimension of the window.
void clear_view_mat()
Resets the lens transform to identity.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
get_nodal_point
Returns the center point of the lens: the point from which the lens is viewing.
get_fov
Returns the horizontal and vertical film size of the virtual film.
void clear_custom_film_mat()
Disables the lens custom_film_mat correction.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
TypeHandle is the identifier used to differentiate C++ class types.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.