add PfmVizzer::set_aux_pfm() and PfmFile::set_no_data_threshold()

This commit is contained in:
David Rose 2014-03-13 23:16:21 +00:00
parent 25ee1ce285
commit dbc6091cf0
6 changed files with 272 additions and 3 deletions

View File

@ -17,7 +17,7 @@
// Function: PfmVizzer::get_pfm
// Access: Published
// Description: Returns the reference to the PfmFile manipulated by
// thiz PfmVizzer.
// this PfmVizzer.
////////////////////////////////////////////////////////////////////
INLINE PfmFile &PfmVizzer::
get_pfm() {
@ -28,7 +28,7 @@ get_pfm() {
// Function: PfmVizzer::get_pfm
// Access: Published
// Description: Returns the reference to the PfmFile manipulated by
// thiz PfmVizzer.
// this PfmVizzer.
////////////////////////////////////////////////////////////////////
INLINE const PfmFile &PfmVizzer::
get_pfm() const {
@ -206,6 +206,49 @@ get_vis_blend() const {
return _vis_blend;
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::set_aux_pfm
// Access: Published
// Description: Assigns an auxiliary PfmFile to this PfmVizzer. This
// file will be queried by column types
// CT_aux_vertex1/2/3, but has no other meaning to the
// vizzer. This size of this PfmFile should exactly
// match the base PfmFile. No reference count is held
// and no copy is made; the caller is responsible for
// ensuring that the auxiliary PfmFile will persist
// throughout the lifetime of the PfmVizzer it is
// assigned to.
////////////////////////////////////////////////////////////////////
INLINE void PfmVizzer::
set_aux_pfm(const PfmFile *pfm) {
assert(pfm == NULL || (pfm->get_x_size() == _pfm.get_x_size() &&
pfm->get_y_size() == _pfm.get_y_size()));
_aux_pfm = pfm;
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::clear_aux_pfm
// Access: Published
// Description: Removes the auxiliary PfmFile from this PfmVizzer.
////////////////////////////////////////////////////////////////////
INLINE void PfmVizzer::
clear_aux_pfm() {
_aux_pfm = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::get_aux_pfm
// Access: Published
// Description: Returns the reference to the auxiliary PfmFile
// queried by this PfmVizzer. This contains the values
// that will be reflected in CT_aux_vertex3 etc. See
// set_aux_pfm().
////////////////////////////////////////////////////////////////////
INLINE const PfmFile *PfmVizzer::
get_aux_pfm() const {
return _aux_pfm;
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::VisColumn::Constructor
// Access: Public

View File

@ -38,6 +38,7 @@ PfmVizzer(PfmFile &pfm) : _pfm(pfm) {
_vis_2d = false;
_keep_beyond_lens = false;
_vis_blend = NULL;
_aux_pfm = NULL;
}
////////////////////////////////////////////////////////////////////
@ -253,6 +254,9 @@ NodePath PfmVizzer::
generate_vis_points() const {
nassertr(_pfm.is_valid(), NodePath());
bool check_aux_pfm = uses_aux_pfm();
nassertr(!check_aux_pfm || (_aux_pfm != NULL && _aux_pfm->is_valid()), NodePath());
CPT(GeomVertexFormat) format;
if (_vis_inverse) {
if (_vis_2d) {
@ -291,6 +295,9 @@ generate_vis_points() const {
if (!_pfm.has_point(xi, yi)) {
continue;
}
if (check_aux_pfm && !_aux_pfm->has_point(xi, yi)) {
continue;
}
const LPoint3f &point = _pfm.get_point(xi, yi);
LPoint2f uv((PN_float32(xi) + 0.5) * uv_scale[0],
@ -330,6 +337,8 @@ generate_vis_points() const {
NodePath PfmVizzer::
generate_vis_mesh(MeshFace face) const {
nassertr(_pfm.is_valid(), NodePath());
bool check_aux_pfm = uses_aux_pfm();
nassertr(!check_aux_pfm || (_aux_pfm != NULL && _aux_pfm->is_valid()), NodePath());
nassertr(face != 0, NodePath());
if (_pfm.get_num_channels() == 1 && _vis_columns.empty()) {
@ -512,6 +521,31 @@ make_displacement(PNMImage &result, double max_u, double max_v) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::uses_aux_pfm
// Access: Private
// Description: Returns true if any of the vis_column tokens
// reference the aux_pfm file, false otherwise.
////////////////////////////////////////////////////////////////////
bool PfmVizzer::
uses_aux_pfm() const {
for (VisColumns::const_iterator vci = _vis_columns.begin();
vci != _vis_columns.end();
++vci) {
const VisColumn &column = *vci;
switch (column._source) {
case CT_aux_vertex1:
case CT_aux_vertex2:
case CT_aux_vertex3:
return true;
default:
break;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmVizzer::r_fill_displacement
// Access: Private
@ -616,6 +650,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
if (vis_columns.empty()) {
build_auto_vis_columns(vis_columns, true);
}
bool check_aux_pfm = uses_aux_pfm();
CPT(GeomVertexFormat) format = make_array_format(vis_columns);
@ -685,7 +720,13 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
!_pfm.has_point(xi + 1, yi)) {
continue;
}
if (check_aux_pfm && (!_aux_pfm->has_point(xi, yi) ||
!_aux_pfm->has_point(xi, yi + 1) ||
!_aux_pfm->has_point(xi + 1, yi + 1) ||
!_aux_pfm->has_point(xi + 1, yi))) {
continue;
}
if (!keep_beyond_lens &&
(skip_points[(yi - y_begin) * x_size + (xi - x_begin)] ||
skip_points[(yi - y_begin + 1) * x_size + (xi - x_begin)] ||
@ -833,18 +874,21 @@ make_array_format(const VisColumns &vis_columns) const {
break;
case CT_vertex1:
case CT_aux_vertex1:
num_components = 1;
numeric_type = GeomEnums::NT_float32;
contents = GeomEnums::C_point;
break;
case CT_vertex2:
case CT_aux_vertex2:
num_components = 2;
numeric_type = GeomEnums::NT_float32;
contents = GeomEnums::C_point;
break;
case CT_vertex3:
case CT_aux_vertex3:
num_components = 3;
numeric_type = GeomEnums::NT_float32;
contents = GeomEnums::C_point;
@ -917,6 +961,18 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
}
break;
case CT_aux_vertex1:
{
nassertr(vizzer.get_aux_pfm() != NULL, false);
PN_float32 p = vizzer.get_aux_pfm()->get_point1(xi, yi);
LPoint2f point(p, 0.0);
if (!transform_point(point)) {
success = false;
}
vwriter.set_data2f(point);
}
break;
case CT_vertex2:
{
LPoint2f point = pfm.get_point2(xi, yi);
@ -927,6 +983,17 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
}
break;
case CT_aux_vertex2:
{
nassertr(vizzer.get_aux_pfm() != NULL, false);
LPoint2f point = vizzer.get_aux_pfm()->get_point2(xi, yi);
if (!transform_point(point)) {
success = false;
}
vwriter.set_data2f(point);
}
break;
case CT_vertex3:
{
LPoint3f point = pfm.get_point(xi, yi);
@ -937,6 +1004,16 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
}
break;
case CT_aux_vertex3:
{
LPoint3f point = vizzer.get_aux_pfm()->get_point(xi, yi);
if (!transform_point(point)) {
success = false;
}
vwriter.set_data3f(point);
}
break;
case CT_normal3:
{
// Calculate the normal based on two neighboring vertices.

View File

@ -53,6 +53,10 @@ PUBLISHED:
INLINE void clear_vis_blend();
INLINE const PNMImage *get_vis_blend() const;
INLINE void set_aux_pfm(const PfmFile *pfm);
INLINE void clear_aux_pfm();
INLINE const PfmFile *get_aux_pfm() const;
enum ColumnType {
CT_texcoord2,
CT_texcoord3,
@ -61,6 +65,9 @@ PUBLISHED:
CT_vertex3,
CT_normal3,
CT_blend1,
CT_aux_vertex1,
CT_aux_vertex2,
CT_aux_vertex3,
};
void clear_vis_columns();
void add_vis_column(ColumnType source, ColumnType target,
@ -82,6 +89,7 @@ PUBLISHED:
BLOCKING void make_displacement(PNMImage &result, double max_u, double max_v) const;
private:
bool uses_aux_pfm() const;
void r_fill_displacement(PNMImage &result, int xi, int yi,
double nxi, double nyi, double u_scale, double v_scale,
int distance) const;
@ -117,6 +125,7 @@ private:
private:
PfmFile &_pfm;
const PfmFile *_aux_pfm;
bool _vis_inverse;
PT(InternalName) _flat_texcoord_name;

View File

@ -478,6 +478,7 @@ INLINE void PfmFile::
set_no_data_chan4(bool chan4) {
if (chan4 && _num_channels == 4) {
_has_no_data_value = true;
_has_no_data_threshold = false;
_no_data_value.set(0.0, 0.0, 0.0, -1.0);
_has_point = has_point_chan4;
} else {
@ -496,6 +497,18 @@ set_no_data_value(const LPoint4d &no_data_value) {
set_no_data_value(LCAST(PN_float32, no_data_value));
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_no_data_threshold
// Access: Published
// Description: Sets the special threshold value. Points that are
// below this value in all components are considered "no
// value".
////////////////////////////////////////////////////////////////////
INLINE void PfmFile::
set_no_data_threshold(const LPoint4d &no_data_threshold) {
set_no_data_threshold(LCAST(PN_float32, no_data_threshold));
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_no_data_value
// Access: Published
@ -506,6 +519,7 @@ set_no_data_value(const LPoint4d &no_data_value) {
INLINE void PfmFile::
clear_no_data_value() {
_has_no_data_value = false;
_has_no_data_threshold = false;
_no_data_value = LPoint4f::zero();
_has_point = has_point_noop;
}
@ -521,6 +535,17 @@ has_no_data_value() const {
return _has_no_data_value;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_no_data_threshold
// Access: Published
// Description: Returns whether a "no data" threshold value has been
// established by set_no_data_threshold().
////////////////////////////////////////////////////////////////////
INLINE bool PfmFile::
has_no_data_threshold() const {
return _has_no_data_threshold;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::get_no_data_value
// Access: Published

View File

@ -33,6 +33,7 @@
PfmFile::
PfmFile() {
_has_no_data_value = false;
_has_no_data_threshold = false;
_no_data_value = LPoint4f::zero();
_has_point = has_point_noop;
clear();
@ -49,6 +50,7 @@ PfmFile(const PfmFile &copy) :
_table(copy._table),
_scale(copy._scale),
_has_no_data_value(copy._has_no_data_value),
_has_no_data_threshold(copy._has_no_data_threshold),
_no_data_value(copy._no_data_value),
_has_point(copy._has_point)
{
@ -65,6 +67,7 @@ operator = (const PfmFile &copy) {
_table = copy._table;
_scale = copy._scale;
_has_no_data_value = copy._has_no_data_value;
_has_no_data_threshold = copy._has_no_data_threshold;
_no_data_value = copy._no_data_value;
_has_point = copy._has_point;
}
@ -908,6 +911,7 @@ set_no_data_nan(int num_channels) {
if (num_channels > 0) {
num_channels = min(num_channels, _num_channels);
_has_no_data_value = true;
_has_no_data_threshold = false;
_no_data_value = LPoint4f::zero();
PN_float32 nan = make_nan((PN_float32)0.0);
for (int i = 0; i < num_channels; ++i) {
@ -945,6 +949,7 @@ set_no_data_value(const LPoint4f &no_data_value) {
nassertv(is_valid());
_has_no_data_value = true;
_has_no_data_threshold = false;
_no_data_value = no_data_value;
switch (_num_channels) {
case 1:
@ -964,6 +969,38 @@ set_no_data_value(const LPoint4f &no_data_value) {
}
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_no_data_threshold
// Access: Published
// Description: Sets the special threshold value. Points that are
// below this value in all components are considered "no
// value".
////////////////////////////////////////////////////////////////////
void PfmFile::
set_no_data_threshold(const LPoint4f &no_data_value) {
nassertv(is_valid());
_has_no_data_value = true;
_has_no_data_threshold = true;
_no_data_value = no_data_value;
switch (_num_channels) {
case 1:
_has_point = has_point_threshold_1;
break;
case 2:
_has_point = has_point_threshold_2;
break;
case 3:
_has_point = has_point_threshold_3;
break;
case 4:
_has_point = has_point_threshold_4;
break;
default:
nassertv(false);
}
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::resize
// Access: Published
@ -2395,6 +2432,76 @@ has_point_4(const PfmFile *self, int x, int y) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_point_threshold_1
// Access: Private, Static
// Description: The implementation of has_point_threshold() for 1-component
// files with a no_data_value.
////////////////////////////////////////////////////////////////////
bool PfmFile::
has_point_threshold_1(const PfmFile *self, int x, int y) {
if ((x >= 0 && x < self->_x_size) &&
(y >= 0 && y < self->_y_size)) {
const float *table = &self->_table[(y * self->_x_size + x)];
return table[0] >= self->_no_data_value[0];
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_point_threshold_2
// Access: Private, Static
// Description: The implementation of has_point_threshold() for 2-component
// files with a no_data_value.
////////////////////////////////////////////////////////////////////
bool PfmFile::
has_point_threshold_2(const PfmFile *self, int x, int y) {
if ((x >= 0 && x < self->_x_size) &&
(y >= 0 && y < self->_y_size)) {
const float *table = &self->_table[(y * self->_x_size + x) * 2];
return (table[0] >= self->_no_data_value[0] ||
table[1] >= self->_no_data_value[1]);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_point_threshold_3
// Access: Private, Static
// Description: The implementation of has_point_threshold() for 3-component
// files with a no_data_value.
////////////////////////////////////////////////////////////////////
bool PfmFile::
has_point_threshold_3(const PfmFile *self, int x, int y) {
if ((x >= 0 && x < self->_x_size) &&
(y >= 0 && y < self->_y_size)) {
const float *table = &self->_table[(y * self->_x_size + x) * 3];
return (table[0] >= self->_no_data_value[0] ||
table[1] >= self->_no_data_value[1] ||
table[2] >= self->_no_data_value[2]);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_point_threshold_4
// Access: Private, Static
// Description: The implementation of has_point_threshold() for 4-component
// files with a no_data_value.
////////////////////////////////////////////////////////////////////
bool PfmFile::
has_point_threshold_4(const PfmFile *self, int x, int y) {
if ((x >= 0 && x < self->_x_size) &&
(y >= 0 && y < self->_y_size)) {
const float *table = &self->_table[(y * self->_x_size + x) * 4];
return (table[0] >= self->_no_data_value[0] ||
table[1] >= self->_no_data_value[1] ||
table[2] >= self->_no_data_value[2] ||
table[3] >= self->_no_data_value[3]);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::has_point_chan4
// Access: Private, Static

View File

@ -104,8 +104,11 @@ PUBLISHED:
void set_no_data_nan(int num_channels);
void set_no_data_value(const LPoint4f &no_data_value);
INLINE void set_no_data_value(const LPoint4d &no_data_value);
void set_no_data_threshold(const LPoint4f &no_data_value);
INLINE void set_no_data_threshold(const LPoint4d &no_data_value);
INLINE void clear_no_data_value();
INLINE bool has_no_data_value() const;
INLINE bool has_no_data_threshold() const;
INLINE const LPoint4f &get_no_data_value() const;
BLOCKING void resize(int new_x_size, int new_y_size);
@ -195,6 +198,10 @@ private:
static bool has_point_2(const PfmFile *file, int x, int y);
static bool has_point_3(const PfmFile *file, int x, int y);
static bool has_point_4(const PfmFile *file, int x, int y);
static bool has_point_threshold_1(const PfmFile *file, int x, int y);
static bool has_point_threshold_2(const PfmFile *file, int x, int y);
static bool has_point_threshold_3(const PfmFile *file, int x, int y);
static bool has_point_threshold_4(const PfmFile *file, int x, int y);
static bool has_point_chan4(const PfmFile *file, int x, int y);
static bool has_point_nan_1(const PfmFile *file, int x, int y);
static bool has_point_nan_2(const PfmFile *file, int x, int y);
@ -208,6 +215,7 @@ private:
PN_float32 _scale;
bool _has_no_data_value;
bool _has_no_data_threshold;
LPoint4f _no_data_value;
typedef bool HasPointFunc(const PfmFile *file, int x, int y);