mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
extend compute_planar_bounds()
This commit is contained in:
parent
91cb23abb0
commit
61fa1e4c26
@ -318,7 +318,7 @@ write(ostream &out) {
|
||||
// value cannot be determined.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PfmFile::
|
||||
calc_average_point(LPoint3 &result, double x, double y, double radius) const {
|
||||
calc_average_point(LPoint3 &result, PN_stdfloat x, PN_stdfloat y, PN_stdfloat radius) const {
|
||||
result = LPoint3::zero();
|
||||
|
||||
int min_x = int(ceil(x - radius));
|
||||
@ -456,27 +456,27 @@ resize(int new_x_size, int new_y_size) {
|
||||
Table new_data;
|
||||
new_data.reserve(new_x_size * new_y_size);
|
||||
|
||||
double from_x0, from_x1, from_y0, from_y1;
|
||||
PN_stdfloat from_x0, from_x1, from_y0, from_y1;
|
||||
|
||||
double x_scale = 1.0;
|
||||
double y_scale = 1.0;
|
||||
PN_stdfloat x_scale = 1.0;
|
||||
PN_stdfloat y_scale = 1.0;
|
||||
|
||||
if (new_x_size > 1) {
|
||||
x_scale = (double)(_x_size - 1) / (double)(new_x_size - 1);
|
||||
x_scale = (PN_stdfloat)(_x_size - 1) / (PN_stdfloat)(new_x_size - 1);
|
||||
}
|
||||
if (new_y_size > 1) {
|
||||
y_scale = (double)(_y_size - 1) / (double)(new_y_size - 1);
|
||||
y_scale = (PN_stdfloat)(_y_size - 1) / (PN_stdfloat)(new_y_size - 1);
|
||||
}
|
||||
|
||||
from_y0 = 0.0;
|
||||
for (int to_y = 0; to_y < new_y_size; ++to_y) {
|
||||
from_y1 = (to_y + 0.5) * y_scale;
|
||||
from_y1 = min(from_y1, (double) _y_size);
|
||||
from_y1 = min(from_y1, (PN_stdfloat) _y_size);
|
||||
|
||||
from_x0 = 0.0;
|
||||
for (int to_x = 0; to_x < new_x_size; ++to_x) {
|
||||
from_x1 = (to_x + 0.5) * x_scale;
|
||||
from_x1 = min(from_x1, (double) _x_size);
|
||||
from_x1 = min(from_x1, (PN_stdfloat) _x_size);
|
||||
|
||||
// Now the box from (from_x0, from_y0) - (from_x1, from_y1)
|
||||
// but not including (from_x1, from_y1) maps to the pixel (to_x, to_y).
|
||||
@ -594,6 +594,18 @@ merge(const PfmFile &other) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::compute_planar_bounds
|
||||
// Access: Published
|
||||
// Description: This version of this method exists for temporary
|
||||
// backward compatibility only.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(BoundingHexahedron) PfmFile::
|
||||
compute_planar_bounds(PN_stdfloat point_dist, PN_stdfloat sample_radius) const {
|
||||
return compute_planar_bounds(LPoint2::zero(), point_dist, sample_radius, false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::compute_planar_bounds
|
||||
// Access: Published
|
||||
@ -606,18 +618,20 @@ merge(const PfmFile &other) {
|
||||
// around the center (cx - pd, cx + pd) and so on, to
|
||||
// approximate the plane of the surface. Then all of
|
||||
// the points are projected into that plane and the
|
||||
// bounding volume within that plane is determined.
|
||||
// bounding volume of the entire mesh within that plane
|
||||
// is determined. If points_only is true, the bounding
|
||||
// volume of only those four points is determined.
|
||||
//
|
||||
// point_dist and sample_radius are in UV space, i.e. in
|
||||
// the range 0..1.
|
||||
// center, point_dist and sample_radius are in UV space,
|
||||
// i.e. in the range 0..1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(BoundingHexahedron) PfmFile::
|
||||
compute_planar_bounds(double point_dist, double sample_radius) const {
|
||||
compute_planar_bounds(const LPoint2 ¢er, PN_stdfloat point_dist, PN_stdfloat sample_radius, bool points_only) const {
|
||||
LPoint3 p0, p1, p2, p3;
|
||||
compute_sample_point(p0, 0.5 + point_dist, 0.5 - point_dist, sample_radius);
|
||||
compute_sample_point(p1, 0.5 + point_dist, 0.5 + point_dist, sample_radius);
|
||||
compute_sample_point(p2, 0.5 - point_dist, 0.5 + point_dist, sample_radius);
|
||||
compute_sample_point(p3, 0.5 - point_dist, 0.5 - point_dist, sample_radius);
|
||||
compute_sample_point(p0, center[0] + point_dist, center[1] - point_dist, sample_radius);
|
||||
compute_sample_point(p1, center[0] + point_dist, center[1] + point_dist, sample_radius);
|
||||
compute_sample_point(p2, center[0] - point_dist, center[1] + point_dist, sample_radius);
|
||||
compute_sample_point(p3, center[0] - point_dist, center[1] - point_dist, sample_radius);
|
||||
|
||||
LPoint3 normal;
|
||||
|
||||
@ -639,21 +653,52 @@ compute_planar_bounds(double point_dist, double sample_radius) const {
|
||||
|
||||
normal.normalize();
|
||||
|
||||
LVector3 up = (p1 - p0) + (p2 - p3);
|
||||
LPoint3 pcenter = ((p0 + p1 + p2 + p3) * 0.25);
|
||||
|
||||
// Compute the transform necessary to rotate all of the points into
|
||||
// the Y = 0 plane.
|
||||
LMatrix4 rotate;
|
||||
look_at(rotate, normal, p1 - p0);
|
||||
look_at(rotate, normal, up);
|
||||
|
||||
LMatrix4 rinv;
|
||||
rinv.invert_from(rotate);
|
||||
|
||||
LPoint3 trans = p0 * rinv;
|
||||
LPoint3 trans = pcenter * rinv;
|
||||
rinv.set_row(3, -trans);
|
||||
rotate.invert_from(rinv);
|
||||
|
||||
// Now determine the minmax.
|
||||
PN_stdfloat min_x, min_y, min_z, max_x, max_y, max_z;
|
||||
bool got_point = false;
|
||||
if (points_only) {
|
||||
LPoint3 points[4] = {
|
||||
p0 * rinv,
|
||||
p1 * rinv,
|
||||
p2 * rinv,
|
||||
p3 * rinv,
|
||||
};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const LPoint3 &point = points[i];
|
||||
if (!got_point) {
|
||||
min_x = point[0];
|
||||
min_y = point[1];
|
||||
min_z = point[2];
|
||||
max_x = point[0];
|
||||
max_y = point[1];
|
||||
max_z = point[2];
|
||||
got_point = true;
|
||||
} else {
|
||||
min_x = min(min_x, point[0]);
|
||||
min_y = min(min_y, point[1]);
|
||||
min_z = min(min_z, point[2]);
|
||||
max_x = max(max_x, point[0]);
|
||||
max_y = max(max_y, point[1]);
|
||||
max_z = max(max_z, point[2]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Table::const_iterator ti;
|
||||
for (ti = _table.begin(); ti != _table.end(); ++ti) {
|
||||
if (_zero_special && (*ti) == LPoint3::zero()) {
|
||||
@ -677,22 +722,42 @@ compute_planar_bounds(double point_dist, double sample_radius) const {
|
||||
max_z = max(max_z, point[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PT(BoundingHexahedron) bounds = new BoundingHexahedron
|
||||
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
|
||||
LPoint3(min_x, min_y, max_z), LPoint3(max_x, min_y, max_z),
|
||||
LPoint3(min_x, max_y, min_z), LPoint3(max_x, max_y, min_z),
|
||||
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_z));
|
||||
bounds->write(cerr);
|
||||
|
||||
// Rotate the bounding volume back into the original space of the
|
||||
// screen.
|
||||
bounds->xform(rotate);
|
||||
bounds->write(cerr);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::compute_sample_point
|
||||
// Access: Published
|
||||
// Description: Computes the average of all the point within
|
||||
// sample_radius (manhattan distance) and the indicated
|
||||
// point.
|
||||
//
|
||||
// The point coordinates are given in UV space, in the
|
||||
// range 0..1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PfmFile::
|
||||
compute_sample_point(LPoint3 &result,
|
||||
PN_stdfloat x, PN_stdfloat y, PN_stdfloat sample_radius) const {
|
||||
x *= _x_size;
|
||||
y *= _y_size;
|
||||
PN_stdfloat xr = sample_radius * _x_size;
|
||||
PN_stdfloat yr = sample_radius * _y_size;
|
||||
box_filter_region(result, x - xr, y - yr, x + xr, y + yr);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::generate_vis_points
|
||||
// Access: Published
|
||||
@ -1016,27 +1081,6 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::compute_sample_point
|
||||
// Access: Private
|
||||
// Description: Computes the average of all the point within
|
||||
// sample_radius (manhattan distance) and the indicated
|
||||
// point.
|
||||
//
|
||||
// Unlike box_filter_*(), these point values are given
|
||||
// in UV space, in the range 0..1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PfmFile::
|
||||
compute_sample_point(LPoint3 &result,
|
||||
double x, double y, double sample_radius) const {
|
||||
x *= _x_size;
|
||||
y *= _y_size;
|
||||
double xr = sample_radius * _x_size;
|
||||
double yr = sample_radius * _y_size;
|
||||
box_filter_region(result, x - xr, y - yr, x + xr, y + yr);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PfmFile::box_filter_region
|
||||
// Access: Private
|
||||
@ -1048,9 +1092,9 @@ compute_sample_point(LPoint3 &result,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PfmFile::
|
||||
box_filter_region(LPoint3 &result,
|
||||
double x0, double y0, double x1, double y1) const {
|
||||
PN_stdfloat x0, PN_stdfloat y0, PN_stdfloat x1, PN_stdfloat y1) const {
|
||||
result = LPoint3::zero();
|
||||
double coverage = 0.0;
|
||||
PN_stdfloat coverage = 0.0;
|
||||
|
||||
if (x1 < x0 || y1 < y0) {
|
||||
return;
|
||||
@ -1059,7 +1103,7 @@ box_filter_region(LPoint3 &result,
|
||||
|
||||
int y = (int)y0;
|
||||
// Get the first (partial) row
|
||||
box_filter_line(result, coverage, x0, y, x1, (double)(y+1)-y0);
|
||||
box_filter_line(result, coverage, x0, y, x1, (PN_stdfloat)(y+1)-y0);
|
||||
|
||||
int y_last = (int)y1;
|
||||
if (y < y_last) {
|
||||
@ -1071,7 +1115,7 @@ box_filter_region(LPoint3 &result,
|
||||
}
|
||||
|
||||
// Get the final (partial) row
|
||||
double y_contrib = y1 - (double)y_last;
|
||||
PN_stdfloat y_contrib = y1 - (PN_stdfloat)y_last;
|
||||
if (y_contrib > 0.0001) {
|
||||
box_filter_line(result, coverage, x0, y, x1, y_contrib);
|
||||
}
|
||||
@ -1088,11 +1132,11 @@ box_filter_region(LPoint3 &result,
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PfmFile::
|
||||
box_filter_line(LPoint3 &result, double &coverage,
|
||||
double x0, int y, double x1, double y_contrib) const {
|
||||
box_filter_line(LPoint3 &result, PN_stdfloat &coverage,
|
||||
PN_stdfloat x0, int y, PN_stdfloat x1, PN_stdfloat y_contrib) const {
|
||||
int x = (int)x0;
|
||||
// Get the first (partial) xel
|
||||
box_filter_point(result, coverage, x, y, (double)(x+1)-x0, y_contrib);
|
||||
box_filter_point(result, coverage, x, y, (PN_stdfloat)(x+1)-x0, y_contrib);
|
||||
|
||||
int x_last = (int)x1;
|
||||
if (x < x_last) {
|
||||
@ -1104,7 +1148,7 @@ box_filter_line(LPoint3 &result, double &coverage,
|
||||
}
|
||||
|
||||
// Get the final (partial) xel
|
||||
double x_contrib = x1 - (double)x_last;
|
||||
PN_stdfloat x_contrib = x1 - (PN_stdfloat)x_last;
|
||||
if (x_contrib > 0.0001) {
|
||||
box_filter_point(result, coverage, x, y, x_contrib, y_contrib);
|
||||
}
|
||||
@ -1117,14 +1161,14 @@ box_filter_line(LPoint3 &result, double &coverage,
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PfmFile::
|
||||
box_filter_point(LPoint3 &result, double &coverage,
|
||||
int x, int y, double x_contrib, double y_contrib) const {
|
||||
box_filter_point(LPoint3 &result, PN_stdfloat &coverage,
|
||||
int x, int y, PN_stdfloat x_contrib, PN_stdfloat y_contrib) const {
|
||||
const LPoint3 &point = get_point(x, y);
|
||||
if (_zero_special && point == LPoint3::zero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
double contrib = x_contrib * y_contrib;
|
||||
PN_stdfloat contrib = x_contrib * y_contrib;
|
||||
result += point * contrib;
|
||||
coverage += contrib;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ PUBLISHED:
|
||||
INLINE void set_point(int x, int y, const LVecBase3 &point);
|
||||
INLINE LPoint3 &modify_point(int x, int y);
|
||||
|
||||
BLOCKING bool calc_average_point(LPoint3 &result, double x, double y, double radius) const;
|
||||
BLOCKING bool calc_average_point(LPoint3 &result, PN_stdfloat x, PN_stdfloat y, PN_stdfloat radius) const;
|
||||
BLOCKING bool calc_min_max(LVecBase3 &min_points, LVecBase3 &max_points) const;
|
||||
|
||||
INLINE void set_zero_special(bool zero_special);
|
||||
@ -67,7 +67,10 @@ PUBLISHED:
|
||||
BLOCKING void project(const Lens *lens);
|
||||
BLOCKING void merge(const PfmFile &other);
|
||||
|
||||
BLOCKING PT(BoundingHexahedron) compute_planar_bounds(double point_dist, double sample_radius) const;
|
||||
BLOCKING PT(BoundingHexahedron) compute_planar_bounds(PN_stdfloat point_dist, PN_stdfloat sample_radius) const;
|
||||
BLOCKING PT(BoundingHexahedron) compute_planar_bounds(const LPoint2 ¢er, PN_stdfloat point_dist, PN_stdfloat sample_radius, bool points_only) const;
|
||||
void compute_sample_point(LPoint3 &result,
|
||||
PN_stdfloat x, PN_stdfloat y, PN_stdfloat sample_radius) const;
|
||||
|
||||
INLINE void set_vis_inverse(bool vis_inverse);
|
||||
INLINE bool get_vis_inverse() const;
|
||||
@ -89,14 +92,12 @@ PUBLISHED:
|
||||
private:
|
||||
void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const;
|
||||
|
||||
void compute_sample_point(LPoint3 &result,
|
||||
double x, double y, double sample_radius) const;
|
||||
void box_filter_region(LPoint3 &result,
|
||||
double x0, double y0, double x1, double y1) const;
|
||||
void box_filter_line(LPoint3 &result, double &coverage,
|
||||
double x0, int y, double x1, double y_contrib) const;
|
||||
void box_filter_point(LPoint3 &result, double &coverage,
|
||||
int x, int y, double x_contrib, double y_contrib) const;
|
||||
PN_stdfloat x0, PN_stdfloat y0, PN_stdfloat x1, PN_stdfloat y1) const;
|
||||
void box_filter_line(LPoint3 &result, PN_stdfloat &coverage,
|
||||
PN_stdfloat x0, int y, PN_stdfloat x1, PN_stdfloat y_contrib) const;
|
||||
void box_filter_point(LPoint3 &result, PN_stdfloat &coverage,
|
||||
int x, int y, PN_stdfloat x_contrib, PN_stdfloat y_contrib) const;
|
||||
|
||||
class MiniGridCell {
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user