|
|
@@ -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);
|
|
|
- }
|
|
|
-}
|