44 Lens(
const Lens ©) : _cycler(copy._cycler) {
46 CDWriter cdata(_cycler,
true);
47 cdata->_geom_data =
nullptr;
54 operator = (
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);
134 get_min_fov()
const {
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);
182 const LVecBase3 &Lens::
183 get_view_hpr()
const {
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;
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;
240 get_nodal_point()
const {
241 return get_view_mat().get_row3(3);
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);
642 make_bounds()
const {
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)) {
682 output(std::ostream &out)
const {
690 write(std::ostream &out,
int indent_level)
const {
691 indent(out, indent_level) << get_type() <<
" fov = " <<
get_fov() <<
"\n";
698 do_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);
725 do_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);
757 const LVecBase2 &Lens::
758 do_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;
772 do_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);
800 do_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;
811 do_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);
844 do_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);
876 const LVecBase2 &Lens::
877 do_get_fov(
const CData *cdata)
const {
878 if ((cdata->_comp_flags & CF_fov) == 0) {
879 ((
Lens *)
this)->do_compute_fov((CData *)cdata);
888 do_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);
902 do_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;
912 const LMatrix4 &Lens::
913 do_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;
934 const LMatrix4 &Lens::
935 do_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;
973 const LMatrix4 &Lens::
974 do_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;
984 const LMatrix4 &Lens::
985 do_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;
997 const LMatrix4 &Lens::
998 do_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;
1008 const LMatrix4 &Lens::
1009 do_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;
1022 do_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);
1038 do_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);
1054 do_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);
1069 const LMatrix4 &Lens::
1070 do_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;
1081 do_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);
1112 do_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);
1146 do_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;
1163 do_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);
1192 do_extrude_vec(
const CData *cdata,
const LPoint3 &point2d, LVector3 &vec)
const {
1193 vec = LVector3::forward(cdata->_cs) * do_get_lens_mat(cdata);
1212 do_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) && (point2d[0] <= 1.0f) &&
1225 (point2d[1] >= -1.0f) && (point2d[1] <= 1.0f);
1233 do_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);
1293 do_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);
1308 do_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);
1383 do_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);
1399 do_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);
1412 do_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);
1426 do_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);
1455 do_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);
1490 do_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);
1516 fov_to_film(PN_stdfloat, PN_stdfloat,
bool)
const {
1527 fov_to_focal_length(PN_stdfloat, PN_stdfloat,
bool)
const {
1538 film_to_fov(PN_stdfloat, PN_stdfloat,
bool)
const {
1553 do_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)
1613 do_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;
1688 build_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);
1837 sqr_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;
1879 CData(
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;
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
const CycleDataType * p() const
This allows the CycleDataReader to be passed to any function that expects a const CycleDataType point...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
A base class for any number of different kinds of lenses, linear and otherwise.
virtual bool is_orthographic() const
Returns true if the lens represents a orthographic projection (i.e.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
void clear()
Resets all lens parameters to their initial default settings.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_view_hpr
Sets the direction in which the lens is facing.
A single page of data maintained by a PipelineCycler.
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
PT(Geom) Lens
Allocates and returns a new Geom that can be rendered to show a visible representation of the frustum...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_min_fov
Sets the field of view of the smallest dimension of the window.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
set_coordinate_system
Specifies the coordinate system that all 3-d computations are performed within for this Lens.
std::string get_string()
Extracts a variable-length string.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
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.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
static PN_stdfloat get_default_far()
Returns the default far plane distance that will be assigned to each newly- created lens.
const LVector3 & get_up_vector() const
Returns the axis perpendicular to the camera's view vector that indicates the "up" direction.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
get_fov
Returns the horizontal and vertical film size of the virtual film.
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 add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
virtual bool is_perspective() const
Returns true if the lens represents a perspective projection (i.e.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
A container for geometry primitives.
static PN_stdfloat get_default_near()
Returns the default near plane distance that will be assigned to each newly-created lens.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
bool has_value() const
Returns true if this variable has an explicit value, either from a prc file or locally set,...
Defines a series of line strips.
void recompute_all()
Forces all internal parameters of the Lens to be recomputed.
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 (...
void clear_keystone()
Disables the lens keystone correction.
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
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,...
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines a bounding convex hexahedron.
set_keystone
Indicates the ratio of keystone correction to perform on the lens, in each of three axes.
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_view_mat()
Resets the lens transform to identity.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.