mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
add undist_lut to ProjectionScreen, PfmVizzer
This commit is contained in:
parent
abf29fa3fe
commit
a515048908
@ -26,6 +26,58 @@ get_projector() const {
|
||||
return _projector;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProjectionScreen::clear_undist_lut
|
||||
// Access: Published
|
||||
// Description: Removes the distortion lookup table from the
|
||||
// projector, if specified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ProjectionScreen::
|
||||
clear_undist_lut() {
|
||||
_has_undist_lut = false;
|
||||
_undist_lut = PfmFile();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProjectionScreen::set_undist_lut
|
||||
// Access: Published
|
||||
// Description: Applies a distortion lookup table to the
|
||||
// projector. This mapping warps the lens effect by
|
||||
// passing each ray through an indirection table: the
|
||||
// point (u,v) in the indicated lookup table stores the
|
||||
// actual (u,v) that the lens produces.
|
||||
//
|
||||
// This does not affect the operation of
|
||||
// generate_screen().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ProjectionScreen::
|
||||
set_undist_lut(const PfmFile &undist_lut) {
|
||||
_has_undist_lut = undist_lut.is_valid();
|
||||
_undist_lut = undist_lut;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProjectionScreen::has_undist_lut
|
||||
// Access: Published
|
||||
// Description: Returns true if a valid distortion lookup table was
|
||||
// provided via set_undist_lut(), false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ProjectionScreen::
|
||||
has_undist_lut() const {
|
||||
return _has_undist_lut;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProjectionScreen::get_undist_lut
|
||||
// Access: Published
|
||||
// Description: Returns the distortion lookup table provided via
|
||||
// set_undist_lut(), if any.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const PfmFile &ProjectionScreen::
|
||||
get_undist_lut() const {
|
||||
return _undist_lut;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ProjectionScreen::set_texcoord_name
|
||||
// Access: Published
|
||||
|
@ -39,6 +39,7 @@ ProjectionScreen(const string &name) : PandaNode(name)
|
||||
|
||||
_texcoord_name = InternalName::get_texcoord();
|
||||
|
||||
_has_undist_lut = false;
|
||||
_invert_uvs = project_invert_uvs;
|
||||
_texcoord_3d = false;
|
||||
_vignette_on = false;
|
||||
@ -214,7 +215,7 @@ generate_screen(const NodePath &projector, const string &screen_name,
|
||||
for (int yi = 0; yi < num_y_verts; yi++) {
|
||||
for (int xi = 0; xi < num_x_verts; xi++) {
|
||||
LPoint2 film = LPoint2((PN_stdfloat)xi * x_scale - 1.0f,
|
||||
(PN_stdfloat)yi * y_scale - 1.0f);
|
||||
(PN_stdfloat)yi * y_scale - 1.0f);
|
||||
|
||||
// Reduce the image by the fill ratio.
|
||||
film *= fill_ratio;
|
||||
@ -590,6 +591,22 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
|
||||
// Now the lens gives us coordinates in the range [-1, 1].
|
||||
// Rescale these to [0, 1].
|
||||
LPoint3 uvw = film * to_uv;
|
||||
|
||||
if (good && _has_undist_lut) {
|
||||
int x_size = _undist_lut.get_x_size();
|
||||
int y_size = _undist_lut.get_y_size();
|
||||
|
||||
int dist_xi = (int)cfloor(uvw[0] * (PN_float32)x_size);
|
||||
int dist_yi = (int)cfloor(uvw[1] * (PN_float32)y_size);
|
||||
if (!_undist_lut.has_point(dist_xi, y_size - 1 - dist_yi)) {
|
||||
// Point is missing.
|
||||
uvw.set(0, 0, 0);
|
||||
good = false;
|
||||
} else {
|
||||
uvw = _undist_lut.get_point(dist_xi, y_size - 1 - dist_yi);
|
||||
uvw[1] = 1.0 - uvw[1];
|
||||
}
|
||||
}
|
||||
texcoord.set_data3(uvw);
|
||||
|
||||
// If we have vignette color in effect, color the vertex according
|
||||
@ -722,6 +739,13 @@ make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Geom) ProjectionScreen::
|
||||
make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4 &rel_mat) {
|
||||
static const LMatrix4 lens_to_uv
|
||||
(0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f);
|
||||
static const LMatrix4 uv_to_lens = invert(lens_to_uv);
|
||||
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
PT(Geom) new_geom = geom->make_copy();
|
||||
PT(GeomVertexData) vdata = new_geom->modify_vertex_data();
|
||||
@ -735,7 +759,30 @@ make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4 &rel_mat) {
|
||||
// dimensions so the Z coordinate remains meaningful.
|
||||
LPoint3 vert3d = vert * rel_mat;
|
||||
LPoint3 film(0.0f, 0.0f, 0.0f);
|
||||
lens->project(vert3d, film);
|
||||
bool good = lens->project(vert3d, film);
|
||||
|
||||
if (good && _has_undist_lut) {
|
||||
|
||||
// Now the lens gives us coordinates in the range [-1, 1].
|
||||
// Rescale these to [0, 1].
|
||||
LPoint3 uvw = film * lens_to_uv;
|
||||
|
||||
int x_size = _undist_lut.get_x_size();
|
||||
int y_size = _undist_lut.get_y_size();
|
||||
|
||||
int dist_xi = (int)cfloor(uvw[0] * (PN_float32)x_size);
|
||||
int dist_yi = (int)cfloor(uvw[1] * (PN_float32)y_size);
|
||||
if (!_undist_lut.has_point(dist_xi, y_size - 1 - dist_yi)) {
|
||||
// Point is missing.
|
||||
uvw.set(0, 0, 0);
|
||||
good = false;
|
||||
} else {
|
||||
uvw = _undist_lut.get_point(dist_xi, y_size - 1 - dist_yi);
|
||||
uvw[1] = 1.0 - uvw[1];
|
||||
}
|
||||
|
||||
film = uvw * uv_to_lens;
|
||||
}
|
||||
|
||||
vertex.set_data3(film);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nodePath.h"
|
||||
#include "internalName.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pfmFile.h"
|
||||
|
||||
class Geom;
|
||||
class WorkingNodePath;
|
||||
@ -67,6 +68,11 @@ PUBLISHED:
|
||||
void set_projector(const NodePath &projector);
|
||||
INLINE const NodePath &get_projector() const;
|
||||
|
||||
INLINE void clear_undist_lut();
|
||||
INLINE void set_undist_lut(const PfmFile &undist_lut);
|
||||
INLINE bool has_undist_lut() const;
|
||||
INLINE const PfmFile &get_undist_lut() const;
|
||||
|
||||
PT(GeomNode) generate_screen(const NodePath &projector,
|
||||
const string &screen_name,
|
||||
int num_x_verts, int num_y_verts,
|
||||
@ -124,6 +130,8 @@ private:
|
||||
|
||||
NodePath _projector;
|
||||
PT(LensNode) _projector_node;
|
||||
bool _has_undist_lut;
|
||||
PfmFile _undist_lut;
|
||||
PT(InternalName) _texcoord_name;
|
||||
bool _invert_uvs;
|
||||
bool _texcoord_3d;
|
||||
|
@ -180,3 +180,13 @@ INLINE const PNMImage *PfmVizzer::
|
||||
get_vis_blend() const {
|
||||
return _vis_blend;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmVizzer::VisColumn::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PfmVizzer::VisColumn::
|
||||
VisColumn() {
|
||||
_undist_lut = NULL;
|
||||
}
|
||||
|
@ -230,8 +230,8 @@ clear_vis_columns() {
|
||||
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);
|
||||
const Lens *lens, const PfmFile *undist_lut) {
|
||||
add_vis_column(_vis_columns, source, target, name, transform, lens, undist_lut);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -726,7 +726,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
|
||||
void PfmVizzer::
|
||||
add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
|
||||
InternalName *name, const TransformState *transform,
|
||||
const Lens *lens) {
|
||||
const Lens *lens, const PfmFile *undist_lut) {
|
||||
VisColumn column;
|
||||
column._source = source;
|
||||
column._target = target;
|
||||
@ -736,6 +736,9 @@ add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
|
||||
column._transform = TransformState::make_identity();
|
||||
}
|
||||
column._lens = lens;
|
||||
if (undist_lut != NULL && undist_lut->is_valid()) {
|
||||
column._undist_lut = undist_lut;
|
||||
}
|
||||
vis_columns.push_back(column);
|
||||
}
|
||||
|
||||
@ -986,10 +989,12 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PfmVizzer::VisColumn::
|
||||
transform_point(LPoint2f &point) const {
|
||||
bool success = true;
|
||||
if (!_transform->is_identity()) {
|
||||
LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point);
|
||||
}
|
||||
return true;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1016,6 +1021,22 @@ transform_point(LPoint3f &point) const {
|
||||
point = to_uv.xform_point(LCAST(PN_float32, film));
|
||||
}
|
||||
|
||||
if (_undist_lut != NULL) {
|
||||
int x_size = _undist_lut->get_x_size();
|
||||
int y_size = _undist_lut->get_y_size();
|
||||
|
||||
int dist_xi = (int)cfloor(point[0] * (PN_float32)x_size);
|
||||
int dist_yi = (int)cfloor(point[1] * (PN_float32)y_size);
|
||||
if (!_undist_lut->has_point(dist_xi, y_size - 1 - dist_yi)) {
|
||||
// Point is missing.
|
||||
point.set(0, 0, 0);
|
||||
success = false;
|
||||
} else {
|
||||
point = _undist_lut->get_point(dist_xi, y_size - 1 - dist_yi);
|
||||
point[1] = 1.0 - point[1];
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ PUBLISHED:
|
||||
void clear_vis_columns();
|
||||
void add_vis_column(ColumnType source, ColumnType target,
|
||||
InternalName *name,
|
||||
const TransformState *transform = NULL, const Lens *lens = NULL);
|
||||
const TransformState *transform = NULL, const Lens *lens = NULL,
|
||||
const PfmFile *undist_lut = NULL);
|
||||
|
||||
BLOCKING NodePath generate_vis_points() const;
|
||||
|
||||
@ -88,6 +89,7 @@ private:
|
||||
|
||||
class VisColumn {
|
||||
public:
|
||||
INLINE VisColumn();
|
||||
bool add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const;
|
||||
bool transform_point(LPoint2f &point) const;
|
||||
bool transform_point(LPoint3f &point) const;
|
||||
@ -99,13 +101,15 @@ private:
|
||||
PT(InternalName) _name;
|
||||
CPT(TransformState) _transform;
|
||||
CPT(Lens) _lens;
|
||||
const PfmFile *_undist_lut;
|
||||
};
|
||||
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);
|
||||
const TransformState *transform = NULL,
|
||||
const Lens *lens = NULL, const PfmFile *undist_lut = NULL);
|
||||
void build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const;
|
||||
CPT(GeomVertexFormat) make_array_format(const VisColumns &vis_columns) const;
|
||||
|
||||
|
@ -79,7 +79,7 @@ clear() {
|
||||
_x_size = 0;
|
||||
_y_size = 0;
|
||||
_scale = 1.0;
|
||||
_num_channels = 3;
|
||||
_num_channels = 0;
|
||||
_table.clear();
|
||||
clear_no_data_value();
|
||||
}
|
||||
@ -1044,6 +1044,11 @@ xform(const LMatrix4f &transform) {
|
||||
// file at (x,y), where (x,y) is the point value from
|
||||
// the dist map.
|
||||
//
|
||||
// By convention, the y axis in inverted in the
|
||||
// distortion map relative to the coordinates here. A y
|
||||
// value of 0 in the distortion map corresponds with a v
|
||||
// value of 1 in this file.
|
||||
//
|
||||
// If scale_factor is not 1, it should be a value > 1,
|
||||
// and it specifies the factor to upscale the working
|
||||
// table while processing, to reduce artifacts from
|
||||
@ -1091,16 +1096,11 @@ forward_distort(const PfmFile &dist, PN_float32 scale_factor) {
|
||||
LPoint2f uv = dist_p->get_point2(xi, yi);
|
||||
int dist_xi = (int)cfloor(uv[0] * (PN_float32)working_x_size);
|
||||
int dist_yi = (int)cfloor(uv[1] * (PN_float32)working_y_size);
|
||||
if (dist_xi < 0 || dist_xi >= working_x_size ||
|
||||
dist_yi < 0 || dist_yi >= working_y_size) {
|
||||
if (!source_p->has_point(dist_xi, working_y_size - 1 - dist_yi)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!source_p->has_point(dist_xi, dist_yi)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.set_point(xi, yi, source_p->get_point(dist_xi, dist_yi));
|
||||
result.set_point(xi, working_y_size - 1 - yi, source_p->get_point(dist_xi, working_y_size - 1 - dist_yi));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1122,6 +1122,11 @@ forward_distort(const PfmFile &dist, PN_float32 scale_factor) {
|
||||
// file at (u,v), where (x,y) is the point value from
|
||||
// the dist map.
|
||||
//
|
||||
// By convention, the y axis in inverted in the
|
||||
// distortion map relative to the coordinates here. A y
|
||||
// value of 0 in the distortion map corresponds with a v
|
||||
// value of 1 in this file.
|
||||
//
|
||||
// If scale_factor is not 1, it should be a value > 1,
|
||||
// and it specifies the factor to upscale the working
|
||||
// table while processing, to reduce artifacts from
|
||||
@ -1163,7 +1168,7 @@ reverse_distort(const PfmFile &dist, PN_float32 scale_factor) {
|
||||
|
||||
for (int yi = 0; yi < working_y_size; ++yi) {
|
||||
for (int xi = 0; xi < working_x_size; ++xi) {
|
||||
if (!source_p->has_point(xi, yi)) {
|
||||
if (!source_p->has_point(xi, working_y_size - 1 - yi)) {
|
||||
continue;
|
||||
}
|
||||
if (!dist_p->has_point(xi, yi)) {
|
||||
@ -1177,11 +1182,13 @@ reverse_distort(const PfmFile &dist, PN_float32 scale_factor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!source_p->has_point(dist_xi, dist_yi)) {
|
||||
/*
|
||||
if (!source_p->has_point(dist_xi, working_y_size - 1 - dist_yi)) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
result.set_point(dist_xi, dist_yi, source_p->get_point(xi, yi));
|
||||
result.set_point(dist_xi, working_y_size - 1 - dist_yi, source_p->get_point(xi, working_y_size - 1 - yi));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user