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);
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
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);
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);
912 tris->add_vertices(vi2, vi0, vi1);
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;
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());
1015 CPT(GeomVertexFormat) PfmVizzer::
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);
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
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.
bool has_point(int x, int y) const
Returns true if there is a valid point at x, y.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
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...
A base class for any number of different kinds of lenses, linear and otherwise.
NodePath generate_vis_points() const
Creates a point cloud with the points of the pfm as 3-d coordinates in space, and texture coordinates...
Defines a series of disconnected points.
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.
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...
const LPoint3f & get_point(int x, int y) const
Returns the 3-component point value at the indicated point.
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
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...
static const LVector3f & zero()
Returns a zero-length vector.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
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()...
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 LPoint2f & get_point2(int x, int y) const
Returns the 2-component point value at the indicated point.
PN_float32 get_point1(int x, int y) const
Returns the 1-component point value at the indicated point.
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.
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...
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...
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.
LVecBase3f xform_point(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
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.
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...
xelval get_blue_val(int x, int y) const
Returns the blue component color at the indicated pixel.
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.
PN_float32 get_channel(int x, int y, int c) const
Returns the cth channel of the 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().
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.
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.
void clear()
Frees all memory allocated for the image, and clears all its parameters (size, color, type, etc).
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...
void set_row(int row)
Sets the start row to the indicated value.
This is a two-component point in space.
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 ...
const PfmFile * get_aux_pfm() const
Returns the reference to the auxiliary PfmFile queried by this PfmVizzer.
bool normalize()
Normalizes the vector in place.
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...
double calc_max_u_displacement() const
Computes the maximum amount of shift, in pixels either left or right, of any pixel in the distortion ...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A node that holds Geom objects, renderable pieces of geometry.
LVecBase3f xform_point_general(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
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.
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. ...