wip: PfmFile::calc_bilinear_point()

This commit is contained in:
David Rose 2013-04-11 17:24:32 +00:00
parent a515048908
commit a99e543f05
5 changed files with 125 additions and 37 deletions

View File

@ -593,17 +593,13 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
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)) {
LPoint3 p;
if (!_undist_lut.calc_bilinear_point(p, uvw[0], 1.0 - uvw[1])) {
// Point is missing.
uvw.set(0, 0, 0);
good = false;
} else {
uvw = _undist_lut.get_point(dist_xi, y_size - 1 - dist_yi);
uvw = p;
uvw[1] = 1.0 - uvw[1];
}
}
@ -767,17 +763,13 @@ make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4 &rel_mat) {
// 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)) {
LPoint3 p;
if (!_undist_lut.calc_bilinear_point(p, uvw[0], 1.0 - uvw[1])) {
// Point is missing.
uvw.set(0, 0, 0);
good = false;
} else {
uvw = _undist_lut.get_point(dist_xi, y_size - 1 - dist_yi);
uvw = p;
uvw[1] = 1.0 - uvw[1];
}

View File

@ -1022,17 +1022,13 @@ transform_point(LPoint3f &point) const {
}
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)) {
LPoint3 p;
if (!_undist_lut->calc_bilinear_point(p, point[0], 1.0 - point[1])) {
// Point is missing.
point.set(0, 0, 0);
success = false;
} else {
point = _undist_lut->get_point(dist_xi, y_size - 1 - dist_yi);
point = p;
point[1] = 1.0 - point[1];
}
}

View File

