mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -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.
|
// value cannot be determined.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool PfmFile::
|
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();
|
result = LPoint3::zero();
|
||||||
|
|
||||||
int min_x = int(ceil(x - radius));
|
int min_x = int(ceil(x - radius));
|
||||||
@ -456,27 +456,27 @@ resize(int new_x_size, int new_y_size) {
|
|||||||
Table new_data;
|
Table new_data;
|
||||||
new_data.reserve(new_x_size * new_y_size);
|
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;
|
PN_stdfloat x_scale = 1.0;
|
||||||
double y_scale = 1.0;
|
PN_stdfloat y_scale = 1.0;
|
||||||
|
|
||||||
if (new_x_size > 1) {
|
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) {
|
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;
|
from_y0 = 0.0;
|
||||||
for (int to_y = 0; to_y < new_y_size; ++to_y) {
|
for (int to_y = 0; to_y < new_y_size; ++to_y) {
|
||||||
from_y1 = (to_y + 0.5) * y_scale;
|
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;
|
from_x0 = 0.0;
|
||||||
for (int to_x = 0; to_x < new_x_size; ++to_x) {
|
for (int to_x = 0; to_x < new_x_size; ++to_x) {
|
||||||
from_x1 = (to_x + 0.5) * x_scale;
|
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)
|
// 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).
|
// 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
|
// Function: PfmFile::compute_planar_bounds
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -606,18 +618,20 @@ merge(const PfmFile &other) {
|
|||||||
// around the center (cx - pd, cx + pd) and so on, to
|
// around the center (cx - pd, cx + pd) and so on, to
|
||||||
// approximate the plane of the surface. Then all of
|
// approximate the plane of the surface. Then all of
|
||||||
// the points are projected into that plane and the
|
// 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
|
// center, point_dist and sample_radius are in UV space,
|
||||||
// the range 0..1.
|
// i.e. in the range 0..1.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PT(BoundingHexahedron) PfmFile::
|
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;
|
LPoint3 p0, p1, p2, p3;
|
||||||
compute_sample_point(p0, 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, 0.5 + point_dist, 0.5 + point_dist, sample_radius);
|
compute_sample_point(p1, center[0] + point_dist, center[1] + point_dist, sample_radius);
|
||||||
compute_sample_point(p2, 0.5 - point_dist, 0.5 + point_dist, sample_radius);
|
compute_sample_point(p2, center[0] - point_dist, center[1] + point_dist, sample_radius);
|
||||||
compute_sample_point(p3, 0.5 - point_dist, 0.5 - point_dist, sample_radius);
|
compute_sample_point(p3, center[0] - point_dist, center[1] - point_dist, sample_radius);
|
||||||
|
|
||||||
LPoint3 normal;
|
LPoint3 normal;
|
||||||
|
|
||||||
@ -639,21 +653,52 @@ compute_planar_bounds(double point_dist, double sample_radius) const {
|
|||||||
|
|
||||||
normal.normalize();
|
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
|
// Compute the transform necessary to rotate all of the points into
|
||||||
// the Y = 0 plane.
|
// the Y = 0 plane.
|
||||||
LMatrix4 rotate;
|
LMatrix4 rotate;
|
||||||
look_at(rotate, normal, p1 - p0);
|
look_at(rotate, normal, up);
|
||||||
|
|
||||||
LMatrix4 rinv;
|
LMatrix4 rinv;
|
||||||
rinv.invert_from(rotate);
|
rinv.invert_from(rotate);
|
||||||
|
|
||||||
LPoint3 trans = p0 * rinv;
|
LPoint3 trans = pcenter * rinv;
|
||||||
rinv.set_row(3, -trans);
|
rinv.set_row(3, -trans);
|
||||||
rotate.invert_from(rinv);
|
rotate.invert_from(rinv);
|
||||||
|
|
||||||
// Now determine the minmax.
|
// Now determine the minmax.
|
||||||
PN_stdfloat min_x, min_y, min_z, max_x, max_y, max_z;
|
PN_stdfloat min_x, min_y, min_z, max_x, max_y, max_z;
|
||||||
bool got_point = false;
|
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;
|
Table::const_iterator ti;
|
||||||
for (ti = _table.begin(); ti != _table.end(); ++ti) {
|
for (ti = _table.begin(); ti != _table.end(); ++ti) {
|
||||||
if (_zero_special && (*ti) == LPoint3::zero()) {
|
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]);
|
max_z = max(max_z, point[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PT(BoundingHexahedron) bounds = new BoundingHexahedron
|
PT(BoundingHexahedron) bounds = new BoundingHexahedron
|
||||||
(LPoint3(min_x, min_y, min_z), LPoint3(max_x, min_y, min_z),
|
(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, 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, min_z), LPoint3(max_x, max_y, min_z),
|
||||||
LPoint3(min_x, max_y, max_z), LPoint3(max_x, max_y, max_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
|
// Rotate the bounding volume back into the original space of the
|
||||||
// screen.
|
// screen.
|
||||||
bounds->xform(rotate);
|
bounds->xform(rotate);
|
||||||
bounds->write(cerr);
|
|
||||||
|
|
||||||
return bounds;
|
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
|
// Function: PfmFile::generate_vis_points
|
||||||
// Access: Published
|
// 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
|
// Function: PfmFile::box_filter_region
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1048,9 +1092,9 @@ compute_sample_point(LPoint3 &result,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PfmFile::
|
void PfmFile::
|
||||||
box_filter_region(LPoint3 &result,
|
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();
|
result = LPoint3::zero();
|
||||||
double coverage = 0.0;
|
PN_stdfloat coverage = 0.0;
|
||||||
|
|
||||||
if (x1 < x0 || y1 < y0) {
|
if (x1 < x0 || y1 < y0) {
|
||||||
return;
|
return;
|
||||||
@ -1059,7 +1103,7 @@ box_filter_region(LPoint3 &result,
|
|||||||
|
|
||||||
int y = (int)y0;
|
int y = (int)y0;
|
||||||
// Get the first (partial) row
|
// 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;
|
int y_last = (int)y1;
|
||||||
if (y < y_last) {
|
if (y < y_last) {
|
||||||
@ -1071,7 +1115,7 @@ box_filter_region(LPoint3 &result,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the final (partial) row
|
// 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) {
|
if (y_contrib > 0.0001) {
|
||||||
box_filter_line(result, coverage, x0, y, x1, y_contrib);
|
box_filter_line(result, coverage, x0, y, x1, y_contrib);
|
||||||
}
|
}
|
||||||
@ -1088,11 +1132,11 @@ box_filter_region(LPoint3 &result,
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PfmFile::
|
void PfmFile::
|
||||||
box_filter_line(LPoint3 &result, double &coverage,
|
box_filter_line(LPoint3 &result, PN_stdfloat &coverage,
|
||||||
double x0, int y, double x1, double y_contrib) const {
|
PN_stdfloat x0, int y, PN_stdfloat x1, PN_stdfloat y_contrib) const {
|
||||||
int x = (int)x0;
|
int x = (int)x0;
|
||||||
// Get the first (partial) xel
|
// 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;
|
int x_last = (int)x1;
|
||||||
if (x < x_last) {
|
if (x < x_last) {
|
||||||
@ -1104,7 +1148,7 @@ box_filter_line(LPoint3 &result, double &coverage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the final (partial) xel
|
// 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) {
|
if (x_contrib > 0.0001) {
|
||||||
box_filter_point(result, coverage, x, y, x_contrib, y_contrib);
|
box_filter_point(result, coverage, x, y, x_contrib, y_contrib);
|
||||||
}
|
}
|
||||||
@ -1117,14 +1161,14 @@ box_filter_line(LPoint3 &result, double &coverage,
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PfmFile::
|
void PfmFile::
|
||||||
box_filter_point(LPoint3 &result, double &coverage,
|
box_filter_point(LPoint3 &result, PN_stdfloat &coverage,
|
||||||
int x, int y, double x_contrib, double y_contrib) const {
|
int x, int y, PN_stdfloat x_contrib, PN_stdfloat y_contrib) const {
|
||||||
const LPoint3 &point = get_point(x, y);
|
const LPoint3 &point = get_point(x, y);
|
||||||
if (_zero_special && point == LPoint3::zero()) {
|
if (_zero_special && point == LPoint3::zero()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double contrib = x_contrib * y_contrib;
|
PN_stdfloat contrib = x_contrib * y_contrib;
|
||||||
result += point * contrib;
|
result += point * contrib;
|
||||||
coverage += contrib;
|
coverage += contrib;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ PUBLISHED:
|
|||||||
INLINE void set_point(int x, int y, const LVecBase3 &point);
|
INLINE void set_point(int x, int y, const LVecBase3 &point);
|
||||||
INLINE LPoint3 &modify_point(int x, int y);
|
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;
|
BLOCKING bool calc_min_max(LVecBase3 &min_points, LVecBase3 &max_points) const;
|
||||||
|
|
||||||
INLINE void set_zero_special(bool zero_special);
|
INLINE void set_zero_special(bool zero_special);
|
||||||
@ -67,7 +67,10 @@ PUBLISHED:
|
|||||||
BLOCKING void project(const Lens *lens);
|
BLOCKING void project(const Lens *lens);
|
||||||
BLOCKING void merge(const PfmFile &other);
|
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 void set_vis_inverse(bool vis_inverse);
|
||||||
INLINE bool get_vis_inverse() const;
|
INLINE bool get_vis_inverse() const;
|
||||||
@ -89,14 +92,12 @@ PUBLISHED:
|
|||||||
private:
|
private:
|
||||||
void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const;
|
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,
|
void 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;
|
||||||
void box_filter_line(LPoint3 &result, double &coverage,
|
void box_filter_line(LPoint3 &result, PN_stdfloat &coverage,
|
||||||
double x0, int y, double x1, double y_contrib) const;
|
PN_stdfloat x0, int y, PN_stdfloat x1, PN_stdfloat y_contrib) const;
|
||||||
void box_filter_point(LPoint3 &result, double &coverage,
|
void box_filter_point(LPoint3 &result, PN_stdfloat &coverage,
|
||||||
int x, int y, double x_contrib, double y_contrib) const;
|
int x, int y, PN_stdfloat x_contrib, PN_stdfloat y_contrib) const;
|
||||||
|
|
||||||
class MiniGridCell {
|
class MiniGridCell {
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user