15 #include "pfmVizzer.h"
18 #include "geomVertexData.h"
19 #include "geomVertexFormat.h"
20 #include "geomPoints.h"
21 #include "geomTriangles.h"
22 #include "geomVertexWriter.h"
25 #include "config_grutil.h"
40 _keep_beyond_lens =
false;
58 nassertv(_pfm.is_valid());
60 static LMatrix4 to_uv(0.5f, 0.0f, 0.0f, 0.0f,
61 0.0f, 0.5f, 0.0f, 0.0f,
62 0.0f, 0.0f, 0.5f, 0.0f,
63 0.5f, 0.5f, 0.5f, 1.0f);
65 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
66 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
73 if (!lens->
project(LCAST(PN_stdfloat, p), film) && !_keep_beyond_lens) {
82 LPoint3f uvw = LCAST(
float, film * to_uv);
84 if (undist_lut != NULL) {
89 uvw[1] = 1.0 - uvw[1];
113 nassertv(_pfm.is_valid());
115 static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0,
118 -1.0, -1.0, -1.0, 1.0);
136 uv_scale[0] = 1.0 / PN_stdfloat(_pfm.
get_x_size());
139 uv_scale[1] = 1.0 / PN_stdfloat(_pfm.
get_y_size());
141 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
142 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
147 p.set(((PN_stdfloat)xi + 0.5) * uv_scale[0],
148 ((PN_stdfloat)yi + 0.5) * uv_scale[1],
151 from_uv.xform_point_in_place(p);
158 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
159 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
164 p = LCAST(PN_stdfloat, _pfm.
get_point(xi, yi));
166 from_uv.xform_point_in_place(p);
179 uv_scale[0] = 1.0 / PN_stdfloat(_pfm.
get_x_size());
182 uv_scale[1] = 1.0 / PN_stdfloat(_pfm.
get_y_size());
184 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
185 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
190 p.set(((PN_stdfloat)xi + 0.5) * uv_scale[0],
191 ((PN_stdfloat)yi + 0.5) * uv_scale[1],
194 from_uv.xform_point_in_place(p);
201 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
202 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
207 p = LCAST(PN_stdfloat, _pfm.
get_point(xi, yi));
209 from_uv.xform_point_in_place(p);
229 _vis_columns.clear();
253 InternalName *name,
const TransformState *transform,
255 add_vis_column(_vis_columns, source, target, name, transform, lens, undist_lut);
268 nassertr(_pfm.is_valid(),
NodePath());
270 bool check_aux_pfm = uses_aux_pfm();
271 nassertr(!check_aux_pfm || (_aux_pfm != NULL && _aux_pfm->is_valid()),
NodePath());
273 CPT(GeomVertexFormat) format;
276 format = GeomVertexFormat::get_v3t2();
280 GeomVertexArrayFormat *v3t3 =
new GeomVertexArrayFormat
281 (InternalName::get_vertex(), 3,
282 Geom::NT_stdfloat, Geom::C_point,
283 InternalName::get_texcoord(), 3,
284 Geom::NT_stdfloat, Geom::C_texcoord);
285 format = GeomVertexFormat::register_format(v3t3);
288 format = GeomVertexFormat::get_v3t2();
292 (
"points", format, Geom::UH_static);
299 uv_scale[0] = 1.0f / PN_float32(_pfm.
get_x_size());
302 uv_scale[1] = 1.0f / PN_float32(_pfm.
get_y_size());
306 for (
int yi = 0; yi < _pfm.
get_y_size(); ++yi) {
307 for (
int xi = 0; xi < _pfm.
get_x_size(); ++xi) {
311 if (check_aux_pfm && !_aux_pfm->
has_point(xi, yi)) {
316 LPoint2f uv((PN_float32(xi) + 0.5) * uv_scale[0],
317 (PN_float32(yi) + 0.5) * uv_scale[1]);
321 }
else if (_vis_2d) {
334 points->add_next_vertices(num_points);
335 geom->add_primitive(points);
338 gnode->add_geom(geom);
352 nassertr(_pfm.is_valid(),
NodePath());
353 bool check_aux_pfm = uses_aux_pfm();
354 nassertr(!check_aux_pfm || (_aux_pfm != NULL && _aux_pfm->is_valid()),
NodePath());
375 if (face & MF_front) {
376 make_vis_mesh_geom(gnode,
false);
379 if (face & MF_back) {
380 make_vis_mesh_geom(gnode,
true);
402 for (
int yi = 0; yi < y_size; ++yi) {
403 for (
int xi = 0; xi < x_size; ++xi) {
409 double nxi = point[0] * (double)x_size - 0.5;
411 max_u = max(max_u, cabs(nxi - (
double)xi));
433 for (
int yi = 0; yi < y_size; ++yi) {
434 for (
int xi = 0; xi < x_size; ++xi) {
440 double nyi = point[1] * (double)y_size - 0.5;
442 max_v = max(max_v, cabs(nyi - (
double)yi));
479 result.
clear(x_size, y_size, 3, PNM_MAXMAXVAL);
480 result.
fill_val(0, 0, PNM_MAXMAXVAL);
484 static const int midval = (PNM_MAXMAXVAL + 1) / 2;
491 scale_factor = ae_undershift_factor_32;
497 scale_factor = ae_undershift_factor_16;
500 double u_scale = scale_factor * 0.5 * PNM_MAXMAXVAL / max_u;
501 double v_scale = scale_factor * 0.5 * PNM_MAXMAXVAL / max_v;
503 for (
int yi = 0; yi < y_size; ++yi) {
504 for (
int xi = 0; xi < x_size; ++xi) {
510 double nxi = point[0] * (double)x_size - 0.5;
511 double nyi = point[1] * (double)y_size - 0.5;
513 double x_shift = (nxi - (double)xi);
514 double y_shift = (nyi - (double)yi);
516 int u_val = midval + (int)cfloor(x_shift * u_scale + 0.5);
517 int v_val = midval + (int)cfloor(y_shift * v_scale + 0.5);
522 min(max(u_val, 0), PNM_MAXMAXVAL),
523 min(max(v_val, 0), PNM_MAXMAXVAL),
529 for (
int yi = 0; yi < y_size; ++yi) {
530 for (
int xi = 0; xi < x_size; ++xi) {
536 double nxi = point[0] * (double)x_size - 0.5;
537 double nyi = point[1] * (double)y_size - 0.5;
539 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, 1);
540 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, 1);
541 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, 1);
542 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, 1);
547 for (
int yi = 0; yi < y_size; ++yi) {
548 for (
int xi = 0; xi < x_size; ++xi) {
583 result.
clear(x_size, y_size, 3);
590 scale_factor = ae_undershift_factor_32;
596 scale_factor = ae_undershift_factor_16;
599 double u_scale = scale_factor * 0.5 / max_u;
600 double v_scale = scale_factor * 0.5 / max_v;
602 for (
int yi = 0; yi < y_size; ++yi) {
603 for (
int xi = 0; xi < x_size; ++xi) {
609 double nxi = point[0] * (double)x_size - 0.5;
610 double nyi = point[1] * (double)y_size - 0.5;
612 double x_shift = (nxi - (double)xi);
613 double y_shift = (nyi - (double)yi);
615 float u_val = 0.5 + (float)(x_shift * u_scale);
616 float v_val = 0.5 + (float)(y_shift * v_scale);
625 for (
int yi = 0; yi < y_size; ++yi) {
626 for (
int xi = 0; xi < x_size; ++xi) {
632 double nxi = point[0] * (double)x_size - 0.5;
633 double nyi = point[1] * (double)y_size - 0.5;
635 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, 1);
636 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, 1);
637 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, 1);
638 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, 1);
643 for (
int yi = 0; yi < y_size; ++yi) {
644 for (
int xi = 0; xi < x_size; ++xi) {
657 uses_aux_pfm()
const {
658 for (VisColumns::const_iterator vci = _vis_columns.begin();
659 vci != _vis_columns.end();
661 const VisColumn &column = *vci;
662 switch (column._source) {
684 r_fill_displacement(
PNMImage &result,
int xi,
int yi,
685 double nxi,
double nyi,
double u_scale,
double v_scale,
686 int distance)
const {
687 if (xi < 0 || yi < 0 ||
693 if (distance > 1000) {
699 if (val > distance) {
701 static const int midval = (PNM_MAXMAXVAL + 1) / 2;
703 double x_shift = (nxi - (double)xi);
704 double y_shift = (nyi - (double)yi);
705 int u_val = midval + (int)cfloor(x_shift * u_scale + 0.5);
706 int v_val = midval + (int)cfloor(y_shift * v_scale + 0.5);
708 min(max(u_val, 0), PNM_MAXMAXVAL),
709 min(max(v_val, 0), PNM_MAXMAXVAL),
710 min(distance, PNM_MAXMAXVAL));
712 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
713 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
714 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, distance + 1);
715 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, distance + 1);
728 r_fill_displacement(
PfmFile &result,
int xi,
int yi,
729 double nxi,
double nyi,
double u_scale,
double v_scale,
730 int distance)
const {
731 if (xi < 0 || yi < 0 ||
737 if (distance > 1000) {
743 if (val > (
float)distance) {
745 double x_shift = (nxi - (double)xi);
746 double y_shift = (nyi - (double)yi);
747 float u_val = 0.5 + (float)(x_shift * u_scale);
748 float v_val = 0.5 + (float)(y_shift * v_scale);
751 r_fill_displacement(result, xi - 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
752 r_fill_displacement(result, xi + 1, yi, nxi, nyi, u_scale, v_scale, distance + 1);
753 r_fill_displacement(result, xi, yi - 1, nxi, nyi, u_scale, v_scale, distance + 1);
754 r_fill_displacement(result, xi, yi + 1, nxi, nyi, u_scale, v_scale, distance + 1);
765 make_vis_mesh_geom(
GeomNode *gnode,
bool inverted)
const {
766 static const bool keep_beyond_lens =
true;
774 int num_vertices = x_size * y_size;
775 if (num_vertices == 0) {
780 bool reverse_normals = inverted;
781 bool reverse_faces = inverted;
782 if (!is_right_handed(get_default_coordinate_system())) {
783 reverse_faces = !reverse_faces;
789 int max_indices = (x_size - 1) * (y_size - 1) * 6;
791 while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) {
794 if (num_x_cells > num_y_cells) {
800 x_size = (_pfm.
get_x_size() + num_x_cells - 1) / num_x_cells + 1;
801 y_size = (_pfm.
get_y_size() + num_y_cells - 1) / num_y_cells + 1;
803 num_vertices = x_size * y_size;
804 max_indices = (x_size - 1) * (y_size - 1) * 6;
808 if (grutil_cat.is_debug()) {
810 <<
"Generating mesh with " << num_x_cells <<
" x " << num_y_cells
814 VisColumns vis_columns = _vis_columns;
815 if (vis_columns.empty()) {
816 build_auto_vis_columns(vis_columns,
true);
818 bool check_aux_pfm = uses_aux_pfm();
820 CPT(GeomVertexFormat) format = make_array_format(vis_columns);
822 for (
int yci = 0; yci < num_y_cells; ++yci) {
823 int y_begin = (yci * _pfm.
get_y_size()) / num_y_cells;
824 int y_end = ((yci + 1) * _pfm.
get_y_size()) / num_y_cells;
830 y_size = y_end - y_begin;
835 for (
int xci = 0; xci < num_x_cells; ++xci) {
836 int x_begin = (xci * _pfm.
get_x_size()) / num_x_cells;
837 int x_end = ((xci + 1) * _pfm.
get_x_size()) / num_x_cells;
839 x_size = x_end - x_begin;
844 num_vertices = x_size * y_size;
845 max_indices = (x_size - 1) * (y_size - 1) * 6;
848 mesh_name <<
"mesh_" << xci <<
"_" << yci;
850 (mesh_name.str(), format,
Geom::UH_static);
852 vdata->set_num_rows(num_vertices);
854 char *skip_points = new
char[num_vertices];
855 memset(skip_points, 0, sizeof(
char) * num_vertices);
858 for (VisColumns::const_iterator vci = vis_columns.begin();
859 vci != vis_columns.end();
861 const VisColumn &column = *vci;
865 for (
int yi = y_begin; yi < y_end; ++yi) {
866 for (
int xi = x_begin; xi < x_end; ++xi) {
867 if (!column.add_data(*
this, vwriter, xi, yi, reverse_normals)) {
868 skip_points[(yi - y_begin) * x_size + (xi - x_begin)] = (char)
true;
877 tris->reserve_num_vertices(max_indices);
879 for (
int yi = y_begin; yi < y_end - 1; ++yi) {
880 for (
int xi = x_begin; xi < x_end - 1; ++xi) {
888 if (check_aux_pfm && (!_aux_pfm->
has_point(xi, yi) ||
895 if (!keep_beyond_lens &&
896 (skip_points[(yi - y_begin) * x_size + (xi - x_begin)] ||
897 skip_points[(yi - y_begin + 1) * x_size + (xi - x_begin)] ||
898 skip_points[(yi - y_begin) * x_size + (xi - x_begin + 1)] ||
899 skip_points[(yi - y_begin + 1) * x_size + (xi - x_begin + 1)])) {
903 int xi0 = xi - x_begin;
904 int yi0 = yi - y_begin;
906 int vi0 = ((xi0) + (yi0) * x_size);
907 int vi1 = ((xi0) + (yi0 + 1) * x_size);
908 int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
909 int vi3 = ((xi0 + 1) + (yi0) * x_size);
913 tris->close_primitive();
915 tris->add_vertices(vi3, vi0, vi2);
916 tris->close_primitive();
918 tris->add_vertices(vi2, vi1, vi0);
919 tris->close_primitive();
921 tris->add_vertices(vi3, vi2, vi0);
922 tris->close_primitive();
926 geom->add_primitive(tris);
929 delete[] skip_points;
942 add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
943 InternalName *name,
const TransformState *transform,
946 column._source = source;
947 column._target = target;
949 column._transform = transform;
950 if (transform == NULL) {
951 column._transform = TransformState::make_identity();
954 if (undist_lut != NULL && undist_lut->is_valid()) {
955 column._undist_lut = undist_lut;
957 vis_columns.push_back(column);
970 build_auto_vis_columns(VisColumns &vis_columns,
bool for_points)
const {
976 add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex());
977 add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord());
979 add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex());
980 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
987 add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex());
988 add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord());
992 add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex());
993 add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal());
994 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
998 if (_flat_texcoord_name != (InternalName *)NULL) {
1000 add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name);
1003 if (_vis_blend != (
PNMImage *)NULL) {
1005 add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color());
1016 make_array_format(const VisColumns &vis_columns)
const {
1017 PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat;
1019 for (VisColumns::const_iterator vci = vis_columns.begin();
1020 vci != vis_columns.end();
1022 const VisColumn &column = *vci;
1023 InternalName *name = column._name;
1025 int num_components = 0;
1026 GeomEnums::NumericType numeric_type = GeomEnums::NT_float32;
1027 GeomEnums::Contents contents = GeomEnums::C_point;
1028 switch (column._target) {
1031 numeric_type = GeomEnums::NT_float32;
1032 contents = GeomEnums::C_texcoord;
1037 numeric_type = GeomEnums::NT_float32;
1038 contents = GeomEnums::C_texcoord;
1042 case CT_aux_vertex1:
1044 numeric_type = GeomEnums::NT_float32;
1045 contents = GeomEnums::C_point;
1049 case CT_aux_vertex2:
1051 numeric_type = GeomEnums::NT_float32;
1052 contents = GeomEnums::C_point;
1056 case CT_aux_vertex3:
1058 numeric_type = GeomEnums::NT_float32;
1059 contents = GeomEnums::C_point;
1064 numeric_type = GeomEnums::NT_float32;
1065 contents = GeomEnums::C_normal;
1070 numeric_type = GeomEnums::NT_uint8;
1071 contents = GeomEnums::C_color;
1074 nassertr(num_components != 0, NULL);
1076 array_format->add_column(name, num_components, numeric_type, contents);
1079 return GeomVertexFormat::register_format(array_format);
1089 bool PfmVizzer::VisColumn::
1092 bool success =
true;
1098 (PN_float32(yi) + 0.5) / PN_float32(pfm.
get_y_size()));
1099 if (!transform_point(uv)) {
1109 (PN_float32(yi) + 0.5) / PN_float32(pfm.
get_y_size()),
1111 if (!transform_point(uv)) {
1122 if (!transform_point(point)) {
1129 case CT_aux_vertex1:
1134 if (!transform_point(point)) {
1144 if (!transform_point(point)) {
1151 case CT_aux_vertex2:
1155 if (!transform_point(point)) {
1165 if (!transform_point(point)) {
1172 case CT_aux_vertex3:
1175 if (!transform_point(point)) {
1185 bool flip = reverse_normals;
1206 for (
int i = 0; i < 3; ++i) {
1208 const LPoint3f &v1 = v[(i + 1) % 3];
1209 n[0] += v0[1] * v1[2] - v0[2] * v1[1];
1210 n[1] += v0[2] * v1[0] - v0[0] * v1[2];
1211 n[2] += v0[0] * v1[1] - v0[1] * v1[0];
1227 if (!transform_vector(n)) {
1237 if (vis_blend != NULL) {
1238 double gray = vis_blend->
get_gray(xi, yi);
1254 bool PfmVizzer::VisColumn::
1255 transform_point(
LPoint2f &point)
const {
1256 bool success =
true;
1257 if (!_transform->is_identity()) {
1258 LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point);
1270 bool PfmVizzer::VisColumn::
1271 transform_point(
LPoint3f &point)
const {
1272 bool success =
true;
1273 if (!_transform->is_identity()) {
1274 LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point);
1276 if (_lens != (
Lens *)NULL) {
1277 static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0,
1280 0.5, 0.5, 0.0, 1.0);
1282 if (!_lens->project(LCAST(PN_stdfloat, point), film)) {
1285 point = to_uv.xform_point(LCAST(PN_float32, film));
1288 if (_undist_lut != NULL) {
1290 if (!_undist_lut->calc_bilinear_point(p, point[0], 1.0 - point[1])) {
1296 point[1] = 1.0 - point[1];
1309 bool PfmVizzer::VisColumn::
1310 transform_vector(
LVector3f &vec)
const {
1311 if (!_transform->is_identity()) {
1312 LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec);
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void clear_vis_columns()
Removes all of the previously-added vis columns in preparation for building a new list...
This is the base class for all three-component vectors and points.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
A base class for any number of different kinds of lenses, linear and otherwise.
Defines a series of disconnected points.
PN_float32 get_point1(int x, int y) const
Returns the 1-component point value at the indicated point.
void add_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row. ...
void set_point4(int x, int y, const LVecBase4f &point)
Replaces the 4-component point value at the indicated point.
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
PN_float32 get_channel(int x, int y, int c) const
Returns the cth channel of the point value at the indicated point.
xelval get_blue_val(int x, int y) const
Returns the blue component color at the indicated pixel.
static const LVector3f & zero()
Returns a zero-length vector.
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
bool calc_bilinear_point(LPoint3f &result, PN_float32 x, PN_float32 y) const
Computes the weighted average of the four nearest points to the floating-point index (x...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
void extrude(const Lens *lens)
Converts each (u, v, depth) point of the Pfm file to an (x, y, z) point, by reversing project()...
const PfmFile * get_aux_pfm() const
Returns the reference to the auxiliary PfmFile queried by this PfmVizzer.
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
void add_vis_column(ColumnType source, ColumnType target, InternalName *name, const TransformState *transform=NULL, const Lens *lens=NULL, const PfmFile *undist_lut=NULL)
Adds a new vis column specification to the list of vertex data columns that will be generated at the ...
void set_point3(int x, int y, const LVecBase3f &point)
Replaces the 3-component point value at the indicated point.
const PNMImage * get_vis_blend() const
Returns the blending map set by the most recent call to set_vis_blend(), or NULL if there is no blend...
void set_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void set_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void project(const Lens *lens, const PfmFile *undist_lut=NULL)
Adjusts each (x, y, z) point of the Pfm file by projecting it through the indicated lens...
void add_vertices(int v1, int v2)
Adds several vertices in a row.
void make_displacement(PNMImage &result, double max_u, double max_v, bool for_32bit) const
Assuming the underlying PfmFile is a 2-d distortion mesh, with the U and V in the first two component...
NodePath generate_vis_points() const
Creates a point cloud with the points of the pfm as 3-d coordinates in space, and texture coordinates...
const LPoint2f & get_point2(int x, int y) const
Returns the 2-component point value at the indicated point.
Defines a pfm file, a 2-d table of floating-point numbers, either 3-component or 1-component, or with a special extension, 2- or 4-component.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
void set_blue_val(int x, int y, xelval b)
Sets the blue component color only at the indicated pixel.
This is a 4-by-4 transform matrix.
bool has_point(int x, int y) const
Returns true if there is a valid point at x, y.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
void clear_to_texcoords(int x_size, int y_size)
Replaces this PfmFile with a new PfmFile of size x_size x y_size x 3, containing the x y 0 values in ...
A container for geometry primitives.
bool project(const LPoint3 &point3d, LPoint3 &point2d) const
Given a 3-d point in space, determine the 2-d point this maps to, in the range (-1,1) in both dimensions, where (0,0) is the center of the lens and (-1,-1) is the lower-left corner.
bool set_num_rows(int n)
Sets the length of the array to n rows in all of the various arrays (presumably by adding rows)...
void set_point(int x, int y, const LVecBase3f &point)
Replaces the 3-component point value at the indicated point.
bool has_no_data_value() const
Returns whether a "no data" value has been established by set_no_data_value().
const LMatrix4 & get_projection_mat_inv(StereoChannel channel=SC_mono) const
Returns the matrix that transforms from a 2-d point on the film to a 3-d vector in space...
LVecBase3f xform_point_general(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
void add_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void set_channel(int x, int y, int c, PN_float32 value)
Replaces the cth channel of the point value at the indicated point.
PfmFile & get_pfm()
Returns the reference to the PfmFile manipulated by this PfmVizzer.
This is the base class for all three-component vectors and points.
bool extrude_depth(const LPoint3 &point2d, LPoint3 &point3d) const
Uses the depth component of the 3-d result from project() to compute the original point in 3-d space ...
void clear()
Frees all memory allocated for the image, and clears all its parameters (size, color, type, etc).
double calc_max_u_displacement() const
Computes the maximum amount of shift, in pixels either left or right, of any pixel in the distortion ...
LPoint3f & modify_point(int x, int y)
Returns a modifiable 3-component point value at the indicated point.
void set_zero_special(bool zero_special)
Sets the zero_special flag.
Defines a series of disconnected triangles.
void set_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row. ...
void copy_channel(int to_channel, const PfmFile &other, int from_channel)
Copies just the specified channel values from the indicated PfmFile (which could be same as this PfmF...
const LPoint3f & get_point(int x, int y) const
Returns the 3-component point value at the indicated point.
This is a two-component point in space.
bool normalize()
Normalizes the vector in place.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
double calc_max_v_displacement() const
Computes the maximum amount of shift, in pixels either up or down, of any pixel in the distortion map...
A node that holds Geom objects, renderable pieces of geometry.
void fill_val(xelval red, xelval green, xelval blue)
Sets the entire image (except the alpha channel) to the given color.
void clear()
Eliminates all data in the file.
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
NodePath generate_vis_mesh(MeshFace face=MF_front) const
Creates a triangle mesh with the points of the pfm as 3-d coordinates in space, and texture coordinat...
PfmVizzer(PfmFile &pfm)
The PfmVizzer constructor receives a reference to a PfmFile which it will operate on...
This class aids in the visualization and manipulation of PfmFile objects.
const LPoint4f & get_no_data_value() const
If has_no_data_value() returns true, this returns the particular "no data" value. ...