@ -196,9 +196,7 @@ modify_point2(int x, int y) {
////////////////////////////////////////////////////////////////////
INLINE const LPoint3f &PfmFile::
get_point(int x, int y) const {
nassertr(x >= 0 && x < _x_size &&
y >= 0 && y < _y_size, LPoint3f::zero());
return *(LPoint3f *)&_table[(y * _x_size + x) * _num_channels];
return get_point3(x, y);
}
////////////////////////////////////////////////////////////////////
@ -210,6 +208,55 @@ get_point(int x, int y) const {
////////////////////////////////////////////////////////////////////
INLINE void PfmFile::
set_point(int x, int y, const LVecBase3f &point) {
set_point3(x, y, point);
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_point
// Access: Published
// Description: Replaces the 3-component point value at the indicated
// point. In a 1-channel image, the channel value is in
// the x component.
////////////////////////////////////////////////////////////////////
INLINE void PfmFile::
set_point(int x, int y, const LVecBase3d &point) {
set_point3(x, y, point);
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::modify_point
// Access: Published
// Description: Returns a modifiable 3-component point value at the
// indicated point.
////////////////////////////////////////////////////////////////////
INLINE LPoint3f &PfmFile::
modify_point(int x, int y) {
return modify_point3(x, y);
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::get_point3
// Access: Published
// Description: Returns the 3-component point value at the indicated
// point. In a 1-channel image, the channel value is in
// the x component.
////////////////////////////////////////////////////////////////////
INLINE const LPoint3f &PfmFile::
get_point3(int x, int y) const {
nassertr(x >= 0 && x < _x_size &&
y >= 0 && y < _y_size, LPoint3f::zero());
return *(LPoint3f *)&_table[(y * _x_size + x) * _num_channels];
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_point3
// Access: Published
// Description: Replaces the 3-component point value at the indicated
// point. In a 1-channel image, the channel value is in
// the x component.
////////////////////////////////////////////////////////////////////
INLINE void PfmFile::
set_point3(int x, int y, const LVecBase3f &point) {
nassertv(!point.is_nan());
nassertv(x >= 0 && x < _x_size &&
y >= 0 && y < _y_size);
@ -233,25 +280,25 @@ set_point(int x, int y, const LVecBase3f &point) {
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::set_point
// Function: PfmFile::set_point3
// Access: Published
// Description: Replaces the 3-component point value at the indicated
// point. In a 1-channel image, the channel value is in
// the x component.
////////////////////////////////////////////////////////////////////
INLINE void PfmFile::
set_point(int x, int y, const LVecBase3d &point) {
set_point(x, y, LCAST(PN_float32, point));
set_point3(int x, int y, const LVecBase3d &point) {
set_point3(x, y, LCAST(PN_float32, point));
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::modify_point
// Function: PfmFile::modify_point3
// Access: Published
// Description: Returns a modifiable 3-component point value at the
// indicated point.
////////////////////////////////////////////////////////////////////
INLINE LPoint3f &PfmFile::
modify_point(int x, int y) {
modify_point3(int x, int y) {
#ifndef NDEBUG
static LPoint3f dummy_value = LPoint3f::zero();
nassertr(x >= 0 && x < _x_size &&

View File

@ -610,6 +610,56 @@ calc_average_point(LPoint3f &result, PN_float32 x, PN_float32 y, PN_float32 radi
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::calc_bilinear_point
// Access: Published
// Description: Computes the weighted average of the four nearest
// points to the floating-point index (x, y). Returns
// true if the point has any contributors, false if the
// point is unknown.
////////////////////////////////////////////////////////////////////
bool PfmFile::
calc_bilinear_point(LPoint3f &result, PN_float32 x, PN_float32 y) const {
result = LPoint3f::zero();
x *= _x_size;
y *= _y_size;
int min_x = int(floor(x));
int min_y = int(floor(y));
PN_float32 frac_x = x - min_x;
PN_float32 frac_y = y - min_y;
LPoint3f p00, p01, p10, p11;
PN_float32 w00 = 0.0, w01 = 0.0, w10 = 0.0, w11 = 0.0;
if (has_point(min_x, min_y)) {
w00 = (1.0 - frac_y) * (1.0 - frac_x);
p00 = get_point(min_x, min_y);
}
if (has_point(min_x + 1, min_y)) {
w10 = (1.0 - frac_y) * frac_x;
p10 = get_point(min_x + 1, min_y);
}
if (has_point(min_x, min_y + 1)) {
w01 = frac_y * (1.0 - frac_x);
p01 = get_point(min_x, min_y + 1);
}
if (has_point(min_x + 1, min_y + 1)) {
w11 = frac_y * frac_x;
p11 = get_point(min_x + 1, min_y + 1);
}
PN_float32 net_w = w00 + w01 + w10 + w11;
if (net_w == 0.0) {
return false;
}
result = (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11) / net_w;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: PfmFile::calc_min_max
// Access: Published
@ -1093,14 +1143,12 @@ forward_distort(const PfmFile &dist, PN_float32 scale_factor) {
if (!dist_p->has_point(xi, yi)) {
continue;
}
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 (!source_p->has_point(dist_xi, working_y_size - 1 - dist_yi)) {
LPoint2 uv = dist_p->get_point2(xi, yi);
LPoint3 p;
if (!calc_bilinear_point(p, uv[0], 1.0 - uv[1])) {
continue;
}
result.set_point(xi, working_y_size - 1 - yi, source_p->get_point(dist_xi, working_y_size - 1 - dist_yi));
result.set_point(xi, working_y_size - 1 - yi, p);
}
}
@ -1302,8 +1350,8 @@ clear_to_texcoords(int x_size, int y_size) {
for (int yi = 0; yi < _y_size; ++yi) {
for (int xi = 0; xi < _x_size; ++xi) {
LPoint3f uv(PN_float32(xi) * uv_scale[0] + 0.5,
PN_float32(yi) * uv_scale[1] + 0.5,
LPoint3f uv((PN_float32(xi) + 0.5) * uv_scale[0],
(PN_float32(yi) + 0.5) * uv_scale[1],
0.0f);
set_point(xi, yi, uv);
}

View File

@ -69,6 +69,10 @@ PUBLISHED:
INLINE void set_point(int x, int y, const LVecBase3f &point);
INLINE void set_point(int x, int y, const LVecBase3d &point);
INLINE LPoint3f &modify_point(int x, int y);
INLINE const LPoint3f &get_point3(int x, int y) const;
INLINE void set_point3(int x, int y, const LVecBase3f &point);
INLINE void set_point3(int x, int y, const LVecBase3d &point);
INLINE LPoint3f &modify_point3(int x, int y);
INLINE const LPoint4f &get_point4(int x, int y) const;
INLINE void set_point4(int x, int y, const LVecBase4f &point);
INLINE void set_point4(int x, int y, const LVecBase4d &point);
@ -80,6 +84,7 @@ PUBLISHED:
void fill(const LPoint4f &value);
BLOCKING bool calc_average_point(LPoint3f &result, PN_float32 x, PN_float32 y, PN_float32 radius) const;
BLOCKING bool calc_bilinear_point(LPoint3f &result, PN_float32 x, PN_float32 y) const;
BLOCKING bool calc_min_max(LVecBase3f &min_points, LVecBase3f &max_points) const;
BLOCKING bool calc_autocrop(int &x_begin, int &x_end, int &y_begin, int &y_end) const;
BLOCKING INLINE bool calc_autocrop(LVecBase4f &range) const;