mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
fix build circularity issue
This commit is contained in:
parent
25870f099f
commit
8e3e89b5b3
@ -25,6 +25,7 @@
|
|||||||
lineSegs.I lineSegs.h \
|
lineSegs.I lineSegs.h \
|
||||||
multitexReducer.I multitexReducer.h multitexReducer.cxx \
|
multitexReducer.I multitexReducer.h multitexReducer.cxx \
|
||||||
nodeVertexTransform.I nodeVertexTransform.h \
|
nodeVertexTransform.I nodeVertexTransform.h \
|
||||||
|
pfmVizzer.I pfmVizzer.h \
|
||||||
rigidBodyCombiner.I rigidBodyCombiner.h
|
rigidBodyCombiner.I rigidBodyCombiner.h
|
||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
@ -39,6 +40,7 @@
|
|||||||
sceneGraphAnalyzerMeter.cxx \
|
sceneGraphAnalyzerMeter.cxx \
|
||||||
heightfieldTesselator.cxx \
|
heightfieldTesselator.cxx \
|
||||||
nodeVertexTransform.cxx \
|
nodeVertexTransform.cxx \
|
||||||
|
pfmVizzer.cxx \
|
||||||
pipeOcclusionCullTraverser.cxx \
|
pipeOcclusionCullTraverser.cxx \
|
||||||
lineSegs.cxx \
|
lineSegs.cxx \
|
||||||
rigidBodyCombiner.cxx
|
rigidBodyCombiner.cxx
|
||||||
@ -56,6 +58,7 @@
|
|||||||
lineSegs.I lineSegs.h \
|
lineSegs.I lineSegs.h \
|
||||||
multitexReducer.I multitexReducer.h \
|
multitexReducer.I multitexReducer.h \
|
||||||
nodeVertexTransform.I nodeVertexTransform.h \
|
nodeVertexTransform.I nodeVertexTransform.h \
|
||||||
|
pfmVizzer.I pfmVizzer.h \
|
||||||
rigidBodyCombiner.I rigidBodyCombiner.h
|
rigidBodyCombiner.I rigidBodyCombiner.h
|
||||||
|
|
||||||
#define IGATESCAN all
|
#define IGATESCAN all
|
||||||
|
@ -72,6 +72,18 @@ ConfigVariableBool movies_sync_pages
|
|||||||
"such as cube maps, 3-d textures, or stereo textures, or textures "
|
"such as cube maps, 3-d textures, or stereo textures, or textures "
|
||||||
"with separate color and alpha channel movie sources."));
|
"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
|
// Function: init_libgrutil
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -37,6 +37,9 @@ extern ConfigVariableDouble scene_graph_analyzer_meter_side_margins;
|
|||||||
|
|
||||||
extern ConfigVariableBool movies_sync_pages;
|
extern ConfigVariableBool movies_sync_pages;
|
||||||
|
|
||||||
|
extern ConfigVariableInt pfm_vis_max_vertices;
|
||||||
|
extern ConfigVariableInt pfm_vis_max_indices;
|
||||||
|
|
||||||
extern EXPCL_PANDA_GRUTIL void init_libgrutil();
|
extern EXPCL_PANDA_GRUTIL void init_libgrutil();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
#include "meshDrawer.cxx"
|
||||||
|
#include "meshDrawer2D.cxx"
|
||||||
#include "movieTexture.cxx"
|
#include "movieTexture.cxx"
|
||||||
#include "nodeVertexTransform.cxx"
|
#include "nodeVertexTransform.cxx"
|
||||||
#include "pipeOcclusionCullTraverser.cxx"
|
#include "pipeOcclusionCullTraverser.cxx"
|
||||||
|
#include "pfmVizzer.cxx"
|
||||||
#include "rigidBodyCombiner.cxx"
|
#include "rigidBodyCombiner.cxx"
|
||||||
#include "meshDrawer.cxx"
|
|
||||||
#include "meshDrawer2D.cxx"
|
|
||||||
|
182
panda/src/grutil/pfmVizzer.I
Normal file
182
panda/src/grutil/pfmVizzer.I
Normal file
@ -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;
|
||||||
|
}
|
743
panda/src/grutil/pfmVizzer.cxx
Normal file
743
panda/src/grutil/pfmVizzer.cxx
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
120
panda/src/grutil/pfmVizzer.h
Normal file
120
panda/src/grutil/pfmVizzer.h
Normal file
@ -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<VisColumn> 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
|
||||||
|
|
@ -36,18 +36,6 @@ ConfigVariableBool pfm_reverse_dimensions
|
|||||||
"backwards, in the form height width instead of width height, "
|
"backwards, in the form height width instead of width height, "
|
||||||
"on input. Does not affect output, which is always written 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
|
// Function: init_libpnmimage
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -24,8 +24,6 @@ NotifyCategoryDecl(pnmimage, EXPCL_PANDA_PNMIMAGE, EXPTP_PANDA_PNMIMAGE);
|
|||||||
|
|
||||||
extern ConfigVariableBool pfm_force_littleendian;
|
extern ConfigVariableBool pfm_force_littleendian;
|
||||||
extern ConfigVariableBool pfm_reverse_dimensions;
|
extern ConfigVariableBool pfm_reverse_dimensions;
|
||||||
extern ConfigVariableInt pfm_vis_max_vertices;
|
|
||||||
extern ConfigVariableInt pfm_vis_max_indices;
|
|
||||||
|
|
||||||
extern EXPCL_PANDA_PNMIMAGE void init_libpnmimage();
|
extern EXPCL_PANDA_PNMIMAGE void init_libpnmimage();
|
||||||
|
|
||||||
|
@ -442,19 +442,6 @@ get_no_data_value() const {
|
|||||||
return _no_data_value;
|
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
|
// Function: PfmFile::xform
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -465,6 +452,7 @@ INLINE void PfmFile::
|
|||||||
xform(const LMatrix4d &transform) {
|
xform(const LMatrix4d &transform) {
|
||||||
xform(LCAST(PN_float32, transform));
|
xform(LCAST(PN_float32, transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PfmFile::compute_planar_bounds
|
// Function: PfmFile::compute_planar_bounds
|
||||||
// Access: Published
|
// 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);
|
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
|
// Function: PfmFile::get_table
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -19,18 +19,10 @@
|
|||||||
#include "littleEndian.h"
|
#include "littleEndian.h"
|
||||||
#include "bigEndian.h"
|
#include "bigEndian.h"
|
||||||
#include "cmath.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 "pnmImage.h"
|
||||||
#include "pnmReader.h"
|
#include "pnmReader.h"
|
||||||
#include "pnmWriter.h"
|
#include "pnmWriter.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "lens.h"
|
|
||||||
#include "look_at.h"
|
#include "look_at.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -43,9 +35,6 @@ PfmFile() {
|
|||||||
_has_no_data_value = false;
|
_has_no_data_value = false;
|
||||||
_no_data_value = LPoint4f::zero();
|
_no_data_value = LPoint4f::zero();
|
||||||
_has_point = has_point_noop;
|
_has_point = has_point_noop;
|
||||||
_vis_inverse = false;
|
|
||||||
_vis_2d = false;
|
|
||||||
_vis_blend = NULL;
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,10 +50,7 @@ PfmFile(const PfmFile ©) :
|
|||||||
_scale(copy._scale),
|
_scale(copy._scale),
|
||||||
_has_no_data_value(copy._has_no_data_value),
|
_has_no_data_value(copy._has_no_data_value),
|
||||||
_no_data_value(copy._no_data_value),
|
_no_data_value(copy._no_data_value),
|
||||||
_has_point(copy._has_point),
|
_has_point(copy._has_point)
|
||||||
_vis_inverse(copy._vis_inverse),
|
|
||||||
_vis_2d(copy._vis_2d),
|
|
||||||
_vis_blend(copy._vis_blend)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +67,6 @@ operator = (const PfmFile ©) {
|
|||||||
_has_no_data_value = copy._has_no_data_value;
|
_has_no_data_value = copy._has_no_data_value;
|
||||||
_no_data_value = copy._no_data_value;
|
_no_data_value = copy._no_data_value;
|
||||||
_has_point = copy._has_point;
|
_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;
|
_y_size = 0;
|
||||||
_scale = 1.0;
|
_scale = 1.0;
|
||||||
_num_channels = 3;
|
_num_channels = 3;
|
||||||
_vis_blend = NULL;
|
|
||||||
_table.clear();
|
_table.clear();
|
||||||
clear_no_data_value();
|
clear_no_data_value();
|
||||||
}
|
}
|
||||||
@ -114,7 +96,6 @@ clear(int x_size, int y_size, int num_channels) {
|
|||||||
_y_size = y_size;
|
_y_size = y_size;
|
||||||
_scale = 1.0;
|
_scale = 1.0;
|
||||||
_num_channels = num_channels;
|
_num_channels = num_channels;
|
||||||
_vis_blend = NULL;
|
|
||||||
|
|
||||||
_table.clear();
|
_table.clear();
|
||||||
int size = _x_size * _y_size * _num_channels;
|
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
|
// Function: PfmFile::forward_distort
|
||||||
// Access: Published
|
// 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
|
// Function: PfmFile::output
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -1658,161 +1376,6 @@ output(ostream &out) const {
|
|||||||
<< _num_channels << " channels.";
|
<< _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
|
// Function: PfmFile::box_filter_region
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -2089,138 +1652,6 @@ box_filter_point(LPoint4f &result, PN_float32 &coverage,
|
|||||||
coverage += contrib;
|
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
|
// Function: PfmFile::fill_mini_grid
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -2320,153 +1751,3 @@ has_point_chan4(const PfmFile *self, int x, int y) {
|
|||||||
}
|
}
|
||||||
return false;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -18,17 +18,11 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
#include "pnmImageHeader.h"
|
#include "pnmImageHeader.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
#include "nodePath.h"
|
|
||||||
#include "boundingHexahedron.h"
|
#include "boundingHexahedron.h"
|
||||||
#include "internalName.h"
|
|
||||||
#include "lens.h"
|
|
||||||
|
|
||||||
class GeomNode;
|
|
||||||
class Lens;
|
|
||||||
class PNMImage;
|
class PNMImage;
|
||||||
class PNMReader;
|
class PNMReader;
|
||||||
class PNMWriter;
|
class PNMWriter;
|
||||||
class GeomVertexWriter;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : PfmFile
|
// Class : PfmFile
|
||||||
@ -98,11 +92,8 @@ PUBLISHED:
|
|||||||
BLOCKING void resize(int new_x_size, int new_y_size);
|
BLOCKING void resize(int new_x_size, int new_y_size);
|
||||||
BLOCKING void reverse_rows();
|
BLOCKING void reverse_rows();
|
||||||
BLOCKING void flip(bool flip_x, bool flip_y, bool transpose);
|
BLOCKING void flip(bool flip_x, bool flip_y, bool transpose);
|
||||||
INLINE BLOCKING void xform(const TransformState *transform);
|
|
||||||
BLOCKING void xform(const LMatrix4f &transform);
|
BLOCKING void xform(const LMatrix4f &transform);
|
||||||
INLINE BLOCKING void xform(const LMatrix4d &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 forward_distort(const PfmFile &dist);
|
||||||
BLOCKING void reverse_distort(const PfmFile &dist);
|
BLOCKING void reverse_distort(const PfmFile &dist);
|
||||||
BLOCKING void merge(const PfmFile &other);
|
BLOCKING void merge(const PfmFile &other);
|
||||||
@ -115,41 +106,6 @@ PUBLISHED:
|
|||||||
void compute_sample_point(LPoint3f &result,
|
void compute_sample_point(LPoint3f &result,
|
||||||
PN_float32 x, PN_float32 y, PN_float32 sample_radius) const;
|
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;
|
void output(ostream &out) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -157,8 +113,6 @@ public:
|
|||||||
INLINE void swap_table(pvector<PN_float32> &table);
|
INLINE void swap_table(pvector<PN_float32> &table);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const;
|
|
||||||
|
|
||||||
void box_filter_region(PN_float32 &result,
|
void box_filter_region(PN_float32 &result,
|
||||||
PN_float32 x0, PN_float32 y0, PN_float32 x1, PN_float32 y1) const;
|
PN_float32 x0, PN_float32 y0, PN_float32 x1, PN_float32 y1) const;
|
||||||
void box_filter_region(LPoint3f &result,
|
void box_filter_region(LPoint3f &result,
|
||||||
@ -178,29 +132,6 @@ private:
|
|||||||
void box_filter_point(LPoint4f &result, PN_float32 &coverage,
|
void box_filter_point(LPoint4f &result, PN_float32 &coverage,
|
||||||
int x, int y, PN_float32 x_contrib, PN_float32 y_contrib) const;
|
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<VisColumn> 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 {
|
class MiniGridCell {
|
||||||
public:
|
public:
|
||||||
MiniGridCell() : _sxi(-1), _syi(-1), _dist(-1) { }
|
MiniGridCell() : _sxi(-1), _syi(-1), _dist(-1) { }
|
||||||
@ -225,17 +156,11 @@ private:
|
|||||||
|
|
||||||
bool _has_no_data_value;
|
bool _has_no_data_value;
|
||||||
LPoint4f _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);
|
typedef bool HasPointFunc(const PfmFile *file, int x, int y);
|
||||||
HasPointFunc *_has_point;
|
HasPointFunc *_has_point;
|
||||||
|
|
||||||
friend class VisColumn;
|
friend class PfmVizzer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "pfmFile.I"
|
#include "pfmFile.I"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user