39 _keep_beyond_lens =
false;
53 nassertv(_pfm.is_valid());
55 static LMatrix4 to_uv(0.5f, 0.0f, 0.0f, 0.0f,
56 0.0f, 0.5f, 0.0f, 0.0f,
57 0.0f, 0.0f, 0.5f, 0.0f,
58 0.5f, 0.5f, 0.5f, 1.0f);
60 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
61 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
68 if (!lens->
project(LCAST(PN_stdfloat, p), film) && !_keep_beyond_lens) {
72 _pfm.
set_point4(xi, yi, LVecBase4f(0, 0, 0, 0));
77 LPoint3f uvw = LCAST(
float, film * to_uv);
79 if (undist_lut !=
nullptr) {
84 uvw[1] = 1.0 - uvw[1];
104 nassertv(_pfm.is_valid());
106 static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0,
109 -1.0, -1.0, -1.0, 1.0);
125 LPoint2 uv_scale(1.0, 1.0);
127 uv_scale[0] = 1.0 / PN_stdfloat(_pfm.
get_x_size());
130 uv_scale[1] = 1.0 / PN_stdfloat(_pfm.
get_y_size());
132 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
133 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
138 p.set(((PN_stdfloat)xi + 0.5) * uv_scale[0],
139 ((PN_stdfloat)yi + 0.5) * uv_scale[1],
142 from_uv.xform_point_in_place(p);
143 rp = proj_mat_inv.xform_point_general(p);
149 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
150 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
155 p = LCAST(PN_stdfloat, _pfm.
get_point(xi, yi));
157 from_uv.xform_point_in_place(p);
158 rp = proj_mat_inv.xform_point_general(p);
168 LPoint2 uv_scale(1.0, 1.0);
170 uv_scale[0] = 1.0 / PN_stdfloat(_pfm.
get_x_size());
173 uv_scale[1] = 1.0 / PN_stdfloat(_pfm.
get_y_size());
175 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
176 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
181 p.set(((PN_stdfloat)xi + 0.5) * uv_scale[0],
182 ((PN_stdfloat)yi + 0.5) * uv_scale[1],
185 from_uv.xform_point_in_place(p);
192 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
193 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
198 p = LCAST(PN_stdfloat, _pfm.
get_point(xi, yi));
200 from_uv.xform_point_in_place(p);
217 _vis_columns.clear();
237 add_vis_column(_vis_columns, source, target, name, transform, lens, undist_lut);
247 nassertr(_pfm.is_valid(),
NodePath());
249 bool check_aux_pfm = uses_aux_pfm();
250 nassertr(!check_aux_pfm || (_aux_pfm !=
nullptr && _aux_pfm->is_valid()),
NodePath());
260 (InternalName::get_vertex(), 3,
261 Geom::NT_stdfloat, Geom::C_point,
262 InternalName::get_texcoord(), 3,
263 Geom::NT_stdfloat, Geom::C_texcoord);
264 format = GeomVertexFormat::register_format(v3t3);
271 (
"points", format, Geom::UH_static);
276 LPoint2f uv_scale(1.0, 1.0);
278 uv_scale[0] = 1.0f / PN_float32(_pfm.
get_x_size());
281 uv_scale[1] = 1.0f / PN_float32(_pfm.
get_y_size());
285 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
286 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
290 if (check_aux_pfm && !_aux_pfm->
has_point(xi, yi)) {
294 const LPoint3f &point = _pfm.
get_point(xi, yi);
295 LPoint2f uv((PN_float32(xi) + 0.5) * uv_scale[0],
296 (PN_float32(yi) + 0.5) * uv_scale[1]);
300 }
else if (_vis_2d) {
313 points->add_next_vertices(num_points);
314 geom->add_primitive(points);
317 gnode->add_geom(geom);
328 nassertr(_pfm.is_valid(),
NodePath());
329 nassertr(!uses_aux_pfm() || (_aux_pfm !=
nullptr && _aux_pfm->is_valid()),
NodePath());
349 if (face & MF_front) {
350 make_vis_mesh_geom(gnode,
false);
353 if (face & MF_back) {
354 make_vis_mesh_geom(gnode,
true);
373 for (
int yi = 0; yi < y_size; ++yi) {
374 for (
int xi = 0; xi < x_size; ++xi) {
379 const LPoint3f &point = _pfm.
get_point(xi, yi);
380 double nxi = point[0] * (double)x_size - 0.5;
382 max_u = max(max_u, cabs(nxi - (
double)xi));
401 for (
int yi = 0; yi < y_size; ++yi) {
402 for (
int xi = 0; xi < x_size; ++xi) {
407 const LPoint3f &point = _pfm.
get_point(xi, yi);
408 double nyi = point[1] * (double)y_size - 0.5;
410 max_v = max(max_v, cabs(nyi - (
double)yi));
439 result.
clear(x_size, y_size, 3, PNM_MAXMAXVAL);
440 result.
fill_val(0, 0, PNM_MAXMAXVAL);
444 static const int midval = (PNM_MAXMAXVAL + 1) / 2;
450 scale_factor = ae_undershift_factor_32;
455 scale_factor = ae_undershift_factor_16;
458 double u_scale = scale_factor * 0.5 * PNM_MAXMAXVAL / max_u;
459 double v_scale = scale_factor * 0.5 * PNM_MAXMAXVAL / max_v;
461 for (
int yi = 0; yi < y_size; ++yi) {
462 for (
int xi = 0; xi < x_size; ++xi) {
467 const LPoint3f &point = _pfm.
get_point(xi, yi);
468 double nxi = point[0] * (double)x_size - 0.5;
469 double nyi = point[1] * (double)y_size - 0.5;
471 double x_shift = (nxi - (double)xi);
472 double y_shift = (nyi - (double)yi);
474 int u_val = midval + (int)cfloor(x_shift * u_scale + 0.5);
475 int v_val = midval + (int)cfloor(y_shift * v_scale + 0.5);
479 min(max(u_val, 0), PNM_MAXMAXVAL),
480 min(max(v_val, 0), PNM_MAXMAXVAL),
486 for (
int yi = 0; yi < y_size; ++yi) {
487 for (
int xi = 0; xi < x_size; ++xi) {
492 const LPoint3f &point = _pfm.
get_point(xi, yi);
493 double nxi = point[0] * (double)x_size - 0.5;
494 double nyi = point[1] * (double)y_size - 0.5;
496 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, 1);
497 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, 1);
498 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, 1);
499 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, 1);
504 for (
int yi = 0; yi < y_size; ++yi) {
505 for (
int xi = 0; xi < x_size; ++xi) {
533 result.
clear(x_size, y_size, 3);
539 scale_factor = ae_undershift_factor_32;
544 scale_factor = ae_undershift_factor_16;
547 double u_scale = scale_factor * 0.5 / max_u;
548 double v_scale = scale_factor * 0.5 / max_v;
550 for (
int yi = 0; yi < y_size; ++yi) {
551 for (
int xi = 0; xi < x_size; ++xi) {
556 const LPoint3f &point = _pfm.
get_point(xi, yi);
557 double nxi = point[0] * (double)x_size - 0.5;
558 double nyi = point[1] * (double)y_size - 0.5;
560 double x_shift = (nxi - (double)xi);
561 double y_shift = (nyi - (double)yi);
563 float u_val = 0.5 + (float)(x_shift * u_scale);
564 float v_val = 0.5 + (float)(y_shift * v_scale);
567 result.
set_point3(xi, yi, LVecBase3f(u_val, v_val, 0));
572 for (
int yi = 0; yi < y_size; ++yi) {
573 for (
int xi = 0; xi < x_size; ++xi) {
578 const LPoint3f &point = _pfm.
get_point(xi, yi);
579 double nxi = point[0] * (double)x_size - 0.5;
580 double nyi = point[1] * (double)y_size - 0.5;
582 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, 1);
583 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, 1);
584 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, 1);
585 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, 1);
590 for (
int yi = 0; yi < y_size; ++yi) {
591 for (
int xi = 0; xi < x_size; ++xi) {
602 uses_aux_pfm()
const {
603 for (VisColumns::const_iterator vci = _vis_columns.begin();
604 vci != _vis_columns.end();
606 const VisColumn &column = *vci;
607 switch (column._source) {
626 r_fill_displacement(
PNMImage &result,
int xi,
int yi,
627 double nxi,
double nyi,
double u_scale,
double v_scale,
628 int distance)
const {
629 if (xi < 0 || yi < 0 ||
635 if (distance > 1000) {
641 if (val > distance) {
643 static const int midval = (PNM_MAXMAXVAL + 1) / 2;
645 double x_shift = (nxi - (double)xi);
646 double y_shift = (nyi - (double)yi);
647 int u_val = midval + (int)cfloor(x_shift * u_scale + 0.5);
648 int v_val = midval + (int)cfloor(y_shift * v_scale + 0.5);
650 min(max(u_val, 0), PNM_MAXMAXVAL),
651 min(max(v_val, 0), PNM_MAXMAXVAL),
652 min(distance, PNM_MAXMAXVAL));
654 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
655 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
656 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, distance + 1);
657 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, distance + 1);
667 r_fill_displacement(
PfmFile &result,
int xi,
int yi,
668 double nxi,
double nyi,
double u_scale,
double v_scale,
669 int distance)
const {
670 if (xi < 0 || yi < 0 ||
676 if (distance > 1000) {
682 if (val > (
float)distance) {
684 double x_shift = (nxi - (double)xi);
685 double y_shift = (nyi - (double)yi);
686 float u_val = 0.5 + (float)(x_shift * u_scale);
687 float v_val = 0.5 + (float)(y_shift * v_scale);
688 result.
set_point3(xi, yi, LVecBase3f(u_val, v_val, distance));
690 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
691 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
692 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, distance + 1);
693 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, distance + 1);
702 make_vis_mesh_geom(
GeomNode *gnode,
bool inverted)
const {
703 static const bool keep_beyond_lens =
true;
711 int num_vertices = x_size * y_size;
712 if (num_vertices == 0) {
717 bool reverse_normals = inverted;
718 bool reverse_faces = inverted;
719 if (!is_right_handed(get_default_coordinate_system())) {
720 reverse_faces = !reverse_faces;
726 int max_indices = (x_size - 1) * (y_size - 1) * 6;
728 while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) {
730 if (num_x_cells > num_y_cells) {
736 x_size = (_pfm.
get_x_size() + num_x_cells - 1) / num_x_cells + 1;
737 y_size = (_pfm.
get_y_size() + num_y_cells - 1) / num_y_cells + 1;
739 num_vertices = x_size * y_size;
740 max_indices = (x_size - 1) * (y_size - 1) * 6;
744 if (grutil_cat.is_debug()) {
746 <<
"Generating mesh with " << num_x_cells <<
" x " << num_y_cells
750 VisColumns vis_columns = _vis_columns;
751 if (vis_columns.empty()) {
752 build_auto_vis_columns(vis_columns,
true);
754 bool check_aux_pfm = uses_aux_pfm();
758 for (
int yci = 0; yci < num_y_cells; ++yci) {
759 int y_begin = (yci * _pfm.
get_y_size()) / num_y_cells;
760 int y_end = ((yci + 1) * _pfm.
get_y_size()) / num_y_cells;
766 y_size = y_end - y_begin;
771 for (
int xci = 0; xci < num_x_cells; ++xci) {
772 int x_begin = (xci * _pfm.
get_x_size()) / num_x_cells;
773 int x_end = ((xci + 1) * _pfm.
get_x_size()) / num_x_cells;
775 x_size = x_end - x_begin;
780 num_vertices = x_size * y_size;
781 max_indices = (x_size - 1) * (y_size - 1) * 6;
783 std::ostringstream mesh_name;
784 mesh_name <<
"mesh_" << xci <<
"_" << yci;
786 (mesh_name.str(), format, Geom::UH_static);
788 vdata->set_num_rows(num_vertices);
790 char *skip_points =
new char[num_vertices];
791 memset(skip_points, 0,
sizeof(
char) * num_vertices);
794 for (VisColumns::const_iterator vci = vis_columns.begin();
795 vci != vis_columns.end();
797 const VisColumn &column = *vci;
801 for (
int yi = y_begin; yi < y_end; ++yi) {
802 for (
int xi = x_begin; xi < x_end; ++xi) {
803 if (!column.add_data(*
this, vwriter, xi, yi, reverse_normals)) {
804 skip_points[(yi - y_begin) * x_size + (xi - x_begin)] = (char)
true;
813 tris->reserve_num_vertices(max_indices);
815 for (
int yi = y_begin; yi < y_end - 1; ++yi) {
816 for (
int xi = x_begin; xi < x_end - 1; ++xi) {
824 if (check_aux_pfm && (!_aux_pfm->
has_point(xi, yi) ||
831 if (!keep_beyond_lens &&
832 (skip_points[(yi - y_begin) * x_size + (xi - x_begin)] ||
833 skip_points[(yi - y_begin + 1) * x_size + (xi - x_begin)] ||
834 skip_points[(yi - y_begin) * x_size + (xi - x_begin + 1)] ||
835 skip_points[(yi - y_begin + 1) * x_size + (xi - x_begin + 1)])) {
839 int xi0 = xi - x_begin;
840 int yi0 = yi - y_begin;
842 int vi0 = ((xi0) + (yi0) * x_size);
843 int vi1 = ((xi0) + (yi0 + 1) * x_size);
844 int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
845 int vi3 = ((xi0 + 1) + (yi0) * x_size);
848 tris->add_vertices(vi2, vi0, vi1);
849 tris->close_primitive();
851 tris->add_vertices(vi3, vi0, vi2);
852 tris->close_primitive();
854 tris->add_vertices(vi2, vi1, vi0);
855 tris->close_primitive();
857 tris->add_vertices(vi3, vi2, vi0);
858 tris->close_primitive();
862 geom->add_primitive(tris);
865 delete[] skip_points;
875 add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
879 column._source = source;
880 column._target = target;
882 column._transform = transform;
883 if (transform ==
nullptr) {
884 column._transform = TransformState::make_identity();
887 if (undist_lut !=
nullptr && undist_lut->is_valid()) {
888 column._undist_lut = undist_lut;
890 vis_columns.push_back(column);
900 build_auto_vis_columns(VisColumns &vis_columns,
bool for_points)
const {
906 add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex());
907 add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord());
909 add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex());
910 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
917 add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex());
918 add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord());
922 add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex());
923 add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal());
924 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
928 if (_flat_texcoord_name !=
nullptr) {
930 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name);
933 if (_vis_blend !=
nullptr) {
935 add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color());
943 make_array_format(
const VisColumns &vis_columns)
const {
946 for (VisColumns::const_iterator vci = vis_columns.begin();
947 vci != vis_columns.end();
949 const VisColumn &column = *vci;
952 int num_components = 0;
953 GeomEnums::NumericType numeric_type = GeomEnums::NT_float32;
954 GeomEnums::Contents contents = GeomEnums::C_point;
955 switch (column._target) {
958 numeric_type = GeomEnums::NT_float32;
959 contents = GeomEnums::C_texcoord;
964 numeric_type = GeomEnums::NT_float32;
965 contents = GeomEnums::C_texcoord;
971 numeric_type = GeomEnums::NT_float32;
972 contents = GeomEnums::C_point;
978 numeric_type = GeomEnums::NT_float32;
979 contents = GeomEnums::C_point;
985 numeric_type = GeomEnums::NT_float32;
986 contents = GeomEnums::C_point;
991 numeric_type = GeomEnums::NT_float32;
992 contents = GeomEnums::C_normal;
997 numeric_type = GeomEnums::NT_uint8;
998 contents = GeomEnums::C_color;
1001 nassertr(num_components != 0,
nullptr);
1003 array_format->add_column(name, num_components, numeric_type, contents);
1006 return GeomVertexFormat::register_format(array_format);
1013 bool PfmVizzer::VisColumn::
1016 bool success =
true;
1021 LPoint2f uv((PN_float32(xi) + 0.5) / PN_float32(pfm.
get_x_size()),
1022 (PN_float32(yi) + 0.5) / PN_float32(pfm.
get_y_size()));
1023 if (!transform_point(uv)) {
1032 LPoint3f uv((PN_float32(xi) + 0.5) / PN_float32(pfm.
get_x_size()),
1033 (PN_float32(yi) + 0.5) / PN_float32(pfm.
get_y_size()),
1035 if (!transform_point(uv)) {
1045 LPoint2f point(p, 0.0);
1046 if (!transform_point(point)) {
1053 case CT_aux_vertex1:
1057 LPoint2f point(p, 0.0);
1058 if (!transform_point(point)) {
1068 if (!transform_point(point)) {
1075 case CT_aux_vertex2:
1079 if (!transform_point(point)) {
1089 if (!transform_point(point)) {
1096 case CT_aux_vertex3:
1099 if (!transform_point(point)) {
1109 bool flip = reverse_normals;
1129 LVector3f n = LVector3f::zero();
1130 for (
int i = 0; i < 3; ++i) {
1131 const LPoint3f &v0 = v[i];
1132 const LPoint3f &v1 = v[(i + 1) % 3];
1133 n[0] += v0[1] * v1[2] - v0[2] * v1[1];
1134 n[1] += v0[2] * v1[0] - v0[0] * v1[2];
1135 n[2] += v0[0] * v1[1] - v0[1] * v1[0];
1151 if (!transform_vector(n)) {
1161 if (vis_blend !=
nullptr) {
1162 double gray = vis_blend->
get_gray(xi, yi);
1175 bool PfmVizzer::VisColumn::
1176 transform_point(LPoint2f &point)
const {
1177 bool success =
true;
1178 if (!_transform->is_identity()) {
1179 LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point);
1188 bool PfmVizzer::VisColumn::
1189 transform_point(LPoint3f &point)
const {
1190 bool success =
true;
1191 if (!_transform->is_identity()) {
1192 LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point);
1194 if (_lens !=
nullptr) {
1195 static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0,
1198 0.5, 0.5, 0.0, 1.0);
1200 if (!_lens->project(LCAST(PN_stdfloat, point), film)) {
1203 point = to_uv.xform_point(LCAST(PN_float32, film));
1206 if (_undist_lut !=
nullptr) {
1208 if (!_undist_lut->calc_bilinear_point(p, point[0], 1.0 - point[1])) {
1214 point[1] = 1.0 - point[1];
1224 bool PfmVizzer::VisColumn::
1225 transform_vector(LVector3f &vec)
const {
1226 if (!_transform->is_identity()) {
1227 LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec);