From 8e3e89b5b39d1bbcba9f69e11e2f1436d2f305df Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 1 Oct 2012 00:40:56 +0000 Subject: [PATCH] fix build circularity issue --- panda/src/grutil/Sources.pp | 3 + panda/src/grutil/config_grutil.cxx | 12 + panda/src/grutil/config_grutil.h | 3 + panda/src/grutil/p3grutil_composite2.cxx | 6 +- panda/src/grutil/pfmVizzer.I | 182 ++++++ panda/src/grutil/pfmVizzer.cxx | 743 +++++++++++++++++++++++ panda/src/grutil/pfmVizzer.h | 120 ++++ panda/src/pnmimage/config_pnmimage.cxx | 12 - panda/src/pnmimage/config_pnmimage.h | 2 - panda/src/pnmimage/pfmFile.I | 160 +---- panda/src/pnmimage/pfmFile.cxx | 721 +--------------------- panda/src/pnmimage/pfmFile.h | 77 +-- 12 files changed, 1070 insertions(+), 971 deletions(-) create mode 100644 panda/src/grutil/pfmVizzer.I create mode 100644 panda/src/grutil/pfmVizzer.cxx create mode 100644 panda/src/grutil/pfmVizzer.h diff --git a/panda/src/grutil/Sources.pp b/panda/src/grutil/Sources.pp index cc00879b9f..f22237457e 100644 --- a/panda/src/grutil/Sources.pp +++ b/panda/src/grutil/Sources.pp @@ -25,6 +25,7 @@ lineSegs.I lineSegs.h \ multitexReducer.I multitexReducer.h multitexReducer.cxx \ nodeVertexTransform.I nodeVertexTransform.h \ + pfmVizzer.I pfmVizzer.h \ rigidBodyCombiner.I rigidBodyCombiner.h #define INCLUDED_SOURCES \ @@ -39,6 +40,7 @@ sceneGraphAnalyzerMeter.cxx \ heightfieldTesselator.cxx \ nodeVertexTransform.cxx \ + pfmVizzer.cxx \ pipeOcclusionCullTraverser.cxx \ lineSegs.cxx \ rigidBodyCombiner.cxx @@ -56,6 +58,7 @@ lineSegs.I lineSegs.h \ multitexReducer.I multitexReducer.h \ nodeVertexTransform.I nodeVertexTransform.h \ + pfmVizzer.I pfmVizzer.h \ rigidBodyCombiner.I rigidBodyCombiner.h #define IGATESCAN all diff --git a/panda/src/grutil/config_grutil.cxx b/panda/src/grutil/config_grutil.cxx index 64acac1a4b..d877382a20 100644 --- a/panda/src/grutil/config_grutil.cxx +++ b/panda/src/grutil/config_grutil.cxx @@ -72,6 +72,18 @@ ConfigVariableBool movies_sync_pages "such as cube maps, 3-d textures, or stereo textures, or textures " "with separate color and alpha channel movie sources.")); +ConfigVariableInt pfm_vis_max_vertices +("pfm-vis-max-vertices", 65535, + PRC_DESC("Specifies the maximum number of vertex entries that may appear in " + "a single generated mesh. If the mesh would require more than that, " + "the mesh is subdivided into smaller pieces.")); + +ConfigVariableInt pfm_vis_max_indices +("pfm-vis-max-indices", 1048576, + PRC_DESC("Specifies the maximum number of vertex references that may appear in " + "a single generated mesh. If the mesh would require more than that, " + "the mesh is subdivided into smaller pieces.")); + //////////////////////////////////////////////////////////////////// // Function: init_libgrutil // Description: Initializes the library. This must be called at diff --git a/panda/src/grutil/config_grutil.h b/panda/src/grutil/config_grutil.h index a13106e403..96b666e3a5 100644 --- a/panda/src/grutil/config_grutil.h +++ b/panda/src/grutil/config_grutil.h @@ -37,6 +37,9 @@ extern ConfigVariableDouble scene_graph_analyzer_meter_side_margins; extern ConfigVariableBool movies_sync_pages; +extern ConfigVariableInt pfm_vis_max_vertices; +extern ConfigVariableInt pfm_vis_max_indices; + extern EXPCL_PANDA_GRUTIL void init_libgrutil(); #endif diff --git a/panda/src/grutil/p3grutil_composite2.cxx b/panda/src/grutil/p3grutil_composite2.cxx index 38b3ae66f3..aec820e18b 100644 --- a/panda/src/grutil/p3grutil_composite2.cxx +++ b/panda/src/grutil/p3grutil_composite2.cxx @@ -1,6 +1,8 @@ +#include "meshDrawer.cxx" +#include "meshDrawer2D.cxx" #include "movieTexture.cxx" #include "nodeVertexTransform.cxx" #include "pipeOcclusionCullTraverser.cxx" +#include "pfmVizzer.cxx" #include "rigidBodyCombiner.cxx" -#include "meshDrawer.cxx" -#include "meshDrawer2D.cxx" + diff --git a/panda/src/grutil/pfmVizzer.I b/panda/src/grutil/pfmVizzer.I new file mode 100644 index 0000000000..0aa6495b18 --- /dev/null +++ b/panda/src/grutil/pfmVizzer.I @@ -0,0 +1,182 @@ +// Filename: pfmVizzer.I +// Created by: drose (30Sep12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_pfm +// Access: Published +// Description: Returns the reference to the PfmFile manipulated by +// thiz PfmVizzer. +//////////////////////////////////////////////////////////////////// +INLINE PfmFile &PfmVizzer:: +get_pfm() { + return _pfm; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_pfm +// Access: Published +// Description: Returns the reference to the PfmFile manipulated by +// thiz PfmVizzer. +//////////////////////////////////////////////////////////////////// +INLINE const PfmFile &PfmVizzer:: +get_pfm() const { + return _pfm; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::set_vis_inverse +// Access: Published +// Description: Sets the vis_inverse flag. When this flag is true, +// vis meshes and point clouds are generated with the +// 3-d depth value in the texture coordinates, and the +// 2-d index value in the vertex position. When it is +// false, meshes are generated normally, with the 3-d +// depth value in the vertex position and the 2-d index +// value in the texture coordinates. +// +// This may be used in lieu of the lower-level +// add_vis_column(). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +set_vis_inverse(bool vis_inverse) { + _vis_inverse = vis_inverse; + clear_vis_columns(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_vis_inverse +// Access: Published +// Description: Returns the vis_inverse flag. See set_vis_inverse(). +//////////////////////////////////////////////////////////////////// +INLINE bool PfmVizzer:: +get_vis_inverse() const { + return _vis_inverse; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::set_flat_texcoord_name +// Access: Published +// Description: If the flat_texcoord_name is specified, it is the +// name of an additional vertex column that will be +// created for the "flat" texture coordinates, i.e. the +// original 0..1 values that correspond to the 2-D index +// position of each point in the original pfm file. +// +// These are the same values that will be assigned to +// the default texture coordinates if the vis_inverse +// flag is *not* true. +// +// This may be used in lieu of the lower-level +// add_vis_column(). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +set_flat_texcoord_name(InternalName *flat_texcoord_name) { + _flat_texcoord_name = flat_texcoord_name; + clear_vis_columns(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::clear_flat_texcoord_name +// Access: Published +// Description: Resets the flat_texcoord_name to empty, so that +// additional texture coordinates are not created. +// +// This may be used in lieu of the lower-level +// add_vis_column(). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +clear_flat_texcoord_name() { + _flat_texcoord_name = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_flat_texcoord_name +// Access: Published +// Description: Returns the flat_texcoord_name. See set_flat_texcoord_name(). +//////////////////////////////////////////////////////////////////// +INLINE InternalName *PfmVizzer:: +get_flat_texcoord_name() const { + return _flat_texcoord_name; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::set_vis_2d +// Access: Published +// Description: Sets the vis_2d flag. When this flag is true, +// only the first two (x, y) value of each depth point +// is considered meaningful; the z component is ignored. +// This is only relevant for generating visualizations. +// +// This may be used in lieu of the lower-level +// add_vis_column(). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +set_vis_2d(bool vis_2d) { + _vis_2d = vis_2d; + clear_vis_columns(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_vis_2d +// Access: Published +// Description: Returns the vis_2d flag. See set_vis_2d(). +//////////////////////////////////////////////////////////////////// +INLINE bool PfmVizzer:: +get_vis_2d() const { + return _vis_2d; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::set_vis_blend +// Access: Published +// Description: Specifies a blending map--a grayscale image--that +// will be applied to the vertex color during +// generate_vis_mesh() and generate_vis_points(). The +// image size must exactly match the mesh size of the +// PfmVizzer. +// +// Ownership of the pointer is not kept by the PfmVizzer; +// it is your responsibility to ensure it does not +// destruct during the lifetime of the PfmVizzer (or at +// least not before your subsequent call to +// generate_vis_mesh()). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +set_vis_blend(const PNMImage *vis_blend) { + _vis_blend = vis_blend; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::set_vis_blend +// Access: Published +// Description: Removes the blending map set by a prior call to +// set_vis_blend(). +//////////////////////////////////////////////////////////////////// +INLINE void PfmVizzer:: +clear_vis_blend() { + _vis_blend = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::get_vis_blend +// Access: Published +// Description: Returns the blending map set by the most recent call +// to set_vis_blend(), or NULL if there is no blending +// map in effect. +//////////////////////////////////////////////////////////////////// +INLINE const PNMImage *PfmVizzer:: +get_vis_blend() const { + return _vis_blend; +} diff --git a/panda/src/grutil/pfmVizzer.cxx b/panda/src/grutil/pfmVizzer.cxx new file mode 100644 index 0000000000..d558d4aaf8 --- /dev/null +++ b/panda/src/grutil/pfmVizzer.cxx @@ -0,0 +1,743 @@ +// Filename: pfmVizzer.cxx +// Created by: drose (30Sep12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "pfmVizzer.h" +#include "geomNode.h" +#include "geom.h" +#include "geomVertexData.h" +#include "geomVertexFormat.h" +#include "geomPoints.h" +#include "geomTriangles.h" +#include "geomVertexWriter.h" +#include "lens.h" +#include "config_grutil.h" + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::Constructor +// Access: Published +// Description: The PfmVizzer constructor receives a reference to a +// PfmFile which it will operate on. It does not keep +// ownership of this reference; it is your +// responsibility to ensure the PfmFile does not +// destruct during the lifetime of the PfmVizzer. +//////////////////////////////////////////////////////////////////// +PfmVizzer:: +PfmVizzer(PfmFile &pfm) : _pfm(pfm) { + _vis_inverse = false; + _vis_2d = false; + _vis_blend = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::project +// Access: Published +// Description: Adjusts each (x, y, z) point of the Pfm file by +// projecting it through the indicated lens, converting +// each point to a (u, v, w) texture coordinate. The +// resulting file can be generated to a mesh (with +// set_vis_inverse(true) and generate_vis_mesh()) +// that will apply the lens distortion to an arbitrary +// texture image. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +project(const Lens *lens) { + nassertv(_pfm.is_valid()); + + static LMatrix4f to_uv(0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f); + + for (int yi = 0; yi < _pfm.get_y_size(); ++yi) { + for (int xi = 0; xi < _pfm.get_x_size(); ++xi) { + if (!_pfm.has_point(xi, yi)) { + continue; + } + LPoint3f &p = _pfm.modify_point(xi, yi); + + LPoint3 film; + lens->project(LCAST(PN_stdfloat, p), film); + p = to_uv.xform_point(LCAST(PN_float32, film)); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::extrude +// Access: Published +// Description: Converts each (u, v, depth) point of the Pfm file to +// an (x, y, z) point, by reversing project(). If the +// original file is only a 1-d file, assumes that it is +// a depth map with implicit (u, v) coordinates. +// +// This method is only valid for a linear lens (e.g. a +// PerspectiveLens or OrthographicLens). Non-linear +// lenses don't necessarily compute a sensible depth +// coordinate. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +extrude(const Lens *lens) { + nassertv(_pfm.is_valid()); + nassertv(lens->is_linear()); + + static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 2.0, 0.0, + -1.0, -1.0, -1.0, 1.0); + const LMatrix4 &proj_mat_inv = lens->get_projection_mat_inv(); + + PfmFile result; + result.clear(_pfm.get_x_size(), _pfm.get_y_size(), 3); + result.set_zero_special(true); + + if (_pfm.get_num_channels() == 1) { + // Create an implicit UV coordinate for each point. + LPoint2 uv_scale(1.0, 1.0); + if (_pfm.get_x_size() > 1) { + uv_scale[0] = 1.0 / PN_stdfloat(_pfm.get_x_size() - 1); + } + if (_pfm.get_y_size() > 1) { + uv_scale[1] = 1.0 / PN_stdfloat(_pfm.get_y_size() - 1); + } + for (int yi = 0; yi < _pfm.get_y_size(); ++yi) { + for (int xi = 0; xi < _pfm.get_x_size(); ++xi) { + if (!_pfm.has_point(xi, yi)) { + continue; + } + LPoint3 p; + p.set((PN_stdfloat)xi * uv_scale[0], + (PN_stdfloat)yi * uv_scale[1], + (PN_stdfloat)_pfm.get_point1(xi, yi)); + + from_uv.xform_point_in_place(p); + proj_mat_inv.xform_point_general_in_place(p); + result.set_point(xi, yi, p); + } + } + } else { + // Use the existing UV coordinate for each point. + for (int yi = 0; yi < _pfm.get_y_size(); ++yi) { + for (int xi = 0; xi < _pfm.get_x_size(); ++xi) { + if (!_pfm.has_point(xi, yi)) { + continue; + } + LPoint3 p; + p = LCAST(PN_stdfloat, _pfm.get_point(xi, yi)); + + from_uv.xform_point_in_place(p); + proj_mat_inv.xform_point_general_in_place(p); + result.set_point(xi, yi, p); + } + } + } + + _pfm = result; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::clear_vis_columns +// Access: Published +// Description: Removes all of the previously-added vis columns in +// preparation for building a new list. See +// add_vis_column(). +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +clear_vis_columns() { + _vis_columns.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::add_vis_column +// Access: Published +// Description: Adds a new vis column specification to the list of +// vertex data columns that will be generated at the +// next call to generate_vis_points() or +// generate_vis_mesh(). This advanced interface +// supercedes the higher-level set_vis_inverse(), +// set_flat_texcoord_name(), and set_vis_2d(). +// +// If you use this advanced interface, you must specify +// explicitly the complete list of data columns to be +// created in the resulting GeomVertexData, by calling +// add_vis_column() each time. For each column, you +// specify the source of the column in the PFMFile, the +// target column and name in the GeomVertexData, and an +// optional transform matrix and/or lens to transform +// and project the point before generating it. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +add_vis_column(ColumnType source, ColumnType target, + InternalName *name, const TransformState *transform, + const Lens *lens) { + add_vis_column(_vis_columns, source, target, name, transform, lens); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::generate_vis_points +// Access: Published +// Description: Creates a point cloud with the points of the pfm as +// 3-d coordinates in space, and texture coordinates +// ranging from 0 .. 1 based on the position within the +// pfm grid. +//////////////////////////////////////////////////////////////////// +NodePath PfmVizzer:: +generate_vis_points() const { + nassertr(_pfm.is_valid(), NodePath()); + + CPT(GeomVertexFormat) format; + if (_vis_inverse) { + if (_vis_2d) { + format = GeomVertexFormat::get_v3t2(); + } else { + // We need a 3-d texture coordinate if we're inverting the vis + // and it's 3-d. + GeomVertexArrayFormat *v3t3 = new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, + Geom::NT_stdfloat, Geom::C_point, + InternalName::get_texcoord(), 3, + Geom::NT_stdfloat, Geom::C_texcoord); + format = GeomVertexFormat::register_format(v3t3); + } + } else { + format = GeomVertexFormat::get_v3t2(); + } + + PT(GeomVertexData) vdata = new GeomVertexData + ("points", format, Geom::UH_static); + vdata->set_num_rows(_pfm.get_x_size() * _pfm.get_y_size()); + GeomVertexWriter vertex(vdata, InternalName::get_vertex()); + GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); + + LPoint2f uv_scale(1.0, 1.0); + if (_pfm.get_x_size() > 1) { + uv_scale[0] = 1.0f / PN_float32(_pfm.get_x_size() - 1); + } + if (_pfm.get_y_size() > 1) { + uv_scale[1] = 1.0f / PN_float32(_pfm.get_y_size() - 1); + } + + int num_points = 0; + for (int yi = 0; yi < _pfm.get_y_size(); ++yi) { + for (int xi = 0; xi < _pfm.get_x_size(); ++xi) { + if (!_pfm.has_point(xi, yi)) { + continue; + } + + const LPoint3f &point = _pfm.get_point(xi, yi); + LPoint2f uv(PN_float32(xi) * uv_scale[0], + PN_float32(yi) * uv_scale[1]); + if (_vis_inverse) { + vertex.add_data2f(uv); + texcoord.add_data3f(point); + } else if (_vis_2d) { + vertex.add_data2f(point[0], point[1]); + texcoord.add_data2f(uv); + } else { + vertex.add_data3f(point); + texcoord.add_data2f(uv); + } + ++num_points; + } + } + + PT(Geom) geom = new Geom(vdata); + PT(GeomPoints) points = new GeomPoints(Geom::UH_static); + points->add_next_vertices(num_points); + geom->add_primitive(points); + + PT(GeomNode) gnode = new GeomNode(""); + gnode->add_geom(geom); + return NodePath(gnode); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::generate_vis_mesh +// Access: Published +// Description: Creates a triangle mesh with the points of the pfm as +// 3-d coordinates in space, and texture coordinates +// ranging from 0 .. 1 based on the position within the +// pfm grid. +//////////////////////////////////////////////////////////////////// +NodePath PfmVizzer:: +generate_vis_mesh(MeshFace face) const { + nassertr(_pfm.is_valid(), NodePath()); + nassertr(face != 0, NodePath()); + + if (_pfm.get_num_channels() == 1 && _vis_columns.empty()) { + // If we're generating a default mesh from a one-channel pfm file, + // expand it to a three-channel pfm file to make the visualization + // useful. + PfmFile expanded; + expanded.clear_to_texcoords(_pfm.get_x_size(), _pfm.get_y_size()); + expanded.copy_channel(2, _pfm, 0); + PfmVizzer exvizzer(expanded); + return exvizzer.generate_vis_mesh(face); + } + + if (_pfm.get_x_size() == 1 || _pfm.get_y_size() == 1) { + // Can't generate a 1-d mesh, so generate points in this case. + return generate_vis_points(); + } + + PT(GeomNode) gnode = new GeomNode(""); + + if (face & MF_front) { + make_vis_mesh_geom(gnode, false); + } + + if (face & MF_back) { + make_vis_mesh_geom(gnode, true); + } + + return NodePath(gnode); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::make_vis_mesh_geom +// Access: Private +// Description: Returns a triangle mesh for the pfm. If inverted is +// true, the mesh is facing the opposite direction. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +make_vis_mesh_geom(GeomNode *gnode, bool inverted) const { + int num_x_cells = 1; + int num_y_cells = 1; + + int x_size = _pfm.get_x_size(); + int y_size = _pfm.get_y_size(); + + // This is the number of independent vertices we will require. + int num_vertices = x_size * y_size; + if (num_vertices == 0) { + // Trivial no-op. + return; + } + + bool reverse_normals = inverted; + bool reverse_faces = inverted; + if (!is_right_handed(get_default_coordinate_system())) { + reverse_faces = !reverse_faces; + } + + // This is the max number of vertex indices we might add to the + // GeomTriangles. (We might actually add fewer than this due to + // omitting the occasional missing data point.) + int max_indices = (x_size - 1) * (y_size - 1) * 6; + + while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) { + // Too many vertices in one mesh. Subdivide the mesh into smaller + // pieces. + if (num_x_cells > num_y_cells) { + ++num_y_cells; + } else { + ++num_x_cells; + } + + x_size = (_pfm.get_x_size() + num_x_cells - 1) / num_x_cells + 1; + y_size = (_pfm.get_y_size() + num_y_cells - 1) / num_y_cells + 1; + + num_vertices = x_size * y_size; + max_indices = (x_size - 1) * (y_size - 1) * 6; + } + + // OK, now we know how many cells we need. + if (grutil_cat.is_debug()) { + grutil_cat.debug() + << "Generating mesh with " << num_x_cells << " x " << num_y_cells + << " pieces.\n"; + } + + VisColumns vis_columns = _vis_columns; + if (vis_columns.empty()) { + build_auto_vis_columns(vis_columns, true); + } + + CPT(GeomVertexFormat) format = make_array_format(vis_columns); + + for (int yci = 0; yci < num_y_cells; ++yci) { + int y_begin = (yci * _pfm.get_y_size()) / num_y_cells; + int y_end = ((yci + 1) * _pfm.get_y_size()) / num_y_cells; + + // Include the first vertex from the next strip in this strip's + // vertices, so we are connected. + y_end = min(y_end + 1, _pfm.get_y_size()); + + y_size = y_end - y_begin; + if (y_size == 0) { + continue; + } + + for (int xci = 0; xci < num_x_cells; ++xci) { + int x_begin = (xci * _pfm.get_x_size()) / num_x_cells; + int x_end = ((xci + 1) * _pfm.get_x_size()) / num_x_cells; + x_end = min(x_end + 1, _pfm.get_x_size()); + x_size = x_end - x_begin; + if (x_size == 0) { + continue; + } + + num_vertices = x_size * y_size; + max_indices = (x_size - 1) * (y_size - 1) * 6; + + ostringstream mesh_name; + mesh_name << "mesh_" << xci << "_" << yci; + PT(GeomVertexData) vdata = new GeomVertexData + (mesh_name.str(), format, Geom::UH_static); + + vdata->set_num_rows(num_vertices); + + // Fill in all of the vertices. + for (VisColumns::const_iterator vci = vis_columns.begin(); + vci != vis_columns.end(); + ++vci) { + const VisColumn &column = *vci; + GeomVertexWriter vwriter(vdata, column._name); + vwriter.set_row(0); + + for (int yi = y_begin; yi < y_end; ++yi) { + for (int xi = x_begin; xi < x_end; ++xi) { + column.add_data(*this, vwriter, xi, yi, reverse_normals); + } + } + } + + PT(Geom) geom = new Geom(vdata); + PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static); + + tris->reserve_num_vertices(max_indices); + + for (int yi = y_begin; yi < y_end - 1; ++yi) { + for (int xi = x_begin; xi < x_end - 1; ++xi) { + + if (_pfm.has_no_data_value()) { + if (!_pfm.has_point(xi, yi) || + !_pfm.has_point(xi, yi + 1) || + !_pfm.has_point(xi + 1, yi + 1) || + !_pfm.has_point(xi + 1, yi)) { + continue; + } + } + + int xi0 = xi - x_begin; + int yi0 = yi - y_begin; + + int vi0 = ((xi0) + (yi0) * x_size); + int vi1 = ((xi0) + (yi0 + 1) * x_size); + int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size); + int vi3 = ((xi0 + 1) + (yi0) * x_size); + + if (reverse_faces) { + tris->add_vertices(vi2, vi0, vi1); + tris->close_primitive(); + + tris->add_vertices(vi3, vi0, vi2); + tris->close_primitive(); + } else { + tris->add_vertices(vi2, vi1, vi0); + tris->close_primitive(); + + tris->add_vertices(vi3, vi2, vi0); + tris->close_primitive(); + } + } + } + geom->add_primitive(tris); + gnode->add_geom(geom); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::add_vis_column +// Access: Private, Static +// Description: The private implementation of the public +// add_vis_column(), this adds the column to the +// indicated specific vector. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target, + InternalName *name, const TransformState *transform, + const Lens *lens) { + VisColumn column; + column._source = source; + column._target = target; + column._name = name; + column._transform = transform; + if (transform == NULL) { + column._transform = TransformState::make_identity(); + } + column._lens = lens; + vis_columns.push_back(column); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::build_auto_vis_columns +// Access: Private +// Description: This function is called internally to construct the +// list of vis_columns automatically from the high-level +// interfaces such as set_vis_inverse(), +// set_flat_texcoord_name(), and set_vis_2d(). It's not +// called if the list has been build explicitly. +//////////////////////////////////////////////////////////////////// +void PfmVizzer:: +build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const { + vis_columns.clear(); + + if (_vis_2d) { + // No normals needed if we're just generating a 2-d mesh. + if (_vis_inverse) { + add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex()); + add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord()); + } else { + add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex()); + add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord()); + } + + } else { + if (_vis_inverse) { + // We need a 3-d texture coordinate if we're inverting the vis + // and it's 3-d. But we still don't need normals in that case. + add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex()); + add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord()); + } else { + // Otherwise, we only need a 2-d texture coordinate, and we do + // want normals. + add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex()); + add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal()); + add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord()); + } + } + + if (_flat_texcoord_name != (InternalName *)NULL) { + // We need an additional texcoord column for the flat texcoords. + add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name); + } + + if (_vis_blend != (PNMImage *)NULL) { + // The blend map, if specified, also gets applied to the vertices. + add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::make_array_format +// Access: Private +// Description: Constructs a GeomVertexFormat that corresponds to the +// vis_columns list. +//////////////////////////////////////////////////////////////////// +CPT(GeomVertexFormat) PfmVizzer:: +make_array_format(const VisColumns &vis_columns) const { + PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat; + + for (VisColumns::const_iterator vci = vis_columns.begin(); + vci != vis_columns.end(); + ++vci) { + const VisColumn &column = *vci; + InternalName *name = column._name; + + int num_components = 0; + GeomEnums::NumericType numeric_type = GeomEnums::NT_float32; + GeomEnums::Contents contents = GeomEnums::C_point; + switch (column._target) { + case CT_texcoord2: + num_components = 2; + numeric_type = GeomEnums::NT_float32; + contents = GeomEnums::C_texcoord; + break; + + case CT_texcoord3: + num_components = 3; + numeric_type = GeomEnums::NT_float32; + contents = GeomEnums::C_texcoord; + break; + + case CT_vertex1: + case CT_vertex2: + case CT_vertex3: + num_components = 3; + numeric_type = GeomEnums::NT_float32; + contents = GeomEnums::C_point; + break; + + case CT_normal3: + num_components = 3; + numeric_type = GeomEnums::NT_float32; + contents = GeomEnums::C_vector; + break; + + case CT_blend1: + num_components = 4; + numeric_type = GeomEnums::NT_uint8; + contents = GeomEnums::C_color; + break; + } + nassertr(num_components != 0, NULL); + + array_format->add_column(name, num_components, numeric_type, contents); + } + + return GeomVertexFormat::register_format(array_format); +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::VisColumn::add_data +// Access: Public +// Description: Adds the data for this column to the appropriate +// column of the GeomVertexWriter. +//////////////////////////////////////////////////////////////////// +void PfmVizzer::VisColumn:: +add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const { + const PfmFile &pfm = vizzer.get_pfm(); + + switch (_source) { + case CT_texcoord2: + { + LPoint2f uv(PN_float32(xi) / PN_float32(pfm.get_x_size() - 1), + PN_float32(yi) / PN_float32(pfm.get_y_size() - 1)); + transform_point(uv); + vwriter.set_data2f(uv); + } + break; + + case CT_texcoord3: + { + LPoint3f uv(PN_float32(xi) / PN_float32(pfm.get_x_size() - 1), + PN_float32(yi) / PN_float32(pfm.get_y_size() - 1), + 0.0f); + transform_point(uv); + vwriter.set_data3f(uv); + } + break; + + case CT_vertex1: + { + PN_float32 p = pfm.get_point1(xi, yi); + LPoint2f point(p, 0.0); + transform_point(point); + vwriter.set_data2f(point); + } + break; + + case CT_vertex2: + { + LPoint2f point = pfm.get_point2(xi, yi); + transform_point(point); + vwriter.set_data2f(point); + } + break; + + case CT_vertex3: + { + LPoint3f point = pfm.get_point(xi, yi); + transform_point(point); + vwriter.set_data3f(point); + } + break; + + case CT_normal3: + { + // Calculate the normal based on two neighboring vertices. + LPoint3f v[3]; + v[0] = pfm.get_point(xi, yi); + if (xi + 1 < pfm.get_x_size()) { + v[1] = pfm.get_point(xi + 1, yi); + } else { + v[1] = v[0]; + v[0] = pfm.get_point(xi - 1, yi); + } + + if (yi + 1 < pfm.get_y_size()) { + v[2] = pfm.get_point(xi, yi + 1); + } else { + v[2] = v[0]; + v[0] = pfm.get_point(xi, yi - 1); + } + + LVector3f n = LVector3f::zero(); + for (int i = 0; i < 3; ++i) { + const LPoint3f &v0 = v[i]; + const LPoint3f &v1 = v[(i + 1) % 3]; + n[0] += v0[1] * v1[2] - v0[2] * v1[1]; + n[1] += v0[2] * v1[0] - v0[0] * v1[2]; + n[2] += v0[0] * v1[1] - v0[1] * v1[0]; + } + n.normalize(); + nassertv(!n.is_nan()); + if (reverse_normals) { + n = -n; + } + transform_vector(n); + vwriter.set_data3f(n); + } + break; + + case CT_blend1: + { + const PNMImage *vis_blend = vizzer.get_vis_blend(); + if (vis_blend != NULL) { + double gray = vis_blend->get_gray(xi, yi); + vwriter.set_data3d(gray, gray, gray); + } + } + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::VisColumn::transform_point +// Access: Public +// Description: Transforms the indicated point as specified by the +// VisColumn. +//////////////////////////////////////////////////////////////////// +void PfmVizzer::VisColumn:: +transform_point(LPoint2f &point) const { + if (!_transform->is_identity()) { + LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::VisColumn::transform_point +// Access: Public +// Description: Transforms the indicated point as specified by the +// VisColumn. +//////////////////////////////////////////////////////////////////// +void PfmVizzer::VisColumn:: +transform_point(LPoint3f &point) const { + if (!_transform->is_identity()) { + LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point); + } + if (_lens != (Lens *)NULL) { + static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + LPoint3 film; + _lens->project(LCAST(PN_stdfloat, point), film); + point = to_uv.xform_point(LCAST(PN_float32, film)); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmVizzer::VisColumn::transform_vector +// Access: Public +// Description: Transforms the indicated vector as specified by the +// VisColumn. +//////////////////////////////////////////////////////////////////// +void PfmVizzer::VisColumn:: +transform_vector(LVector3f &vec) const { + if (!_transform->is_identity()) { + LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec); + } +} diff --git a/panda/src/grutil/pfmVizzer.h b/panda/src/grutil/pfmVizzer.h new file mode 100644 index 0000000000..72c883b73a --- /dev/null +++ b/panda/src/grutil/pfmVizzer.h @@ -0,0 +1,120 @@ +// Filename: pfmVizzer.h +// Created by: drose (30Sep12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PFMVIZZER_H +#define PFMVIZZER_H + +#include "pandabase.h" +#include "nodePath.h" +#include "internalName.h" +#include "lens.h" +#include "pfmFile.h" + +class GeomNode; +class Lens; +class GeomVertexWriter; + +//////////////////////////////////////////////////////////////////// +// Class : PfmVizzer +// Description : This class aids in the visualization and manipulation +// of PfmFile objects. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA_GRUTIL PfmVizzer { +PUBLISHED: + PfmVizzer(PfmFile &pfm); + INLINE PfmFile &get_pfm(); + INLINE const PfmFile &get_pfm() const; + + BLOCKING void project(const Lens *lens); + BLOCKING void extrude(const Lens *lens); + + INLINE void set_vis_inverse(bool vis_inverse); + INLINE bool get_vis_inverse() const; + INLINE void set_flat_texcoord_name(InternalName *flat_texcoord_name); + INLINE void clear_flat_texcoord_name(); + INLINE InternalName *get_flat_texcoord_name() const; + INLINE void set_vis_2d(bool vis_2d); + INLINE bool get_vis_2d() const; + + INLINE void set_vis_blend(const PNMImage *vis_blend); + INLINE void clear_vis_blend(); + INLINE const PNMImage *get_vis_blend() const; + + enum ColumnType { + CT_texcoord2, + CT_texcoord3, + CT_vertex1, + CT_vertex2, + CT_vertex3, + CT_normal3, + CT_blend1, + }; + void clear_vis_columns(); + void add_vis_column(ColumnType source, ColumnType target, + InternalName *name, + const TransformState *transform = NULL, const Lens *lens = NULL); + + BLOCKING NodePath generate_vis_points() const; + + enum MeshFace { + MF_front = 0x01, + MF_back = 0x02, + MF_both = 0x03, + }; + BLOCKING NodePath generate_vis_mesh(MeshFace face = MF_front) const; + +private: + void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const; + + + class VisColumn { + public: + void add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const; + void transform_point(LPoint2f &point) const; + void transform_point(LPoint3f &point) const; + void transform_vector(LVector3f &vec) const; + + public: + ColumnType _source; + ColumnType _target; + PT(InternalName) _name; + CPT(TransformState) _transform; + CPT(Lens) _lens; + }; + typedef pvector VisColumns; + + static void add_vis_column(VisColumns &vis_columns, + ColumnType source, ColumnType target, + InternalName *name, + const TransformState *transform = NULL, const Lens *lens = NULL); + void build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const; + CPT(GeomVertexFormat) make_array_format(const VisColumns &vis_columns) const; + +private: + PfmFile &_pfm; + + bool _vis_inverse; + PT(InternalName) _flat_texcoord_name; + bool _vis_2d; + const PNMImage *_vis_blend; + + VisColumns _vis_columns; + + friend class VisColumn; +}; + +#include "pfmVizzer.I" + +#endif + diff --git a/panda/src/pnmimage/config_pnmimage.cxx b/panda/src/pnmimage/config_pnmimage.cxx index add80a36db..6edc7ed71a 100644 --- a/panda/src/pnmimage/config_pnmimage.cxx +++ b/panda/src/pnmimage/config_pnmimage.cxx @@ -36,18 +36,6 @@ ConfigVariableBool pfm_reverse_dimensions "backwards, in the form height width instead of width height, " "on input. Does not affect output, which is always written width height.")); -ConfigVariableInt pfm_vis_max_vertices -("pfm-vis-max-vertices", 65535, - PRC_DESC("Specifies the maximum number of vertex entries that may appear in " - "a single generated mesh. If the mesh would require more than that, " - "the mesh is subdivided into smaller pieces.")); - -ConfigVariableInt pfm_vis_max_indices -("pfm-vis-max-indices", 1048576, - PRC_DESC("Specifies the maximum number of vertex references that may appear in " - "a single generated mesh. If the mesh would require more than that, " - "the mesh is subdivided into smaller pieces.")); - //////////////////////////////////////////////////////////////////// // Function: init_libpnmimage // Description: Initializes the library. This must be called at diff --git a/panda/src/pnmimage/config_pnmimage.h b/panda/src/pnmimage/config_pnmimage.h index b8c49d1c51..6eecae1203 100644 --- a/panda/src/pnmimage/config_pnmimage.h +++ b/panda/src/pnmimage/config_pnmimage.h @@ -24,8 +24,6 @@ NotifyCategoryDecl(pnmimage, EXPCL_PANDA_PNMIMAGE, EXPTP_PANDA_PNMIMAGE); extern ConfigVariableBool pfm_force_littleendian; extern ConfigVariableBool pfm_reverse_dimensions; -extern ConfigVariableInt pfm_vis_max_vertices; -extern ConfigVariableInt pfm_vis_max_indices; extern EXPCL_PANDA_PNMIMAGE void init_libpnmimage(); diff --git a/panda/src/pnmimage/pfmFile.I b/panda/src/pnmimage/pfmFile.I index 3a581613b0..ea38adbecd 100644 --- a/panda/src/pnmimage/pfmFile.I +++ b/panda/src/pnmimage/pfmFile.I @@ -442,19 +442,6 @@ get_no_data_value() const { return _no_data_value; } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::xform -// Access: Published -// Description: Applies the indicated transform matrix to all points -// in-place. -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -xform(const TransformState *transform) { - if (!transform->is_identity()) { - xform(transform->get_mat()); - } -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::xform // Access: Published @@ -465,6 +452,7 @@ INLINE void PfmFile:: xform(const LMatrix4d &transform) { xform(LCAST(PN_float32, transform)); } + //////////////////////////////////////////////////////////////////// // Function: PfmFile::compute_planar_bounds // Access: Published @@ -489,152 +477,6 @@ compute_planar_bounds(const LPoint2d ¢er, PN_float32 point_dist, PN_float32 return compute_planar_bounds(LCAST(PN_float32, center), point_dist, sample_radius, points_only); } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::set_vis_inverse -// Access: Published -// Description: Sets the vis_inverse flag. When this flag is true, -// vis meshes and point clouds are generated with the -// 3-d depth value in the texture coordinates, and the -// 2-d index value in the vertex position. When it is -// false, meshes are generated normally, with the 3-d -// depth value in the vertex position and the 2-d index -// value in the texture coordinates. -// -// This may be used in lieu of the lower-level -// add_vis_column(). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -set_vis_inverse(bool vis_inverse) { - _vis_inverse = vis_inverse; - clear_vis_columns(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::get_vis_inverse -// Access: Published -// Description: Returns the vis_inverse flag. See set_vis_inverse(). -//////////////////////////////////////////////////////////////////// -INLINE bool PfmFile:: -get_vis_inverse() const { - return _vis_inverse; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::set_flat_texcoord_name -// Access: Published -// Description: If the flat_texcoord_name is specified, it is the -// name of an additional vertex column that will be -// created for the "flat" texture coordinates, i.e. the -// original 0..1 values that correspond to the 2-D index -// position of each point in the original pfm file. -// -// These are the same values that will be assigned to -// the default texture coordinates if the vis_inverse -// flag is *not* true. -// -// This may be used in lieu of the lower-level -// add_vis_column(). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -set_flat_texcoord_name(InternalName *flat_texcoord_name) { - _flat_texcoord_name = flat_texcoord_name; - clear_vis_columns(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::clear_flat_texcoord_name -// Access: Published -// Description: Resets the flat_texcoord_name to empty, so that -// additional texture coordinates are not created. -// -// This may be used in lieu of the lower-level -// add_vis_column(). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -clear_flat_texcoord_name() { - _flat_texcoord_name = NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::get_flat_texcoord_name -// Access: Published -// Description: Returns the flat_texcoord_name. See set_flat_texcoord_name(). -//////////////////////////////////////////////////////////////////// -INLINE InternalName *PfmFile:: -get_flat_texcoord_name() const { - return _flat_texcoord_name; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::set_vis_2d -// Access: Published -// Description: Sets the vis_2d flag. When this flag is true, -// only the first two (x, y) value of each depth point -// is considered meaningful; the z component is ignored. -// This is only relevant for generating visualizations. -// -// This may be used in lieu of the lower-level -// add_vis_column(). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -set_vis_2d(bool vis_2d) { - _vis_2d = vis_2d; - clear_vis_columns(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::get_vis_2d -// Access: Published -// Description: Returns the vis_2d flag. See set_vis_2d(). -//////////////////////////////////////////////////////////////////// -INLINE bool PfmFile:: -get_vis_2d() const { - return _vis_2d; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::set_vis_blend -// Access: Published -// Description: Specifies a blending map--a grayscale image--that -// will be applied to the vertex color during -// generate_vis_mesh() and generate_vis_points(). The -// image size must exactly match the mesh size of the -// PfmFile. -// -// Ownership of the pointer is not kept by the PfmFile; -// it is your responsibility to ensure it does not -// destruct during the lifetime of the PfmFile (or at -// least not before your subsequent call to -// generate_vis_mesh()). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -set_vis_blend(const PNMImage *vis_blend) { - _vis_blend = vis_blend; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::set_vis_blend -// Access: Published -// Description: Removes the blending map set by a prior call to -// set_vis_blend(). -//////////////////////////////////////////////////////////////////// -INLINE void PfmFile:: -clear_vis_blend() { - _vis_blend = NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::get_vis_blend -// Access: Published -// Description: Returns the blending map set by the most recent call -// to set_vis_blend(), or NULL if there is no blending -// map in effect. -//////////////////////////////////////////////////////////////////// -INLINE const PNMImage *PfmFile:: -get_vis_blend() const { - return _vis_blend; -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::get_table // Access: Public diff --git a/panda/src/pnmimage/pfmFile.cxx b/panda/src/pnmimage/pfmFile.cxx index 60c71ca6cc..e96c3f4fb9 100644 --- a/panda/src/pnmimage/pfmFile.cxx +++ b/panda/src/pnmimage/pfmFile.cxx @@ -19,18 +19,10 @@ #include "littleEndian.h" #include "bigEndian.h" #include "cmath.h" -#include "geomNode.h" -#include "geom.h" -#include "geomVertexData.h" -#include "geomVertexFormat.h" -#include "geomPoints.h" -#include "geomTriangles.h" -#include "geomVertexWriter.h" #include "pnmImage.h" #include "pnmReader.h" #include "pnmWriter.h" #include "string_utils.h" -#include "lens.h" #include "look_at.h" //////////////////////////////////////////////////////////////////// @@ -43,9 +35,6 @@ PfmFile() { _has_no_data_value = false; _no_data_value = LPoint4f::zero(); _has_point = has_point_noop; - _vis_inverse = false; - _vis_2d = false; - _vis_blend = NULL; clear(); } @@ -61,10 +50,7 @@ PfmFile(const PfmFile ©) : _scale(copy._scale), _has_no_data_value(copy._has_no_data_value), _no_data_value(copy._no_data_value), - _has_point(copy._has_point), - _vis_inverse(copy._vis_inverse), - _vis_2d(copy._vis_2d), - _vis_blend(copy._vis_blend) + _has_point(copy._has_point) { } @@ -81,9 +67,6 @@ operator = (const PfmFile ©) { _has_no_data_value = copy._has_no_data_value; _no_data_value = copy._no_data_value; _has_point = copy._has_point; - _vis_inverse = copy._vis_inverse; - _vis_2d = copy._vis_2d; - _vis_blend = copy._vis_blend; } //////////////////////////////////////////////////////////////////// @@ -97,7 +80,6 @@ clear() { _y_size = 0; _scale = 1.0; _num_channels = 3; - _vis_blend = NULL; _table.clear(); clear_no_data_value(); } @@ -114,7 +96,6 @@ clear(int x_size, int y_size, int num_channels) { _y_size = y_size; _scale = 1.0; _num_channels = num_channels; - _vis_blend = NULL; _table.clear(); int size = _x_size * _y_size * _num_channels; @@ -948,112 +929,6 @@ xform(const LMatrix4f &transform) { } } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::project -// Access: Published -// Description: Adjusts each (x, y, z) point of the Pfm file by -// projecting it through the indicated lens, converting -// each point to a (u, v, w) texture coordinate. The -// resulting file can be generated to a mesh (with -// set_vis_inverse(true) and generate_vis_mesh()) -// that will apply the lens distortion to an arbitrary -// texture image. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -project(const Lens *lens) { - nassertv(is_valid()); - - static LMatrix4f to_uv(0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.5f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f); - - for (int yi = 0; yi < _y_size; ++yi) { - for (int xi = 0; xi < _x_size; ++xi) { - if (!has_point(xi, yi)) { - continue; - } - LPoint3f &p = modify_point(xi, yi); - - LPoint3 film; - lens->project(LCAST(PN_stdfloat, p), film); - p = to_uv.xform_point(LCAST(PN_float32, film)); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::extrude -// Access: Published -// Description: Converts each (u, v, depth) point of the Pfm file to -// an (x, y, z) point, by reversing project(). If the -// original file is only a 1-d file, assumes that it is -// a depth map with implicit (u, v) coordinates. -// -// This method is only valid for a linear lens (e.g. a -// PerspectiveLens or OrthographicLens). Non-linear -// lenses don't necessarily compute a sensible depth -// coordinate. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -extrude(const Lens *lens) { - nassertv(is_valid()); - nassertv(lens->is_linear()); - - static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 2.0, 0.0, - -1.0, -1.0, -1.0, 1.0); - const LMatrix4 &proj_mat_inv = lens->get_projection_mat_inv(); - - PfmFile result; - result.clear(_x_size, _y_size, 3); - result.set_zero_special(true); - - if (_num_channels == 1) { - // Create an implicit UV coordinate for each point. - LPoint2 uv_scale(1.0, 1.0); - if (_x_size > 1) { - uv_scale[0] = 1.0 / PN_stdfloat(_x_size - 1); - } - if (_y_size > 1) { - uv_scale[1] = 1.0 / PN_stdfloat(_y_size - 1); - } - for (int yi = 0; yi < _y_size; ++yi) { - for (int xi = 0; xi < _x_size; ++xi) { - if (!has_point(xi, yi)) { - continue; - } - LPoint3 p; - p.set((PN_stdfloat)xi * uv_scale[0], - (PN_stdfloat)yi * uv_scale[1], - (PN_stdfloat)get_point1(xi, yi)); - - from_uv.xform_point_in_place(p); - proj_mat_inv.xform_point_general_in_place(p); - result.set_point(xi, yi, p); - } - } - } else { - // Use the existing UV coordinate for each point. - for (int yi = 0; yi < _y_size; ++yi) { - for (int xi = 0; xi < _x_size; ++xi) { - if (!has_point(xi, yi)) { - continue; - } - LPoint3 p; - p = LCAST(PN_stdfloat, get_point(xi, yi)); - - from_uv.xform_point_in_place(p); - proj_mat_inv.xform_point_general_in_place(p); - result.set_point(xi, yi, p); - } - } - } - - (*this) = result; -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::forward_distort // Access: Published @@ -1490,163 +1365,6 @@ compute_sample_point(LPoint3f &result, } } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::clear_vis_columns -// Access: Published -// Description: Removes all of the previously-added vis columns in -// preparation for building a new list. See -// add_vis_column(). -//////////////////////////////////////////////////////////////////// -void PfmFile:: -clear_vis_columns() { - _vis_columns.clear(); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::add_vis_column -// Access: Published -// Description: Adds a new vis column specification to the list of -// vertex data columns that will be generated at the -// next call to generate_vis_points() or -// generate_vis_mesh(). This advanced interface -// supercedes the higher-level set_vis_inverse(), -// set_flat_texcoord_name(), and set_vis_2d(). -// -// If you use this advanced interface, you must specify -// explicitly the complete list of data columns to be -// created in the resulting GeomVertexData, by calling -// add_vis_column() each time. For each column, you -// specify the source of the column in the PFMFile, the -// target column and name in the GeomVertexData, and an -// optional transform matrix and/or lens to transform -// and project the point before generating it. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -add_vis_column(ColumnType source, ColumnType target, - InternalName *name, const TransformState *transform, - const Lens *lens) { - add_vis_column(_vis_columns, source, target, name, transform, lens); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::generate_vis_points -// Access: Published -// Description: Creates a point cloud with the points of the pfm as -// 3-d coordinates in space, and texture coordinates -// ranging from 0 .. 1 based on the position within the -// pfm grid. -//////////////////////////////////////////////////////////////////// -NodePath PfmFile:: -generate_vis_points() const { - nassertr(is_valid(), NodePath()); - - CPT(GeomVertexFormat) format; - if (_vis_inverse) { - if (_vis_2d) { - format = GeomVertexFormat::get_v3t2(); - } else { - // We need a 3-d texture coordinate if we're inverting the vis - // and it's 3-d. - GeomVertexArrayFormat *v3t3 = new GeomVertexArrayFormat - (InternalName::get_vertex(), 3, - Geom::NT_stdfloat, Geom::C_point, - InternalName::get_texcoord(), 3, - Geom::NT_stdfloat, Geom::C_texcoord); - format = GeomVertexFormat::register_format(v3t3); - } - } else { - format = GeomVertexFormat::get_v3t2(); - } - - PT(GeomVertexData) vdata = new GeomVertexData - ("points", format, Geom::UH_static); - vdata->set_num_rows(_x_size * _y_size); - GeomVertexWriter vertex(vdata, InternalName::get_vertex()); - GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - - LPoint2f uv_scale(1.0, 1.0); - if (_x_size > 1) { - uv_scale[0] = 1.0f / PN_float32(_x_size - 1); - } - if (_y_size > 1) { - uv_scale[1] = 1.0f / PN_float32(_y_size - 1); - } - - int num_points = 0; - for (int yi = 0; yi < _y_size; ++yi) { - for (int xi = 0; xi < _x_size; ++xi) { - if (!has_point(xi, yi)) { - continue; - } - - const LPoint3f &point = get_point(xi, yi); - LPoint2f uv(PN_float32(xi) * uv_scale[0], - PN_float32(yi) * uv_scale[1]); - if (_vis_inverse) { - vertex.add_data2f(uv); - texcoord.add_data3f(point); - } else if (_vis_2d) { - vertex.add_data2f(point[0], point[1]); - texcoord.add_data2f(uv); - } else { - vertex.add_data3f(point); - texcoord.add_data2f(uv); - } - ++num_points; - } - } - - PT(Geom) geom = new Geom(vdata); - PT(GeomPoints) points = new GeomPoints(Geom::UH_static); - points->add_next_vertices(num_points); - geom->add_primitive(points); - - PT(GeomNode) gnode = new GeomNode(""); - gnode->add_geom(geom); - return NodePath(gnode); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::generate_vis_mesh -// Access: Published -// Description: Creates a triangle mesh with the points of the pfm as -// 3-d coordinates in space, and texture coordinates -// ranging from 0 .. 1 based on the position within the -// pfm grid. -//////////////////////////////////////////////////////////////////// -NodePath PfmFile:: -generate_vis_mesh(MeshFace face) const { - nassertr(is_valid(), NodePath()); - nassertr(face != 0, NodePath()); - - if (_num_channels == 1 && _vis_columns.empty()) { - // If we're generating a default mesh from a one-channel pfm file, - // expand it to a three-channel pfm file to make the visualization - // useful. - PfmFile expanded; - expanded.clear_to_texcoords(_x_size, _y_size); - expanded.copy_channel(2, *this, 0); - return expanded.generate_vis_mesh(face); - } - - if (_x_size == 1 || _y_size == 1) { - // Can't generate a 1-d mesh, so generate points in this case. - return generate_vis_points(); - } - - PT(GeomNode) gnode = new GeomNode(""); - - if (face & MF_front) { - make_vis_mesh_geom(gnode, false); - } - - if (face & MF_back) { - make_vis_mesh_geom(gnode, true); - } - - return NodePath(gnode); -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::output // Access: Published @@ -1658,161 +1376,6 @@ output(ostream &out) const { << _num_channels << " channels."; } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::make_vis_mesh_geom -// Access: Private -// Description: Returns a triangle mesh for the pfm. If inverted is -// true, the mesh is facing the opposite direction. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -make_vis_mesh_geom(GeomNode *gnode, bool inverted) const { - int num_x_cells = 1; - int num_y_cells = 1; - - int x_size = _x_size; - int y_size = _y_size; - - // This is the number of independent vertices we will require. - int num_vertices = x_size * y_size; - if (num_vertices == 0) { - // Trivial no-op. - return; - } - - bool reverse_normals = inverted; - bool reverse_faces = inverted; - if (!is_right_handed(get_default_coordinate_system())) { - reverse_faces = !reverse_faces; - } - - // This is the max number of vertex indices we might add to the - // GeomTriangles. (We might actually add fewer than this due to - // omitting the occasional missing data point.) - int max_indices = (x_size - 1) * (y_size - 1) * 6; - - while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) { - // Too many vertices in one mesh. Subdivide the mesh into smaller - // pieces. - if (num_x_cells > num_y_cells) { - ++num_y_cells; - } else { - ++num_x_cells; - } - - x_size = (_x_size + num_x_cells - 1) / num_x_cells + 1; - y_size = (_y_size + num_y_cells - 1) / num_y_cells + 1; - - num_vertices = x_size * y_size; - max_indices = (x_size - 1) * (y_size - 1) * 6; - } - - // OK, now we know how many cells we need. - if (pnmimage_cat.is_debug()) { - pnmimage_cat.debug() - << "Generating mesh with " << num_x_cells << " x " << num_y_cells - << " pieces.\n"; - } - - VisColumns vis_columns = _vis_columns; - if (vis_columns.empty()) { - build_auto_vis_columns(vis_columns, true); - } - - CPT(GeomVertexFormat) format = make_array_format(vis_columns); - - for (int yci = 0; yci < num_y_cells; ++yci) { - int y_begin = (yci * _y_size) / num_y_cells; - int y_end = ((yci + 1) * _y_size) / num_y_cells; - - // Include the first vertex from the next strip in this strip's - // vertices, so we are connected. - y_end = min(y_end + 1, _y_size); - - y_size = y_end - y_begin; - if (y_size == 0) { - continue; - } - - for (int xci = 0; xci < num_x_cells; ++xci) { - int x_begin = (xci * _x_size) / num_x_cells; - int x_end = ((xci + 1) * _x_size) / num_x_cells; - x_end = min(x_end + 1, _x_size); - x_size = x_end - x_begin; - if (x_size == 0) { - continue; - } - - num_vertices = x_size * y_size; - max_indices = (x_size - 1) * (y_size - 1) * 6; - - ostringstream mesh_name; - mesh_name << "mesh_" << xci << "_" << yci; - PT(GeomVertexData) vdata = new GeomVertexData - (mesh_name.str(), format, Geom::UH_static); - - vdata->set_num_rows(num_vertices); - - // Fill in all of the vertices. - for (VisColumns::const_iterator vci = vis_columns.begin(); - vci != vis_columns.end(); - ++vci) { - const VisColumn &column = *vci; - GeomVertexWriter vwriter(vdata, column._name); - vwriter.set_row(0); - - for (int yi = y_begin; yi < y_end; ++yi) { - for (int xi = x_begin; xi < x_end; ++xi) { - column.add_data(*this, vwriter, xi, yi, reverse_normals); - } - } - } - - PT(Geom) geom = new Geom(vdata); - PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static); - - tris->reserve_num_vertices(max_indices); - - for (int yi = y_begin; yi < y_end - 1; ++yi) { - for (int xi = x_begin; xi < x_end - 1; ++xi) { - - if (_has_no_data_value) { - if (!has_point(xi, yi) || - !has_point(xi, yi + 1) || - !has_point(xi + 1, yi + 1) || - !has_point(xi + 1, yi)) { - continue; - } - } - - int xi0 = xi - x_begin; - int yi0 = yi - y_begin; - - int vi0 = ((xi0) + (yi0) * x_size); - int vi1 = ((xi0) + (yi0 + 1) * x_size); - int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size); - int vi3 = ((xi0 + 1) + (yi0) * x_size); - - if (reverse_faces) { - tris->add_vertices(vi2, vi0, vi1); - tris->close_primitive(); - - tris->add_vertices(vi3, vi0, vi2); - tris->close_primitive(); - } else { - tris->add_vertices(vi2, vi1, vi0); - tris->close_primitive(); - - tris->add_vertices(vi3, vi2, vi0); - tris->close_primitive(); - } - } - } - geom->add_primitive(tris); - gnode->add_geom(geom); - } - } -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::box_filter_region // Access: Private @@ -2089,138 +1652,6 @@ box_filter_point(LPoint4f &result, PN_float32 &coverage, coverage += contrib; } -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::add_vis_column -// Access: Private, Static -// Description: The private implementation of the public -// add_vis_column(), this adds the column to the -// indicated specific vector. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target, - InternalName *name, const TransformState *transform, - const Lens *lens) { - VisColumn column; - column._source = source; - column._target = target; - column._name = name; - column._transform = transform; - if (transform == NULL) { - column._transform = TransformState::make_identity(); - } - column._lens = lens; - vis_columns.push_back(column); -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::build_auto_vis_columns -// Access: Private -// Description: This function is called internally to construct the -// list of vis_columns automatically from the high-level -// interfaces such as set_vis_inverse(), -// set_flat_texcoord_name(), and set_vis_2d(). It's not -// called if the list has been build explicitly. -//////////////////////////////////////////////////////////////////// -void PfmFile:: -build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const { - vis_columns.clear(); - - if (_vis_2d) { - // No normals needed if we're just generating a 2-d mesh. - if (_vis_inverse) { - add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex()); - add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord()); - } else { - add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex()); - add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord()); - } - - } else { - if (_vis_inverse) { - // We need a 3-d texture coordinate if we're inverting the vis - // and it's 3-d. But we still don't need normals in that case. - add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex()); - add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord()); - } else { - // Otherwise, we only need a 2-d texture coordinate, and we do - // want normals. - add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex()); - add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal()); - add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord()); - } - } - - if (_flat_texcoord_name != (InternalName *)NULL) { - // We need an additional texcoord column for the flat texcoords. - add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name); - } - - if (_vis_blend != (PNMImage *)NULL) { - // The blend map, if specified, also gets applied to the vertices. - add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color()); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::make_array_format -// Access: Private -// Description: Constructs a GeomVertexFormat that corresponds to the -// vis_columns list. -//////////////////////////////////////////////////////////////////// -CPT(GeomVertexFormat) PfmFile:: -make_array_format(const VisColumns &vis_columns) const { - PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat; - - for (VisColumns::const_iterator vci = vis_columns.begin(); - vci != vis_columns.end(); - ++vci) { - const VisColumn &column = *vci; - InternalName *name = column._name; - - int num_components = 0; - GeomEnums::NumericType numeric_type = GeomEnums::NT_float32; - GeomEnums::Contents contents = GeomEnums::C_point; - switch (column._target) { - case CT_texcoord2: - num_components = 2; - numeric_type = GeomEnums::NT_float32; - contents = GeomEnums::C_texcoord; - break; - - case CT_texcoord3: - num_components = 3; - numeric_type = GeomEnums::NT_float32; - contents = GeomEnums::C_texcoord; - break; - - case CT_vertex1: - case CT_vertex2: - case CT_vertex3: - num_components = 3; - numeric_type = GeomEnums::NT_float32; - contents = GeomEnums::C_point; - break; - - case CT_normal3: - num_components = 3; - numeric_type = GeomEnums::NT_float32; - contents = GeomEnums::C_vector; - break; - - case CT_blend1: - num_components = 4; - numeric_type = GeomEnums::NT_uint8; - contents = GeomEnums::C_color; - break; - } - nassertr(num_components != 0, NULL); - - array_format->add_column(name, num_components, numeric_type, contents); - } - - return GeomVertexFormat::register_format(array_format); -} - //////////////////////////////////////////////////////////////////// // Function: PfmFile::fill_mini_grid // Access: Private @@ -2320,153 +1751,3 @@ has_point_chan4(const PfmFile *self, int x, int y) { } return false; } - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::VisColumn::add_data -// Access: Public -// Description: Adds the data for this column to the appropriate -// column of the GeomVertexWriter. -//////////////////////////////////////////////////////////////////// -void PfmFile::VisColumn:: -add_data(const PfmFile &file, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const { - switch (_source) { - case CT_texcoord2: - { - LPoint2f uv(PN_float32(xi) / PN_float32(file._x_size - 1), - PN_float32(yi) / PN_float32(file._y_size - 1)); - transform_point(uv); - vwriter.set_data2f(uv); - } - break; - - case CT_texcoord3: - { - LPoint3f uv(PN_float32(xi) / PN_float32(file._x_size - 1), - PN_float32(yi) / PN_float32(file._y_size - 1), - 0.0f); - transform_point(uv); - vwriter.set_data3f(uv); - } - break; - - case CT_vertex1: - { - PN_float32 p = file.get_point1(xi, yi); - LPoint2f point(p, 0.0); - transform_point(point); - vwriter.set_data2f(point); - } - break; - - case CT_vertex2: - { - LPoint2f point = file.get_point2(xi, yi); - transform_point(point); - vwriter.set_data2f(point); - } - break; - - case CT_vertex3: - { - LPoint3f point = file.get_point(xi, yi); - transform_point(point); - vwriter.set_data3f(point); - } - break; - - case CT_normal3: - { - // Calculate the normal based on two neighboring vertices. - LPoint3f v[3]; - v[0] = file.get_point(xi, yi); - if (xi + 1 < file._x_size) { - v[1] = file.get_point(xi + 1, yi); - } else { - v[1] = v[0]; - v[0] = file.get_point(xi - 1, yi); - } - - if (yi + 1 < file._y_size) { - v[2] = file.get_point(xi, yi + 1); - } else { - v[2] = v[0]; - v[0] = file.get_point(xi, yi - 1); - } - - LVector3f n = LVector3f::zero(); - for (int i = 0; i < 3; ++i) { - const LPoint3f &v0 = v[i]; - const LPoint3f &v1 = v[(i + 1) % 3]; - n[0] += v0[1] * v1[2] - v0[2] * v1[1]; - n[1] += v0[2] * v1[0] - v0[0] * v1[2]; - n[2] += v0[0] * v1[1] - v0[1] * v1[0]; - } - n.normalize(); - nassertv(!n.is_nan()); - if (reverse_normals) { - n = -n; - } - transform_vector(n); - vwriter.set_data3f(n); - } - break; - - case CT_blend1: - { - const PNMImage *vis_blend = file.get_vis_blend(); - if (vis_blend != NULL) { - double gray = vis_blend->get_gray(xi, yi); - vwriter.set_data3d(gray, gray, gray); - } - } - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::VisColumn::transform_point -// Access: Public -// Description: Transforms the indicated point as specified by the -// VisColumn. -//////////////////////////////////////////////////////////////////// -void PfmFile::VisColumn:: -transform_point(LPoint2f &point) const { - if (!_transform->is_identity()) { - LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::VisColumn::transform_point -// Access: Public -// Description: Transforms the indicated point as specified by the -// VisColumn. -//////////////////////////////////////////////////////////////////// -void PfmFile::VisColumn:: -transform_point(LPoint3f &point) const { - if (!_transform->is_identity()) { - LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point); - } - if (_lens != (Lens *)NULL) { - static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.5, 0.5, 0.0, 1.0); - LPoint3 film; - _lens->project(LCAST(PN_stdfloat, point), film); - point = to_uv.xform_point(LCAST(PN_float32, film)); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: PfmFile::VisColumn::transform_vector -// Access: Public -// Description: Transforms the indicated vector as specified by the -// VisColumn. -//////////////////////////////////////////////////////////////////// -void PfmFile::VisColumn:: -transform_vector(LVector3f &vec) const { - if (!_transform->is_identity()) { - LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec); - } -} diff --git a/panda/src/pnmimage/pfmFile.h b/panda/src/pnmimage/pfmFile.h index 3d6f1d4a9a..ed317fcf17 100644 --- a/panda/src/pnmimage/pfmFile.h +++ b/panda/src/pnmimage/pfmFile.h @@ -18,17 +18,11 @@ #include "pandabase.h" #include "pnmImageHeader.h" #include "luse.h" -#include "nodePath.h" #include "boundingHexahedron.h" -#include "internalName.h" -#include "lens.h" -class GeomNode; -class Lens; class PNMImage; class PNMReader; class PNMWriter; -class GeomVertexWriter; //////////////////////////////////////////////////////////////////// // Class : PfmFile @@ -98,11 +92,8 @@ PUBLISHED: BLOCKING void resize(int new_x_size, int new_y_size); BLOCKING void reverse_rows(); BLOCKING void flip(bool flip_x, bool flip_y, bool transpose); - INLINE BLOCKING void xform(const TransformState *transform); BLOCKING void xform(const LMatrix4f &transform); INLINE BLOCKING void xform(const LMatrix4d &transform); - BLOCKING void project(const Lens *lens); - BLOCKING void extrude(const Lens *lens); BLOCKING void forward_distort(const PfmFile &dist); BLOCKING void reverse_distort(const PfmFile &dist); BLOCKING void merge(const PfmFile &other); @@ -115,41 +106,6 @@ PUBLISHED: void compute_sample_point(LPoint3f &result, PN_float32 x, PN_float32 y, PN_float32 sample_radius) const; - INLINE void set_vis_inverse(bool vis_inverse); - INLINE bool get_vis_inverse() const; - INLINE void set_flat_texcoord_name(InternalName *flat_texcoord_name); - INLINE void clear_flat_texcoord_name(); - INLINE InternalName *get_flat_texcoord_name() const; - INLINE void set_vis_2d(bool vis_2d); - INLINE bool get_vis_2d() const; - - INLINE void set_vis_blend(const PNMImage *vis_blend); - INLINE void clear_vis_blend(); - INLINE const PNMImage *get_vis_blend() const; - - enum ColumnType { - CT_texcoord2, - CT_texcoord3, - CT_vertex1, - CT_vertex2, - CT_vertex3, - CT_normal3, - CT_blend1, - }; - void clear_vis_columns(); - void add_vis_column(ColumnType source, ColumnType target, - InternalName *name, - const TransformState *transform = NULL, const Lens *lens = NULL); - - BLOCKING NodePath generate_vis_points() const; - - enum MeshFace { - MF_front = 0x01, - MF_back = 0x02, - MF_both = 0x03, - }; - BLOCKING NodePath generate_vis_mesh(MeshFace face = MF_front) const; - void output(ostream &out) const; public: @@ -157,8 +113,6 @@ public: INLINE void swap_table(pvector &table); private: - void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const; - void box_filter_region(PN_float32 &result, PN_float32 x0, PN_float32 y0, PN_float32 x1, PN_float32 y1) const; void box_filter_region(LPoint3f &result, @@ -178,29 +132,6 @@ private: void box_filter_point(LPoint4f &result, PN_float32 &coverage, int x, int y, PN_float32 x_contrib, PN_float32 y_contrib) const; - class VisColumn { - public: - void add_data(const PfmFile &file, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const; - void transform_point(LPoint2f &point) const; - void transform_point(LPoint3f &point) const; - void transform_vector(LVector3f &vec) const; - - public: - ColumnType _source; - ColumnType _target; - PT(InternalName) _name; - CPT(TransformState) _transform; - CPT(Lens) _lens; - }; - typedef pvector VisColumns; - - static void add_vis_column(VisColumns &vis_columns, - ColumnType source, ColumnType target, - InternalName *name, - const TransformState *transform = NULL, const Lens *lens = NULL); - void build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const; - CPT(GeomVertexFormat) make_array_format(const VisColumns &vis_columns) const; - class MiniGridCell { public: MiniGridCell() : _sxi(-1), _syi(-1), _dist(-1) { } @@ -225,17 +156,11 @@ private: bool _has_no_data_value; LPoint4f _no_data_value; - bool _vis_inverse; - PT(InternalName) _flat_texcoord_name; - bool _vis_2d; - const PNMImage *_vis_blend; - - VisColumns _vis_columns; typedef bool HasPointFunc(const PfmFile *file, int x, int y); HasPointFunc *_has_point; - friend class VisColumn; + friend class PfmVizzer; }; #include "pfmFile.I"