*** empty log message ***
This commit is contained in:
parent
fe6ae687a2
commit
f020b438fc
|
|
@ -91,26 +91,22 @@ set_hull_color(float r, float g, float b) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool NurbsCurveDrawer::
|
||||
draw() {
|
||||
// First, draw the curve itself.
|
||||
if (!ParametricCurveDrawer::draw()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ParametricCurve *curve = (ParametricCurve *)NULL;
|
||||
NurbsCurveInterface *nurbs = (NurbsCurveInterface *)NULL;
|
||||
|
||||
if (_curves != (ParametricCurveCollection *)NULL) {
|
||||
curve = _curves->get_default_curve();
|
||||
}
|
||||
|
||||
if (curve != (ParametricCurve *)NULL) {
|
||||
nurbs = curve->get_nurbs_interface();
|
||||
if (nurbs != (NurbsCurveInterface *)NULL) {
|
||||
// Make sure the curve is fresh.
|
||||
nurbs->recompute();
|
||||
if (curve != (ParametricCurve *)NULL) {
|
||||
nurbs = curve->get_nurbs_interface();
|
||||
}
|
||||
}
|
||||
|
||||
// First, draw the curve itself.
|
||||
if (!ParametricCurveDrawer::draw()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nurbs == (NurbsCurveInterface *)NULL) {
|
||||
// The rest of this depends on having an actual NURBS curve.
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -168,5 +168,5 @@ convert_to_nurbs(ParametricCurve *nc) const {
|
|||
nurbs->set_knot(i, get_knot(i));
|
||||
}
|
||||
|
||||
return nurbs->recompute();
|
||||
return nc->recompute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ PUBLISHED:
|
|||
virtual bool set_knot(int n, float t)=0;
|
||||
virtual float get_knot(int n) const=0;
|
||||
|
||||
virtual bool recompute()=0;
|
||||
|
||||
void write_cv(ostream &out, int n) const;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,53 @@ find_length(float start_t, float length_offset) const {
|
|||
return max_t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurve::adjust_point
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it passes through the
|
||||
// point (px, py, pz) at time t, but keeps the same
|
||||
// tangent value at that point.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurve::
|
||||
adjust_point(float, float, float, float) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurve::adjust_tangent
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it has the tangent
|
||||
// (tx, ty, tz) at time t, but keeps the same position
|
||||
// at the point.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurve::
|
||||
adjust_tangent(float, float, float, float) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurve::adjust_pt
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it passes through the
|
||||
// point (px, py, pz) with the tangent (tx, ty, tz).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurve::
|
||||
adjust_pt(float, float, float, float, float, float, float) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurve::recompute
|
||||
// Access: Published, Virtual
|
||||
// Description: Recalculates the curve, if necessary. Returns
|
||||
// true if the resulting curve is valid, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurve::
|
||||
recompute() {
|
||||
return is_valid();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurve::stitch
|
||||
// Access: Published, Virtual
|
||||
|
|
@ -547,9 +594,7 @@ convert_to_nurbs(ParametricCurve *nc) const {
|
|||
}
|
||||
}
|
||||
|
||||
nurbs->recompute();
|
||||
|
||||
return nc->is_valid();
|
||||
return nc->recompute();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -72,6 +72,14 @@ PUBLISHED:
|
|||
virtual bool get_pt(float t, LVecBase3f &point, LVecBase3f &tangent) const=0;
|
||||
virtual bool get_2ndtangent(float t, LVecBase3f &tangent2) const=0;
|
||||
|
||||
virtual bool adjust_point(float t, float px, float py, float pz);
|
||||
virtual bool adjust_tangent(float t, float tx, float ty, float tz);
|
||||
virtual bool adjust_pt(float t,
|
||||
float px, float py, float pz,
|
||||
float tx, float ty, float tz);
|
||||
|
||||
virtual bool recompute();
|
||||
|
||||
virtual bool stitch(const ParametricCurve *a, const ParametricCurve *b);
|
||||
|
||||
bool write_egg(Filename filename, CoordinateSystem cs = CS_default);
|
||||
|
|
|
|||
|
|
@ -73,3 +73,29 @@ evaluate_hpr(float t, LVecBase3f &hpr) const {
|
|||
LVecBase3f xyz;
|
||||
return evaluate(t, xyz, hpr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::adjust_xyz
|
||||
// Access: Published
|
||||
// Description: Adjust the XYZ curve at the indicated time to the new
|
||||
// value. The curve shape will change correspondingly.
|
||||
// Returns true if successful, false if unable to make
|
||||
// the adjustment for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ParametricCurveCollection::
|
||||
adjust_xyz(float t, float x, float y, float z) {
|
||||
return adjust_xyz(t, LVecBase3f(x, y, z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::adjust_hpr
|
||||
// Access: Published
|
||||
// Description: Adjust the HPR curve at the indicated time to the new
|
||||
// value. The curve shape will change correspondingly.
|
||||
// Returns true if successful, false if unable to make
|
||||
// the adjustment for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ParametricCurveCollection::
|
||||
adjust_hpr(float t, float h, float p, float r) {
|
||||
return adjust_hpr(t, LVecBase3f(h, p, r));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <compose_matrix.h>
|
||||
#include <renderRelation.h>
|
||||
#include <string_utils.h>
|
||||
#include <look_at.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::Constructor
|
||||
|
|
@ -30,15 +31,23 @@ ParametricCurveCollection() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
add_curve(ParametricCurve *curve) {
|
||||
prepare_add_curve(curve);
|
||||
_curves.push_back(curve);
|
||||
redraw();
|
||||
}
|
||||
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
curve->register_drawer(drawer);
|
||||
|
||||
drawer->redraw();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::add_curve
|
||||
// Access: Published
|
||||
// Description: Adds a new ParametricCurve to the collection at the
|
||||
// indicated index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
add_curve(ParametricCurve *curve, int index) {
|
||||
prepare_add_curve(curve);
|
||||
index = max(min(index, (int)_curves.size()), 0);
|
||||
_curves.insert(_curves.begin() + index, curve);
|
||||
redraw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -53,11 +62,7 @@ add_curves(Node *node) {
|
|||
int num_curves = r_add_curves(node);
|
||||
|
||||
if (num_curves > 0) {
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
drawer->redraw();
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
return num_curves;
|
||||
|
|
@ -99,15 +104,9 @@ void ParametricCurveCollection::
|
|||
remove_curve(int index) {
|
||||
nassertv(index >= 0 && index < (int)_curves.size());
|
||||
PT(ParametricCurve) curve = _curves[index];
|
||||
prepare_remove_curve(curve);
|
||||
_curves.erase(_curves.begin() + index);
|
||||
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
curve->unregister_drawer(drawer);
|
||||
|
||||
drawer->redraw();
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -134,18 +133,14 @@ has_curve(ParametricCurve *curve) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
clear() {
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
ParametricCurves::iterator ci;
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
curve->unregister_drawer(drawer);
|
||||
}
|
||||
|
||||
drawer->redraw();
|
||||
ParametricCurves::iterator ci;
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
prepare_remove_curve(curve);
|
||||
}
|
||||
_curves.clear();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -157,7 +152,6 @@ void ParametricCurveCollection::
|
|||
clear_timewarps() {
|
||||
PT(ParametricCurve) xyz_curve = (ParametricCurve *)NULL;
|
||||
PT(ParametricCurve) hpr_curve = (ParametricCurve *)NULL;
|
||||
ParametricCurves discard;
|
||||
|
||||
ParametricCurves::iterator ci;
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
|
|
@ -168,7 +162,7 @@ clear_timewarps() {
|
|||
if (xyz_curve == (ParametricCurve *)NULL) {
|
||||
xyz_curve = curve;
|
||||
} else {
|
||||
discard.push_back(curve);
|
||||
prepare_remove_curve(curve);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -176,12 +170,12 @@ clear_timewarps() {
|
|||
if (hpr_curve == (ParametricCurve *)NULL) {
|
||||
hpr_curve = curve;
|
||||
} else {
|
||||
discard.push_back(curve);
|
||||
prepare_remove_curve(curve);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
discard.push_back(curve);
|
||||
prepare_remove_curve(curve);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,18 +186,7 @@ clear_timewarps() {
|
|||
_curves.push_back(hpr_curve);
|
||||
}
|
||||
|
||||
// Properly unregister all the curves we're discarding.
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
ParametricCurves::iterator ci;
|
||||
for (ci = discard.begin(); ci != discard.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
curve->unregister_drawer(drawer);
|
||||
}
|
||||
|
||||
drawer->redraw();
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -288,6 +271,27 @@ get_num_timewarps() const {
|
|||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::get_timewarp_curve
|
||||
// Access: Published
|
||||
// Description: Returns the nth timewarp curve in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ParametricCurve *ParametricCurveCollection::
|
||||
get_timewarp_curve(int n) const {
|
||||
ParametricCurves::const_iterator ci;
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
if (curve->get_curve_type() == PCT_T) {
|
||||
if (n == 0) {
|
||||
return curve;
|
||||
}
|
||||
n--;
|
||||
}
|
||||
}
|
||||
nassertr(false, (ParametricCurve *)NULL);
|
||||
return (ParametricCurve *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::make_even
|
||||
// Access: Published
|
||||
|
|
@ -320,21 +324,43 @@ make_even(float max_t, float segments_per_unit) {
|
|||
// approximately the same length as all the others.
|
||||
CurveFitter fitter;
|
||||
|
||||
int num_segments = (int)floor(segments_per_unit * xyz_curve->get_max_t() + 0.5);
|
||||
int num_segments = max(1, (int)floor(segments_per_unit * xyz_curve->get_max_t() + 0.5));
|
||||
|
||||
if (parametrics_cat.is_debug()) {
|
||||
parametrics_cat.debug()
|
||||
<< "Calculating length of curve.\n";
|
||||
}
|
||||
|
||||
float net_length = xyz_curve->calc_length();
|
||||
float segment_length = net_length / (float)num_segments;
|
||||
|
||||
if (parametrics_cat.is_debug()) {
|
||||
parametrics_cat.debug()
|
||||
<< "Curve has total length " << net_length << "; dividing into "
|
||||
<< num_segments << " segments of " << segment_length << " units each.\n";
|
||||
}
|
||||
|
||||
float last_t = 0.0;
|
||||
fitter.add_xyz(0.0, LVecBase3f(last_t, 0.0, 0.0));
|
||||
|
||||
for (int i = 0; i < num_segments; i++) {
|
||||
float next_t = xyz_curve->find_length(last_t, segment_length);
|
||||
fitter.add_xyz((float)(i + 1) / (num_segments + 1) * max_t,
|
||||
fitter.add_xyz((float)(i + 1) / num_segments * max_t,
|
||||
LVecBase3f(next_t, 0.0, 0.0));
|
||||
|
||||
if (parametrics_cat.is_spam()) {
|
||||
parametrics_cat.spam()
|
||||
<< "Point " << i << " is at " << next_t << "\n";
|
||||
}
|
||||
|
||||
last_t = next_t;
|
||||
}
|
||||
|
||||
if (parametrics_cat.is_debug()) {
|
||||
parametrics_cat.debug()
|
||||
<< "Done computing segments.\n";
|
||||
}
|
||||
|
||||
fitter.compute_tangents(1);
|
||||
PT(ParametricCurveCollection) fit = fitter.make_nurbs();
|
||||
ParametricCurve *t_curve = fit->get_xyz_curve();
|
||||
|
|
@ -343,6 +369,96 @@ make_even(float max_t, float segments_per_unit) {
|
|||
add_curve(t_curve);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::face_forward
|
||||
// Access: Published
|
||||
// Description: Discards the existing HPR curve and generates a new
|
||||
// one that looks in the direction of travel along the
|
||||
// XYZ curve, based on the XYZ curve's tangent at each
|
||||
// point.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
face_forward(float segments_per_unit) {
|
||||
ParametricCurve *xyz_curve = get_xyz_curve();
|
||||
if (xyz_curve == (ParametricCurve *)NULL) {
|
||||
parametrics_cat.error()
|
||||
<< "No XYZ curve for face_forward().\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Eliminate all the old hpr curves, and also take note of the index
|
||||
// number of the first XYZ curve.
|
||||
int xyz_index = -1;
|
||||
ParametricCurves::const_iterator ci;
|
||||
ParametricCurves new_curves;
|
||||
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
if (curve->get_curve_type() == PCT_HPR) {
|
||||
prepare_remove_curve(curve);
|
||||
} else {
|
||||
if (curve->get_curve_type() == PCT_XYZ && xyz_index == -1) {
|
||||
xyz_index = (ci - _curves.begin());
|
||||
}
|
||||
new_curves.push_back(curve);
|
||||
}
|
||||
}
|
||||
_curves.swap(new_curves);
|
||||
|
||||
// Now divvy up the XYZ curve into num_segments sections, of equal
|
||||
// length in parametric time (based on the timewarp curves).
|
||||
CurveFitter fitter;
|
||||
|
||||
float max_t = get_max_t();
|
||||
int num_segments = (int)floor(segments_per_unit * max_t + 0.5);
|
||||
|
||||
LVecBase3f hpr(0.0, 0.0, 0.0);
|
||||
|
||||
// We compute the first HPR point a little point into the beginning
|
||||
// of the curve, instead of at 0.0, because the tangent at 0.0 is
|
||||
// likely to be zero.
|
||||
determine_hpr(0.001, xyz_curve, hpr);
|
||||
fitter.add_hpr(0.0, hpr);
|
||||
|
||||
for (int i = 0; i < num_segments; i++) {
|
||||
float t = (float)(i + 1) / num_segments * max_t;
|
||||
determine_hpr(t, xyz_curve, hpr);
|
||||
fitter.add_hpr(t, hpr);
|
||||
}
|
||||
|
||||
fitter.wrap_hpr();
|
||||
fitter.compute_tangents(1);
|
||||
PT(ParametricCurveCollection) fit = fitter.make_nurbs();
|
||||
ParametricCurve *hpr_curve = fit->get_hpr_curve();
|
||||
nassertv(hpr_curve != (ParametricCurve *)NULL);
|
||||
add_curve(hpr_curve, xyz_index + 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::reset_max_t
|
||||
// Access: Published
|
||||
// Description: Adjusts the apparent length of the curve by applying
|
||||
// a new timewarp that maps the range [0..max_t] to the
|
||||
// range [0..get_max_t()]. After this call, the curve
|
||||
// collection will contain one more timewarp curve, and
|
||||
// get_max_t() will return the given max_t value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
reset_max_t(float max_t) {
|
||||
// Define a linear NURBS curve.
|
||||
PT(NurbsCurve) nurbs = new NurbsCurve;
|
||||
nurbs->set_curve_type(PCT_T);
|
||||
nurbs->set_order(2);
|
||||
nurbs->append_cv(LVecBase3f(0.0, 0.0, 0.0));
|
||||
nurbs->append_cv(LVecBase3f(get_max_t(), 0.0, 0.0));
|
||||
nurbs->set_knot(0, 0.0);
|
||||
nurbs->set_knot(1, 0.0);
|
||||
nurbs->set_knot(2, max_t);
|
||||
nurbs->set_knot(3, max_t);
|
||||
nurbs->recompute();
|
||||
add_curve(nurbs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::evaluate
|
||||
// Access: Published
|
||||
|
|
@ -470,6 +586,72 @@ evaluate_t(float t) const {
|
|||
return t0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::adjust_xyz
|
||||
// Access: Published
|
||||
// Description: Adjust the XYZ curve at the indicated time to the new
|
||||
// value. The curve shape will change correspondingly.
|
||||
// Returns true if successful, false if unable to make
|
||||
// the adjustment for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurveCollection::
|
||||
adjust_xyz(float t, const LVecBase3f &xyz) {
|
||||
ParametricCurve *xyz_curve = get_xyz_curve();
|
||||
if (xyz_curve == (ParametricCurve *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float t0 = evaluate_t(t);
|
||||
if (t0 >= 0.0 && t < xyz_curve->get_max_t()) {
|
||||
return xyz_curve->adjust_point(t, xyz[0], xyz[1], xyz[2]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::adjust_hpr
|
||||
// Access: Published
|
||||
// Description: Adjust the HPR curve at the indicated time to the new
|
||||
// value. The curve shape will change correspondingly.
|
||||
// Returns true if successful, false if unable to make
|
||||
// the adjustment for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurveCollection::
|
||||
adjust_hpr(float t, const LVecBase3f &hpr) {
|
||||
ParametricCurve *hpr_curve = get_hpr_curve();
|
||||
if (hpr_curve == (ParametricCurve *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float t0 = evaluate_t(t);
|
||||
if (t0 >= 0.0 && t < hpr_curve->get_max_t()) {
|
||||
return hpr_curve->adjust_point(t, hpr[0], hpr[1], hpr[2]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::recompute
|
||||
// Access: Published
|
||||
// Description: Ensures all the curves are freshly computed and
|
||||
// up-to-date. Returns true if everything is valid,
|
||||
// false if at least one curve is incorrect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurveCollection::
|
||||
recompute() {
|
||||
bool all_ok = true;
|
||||
|
||||
ParametricCurves::iterator ci;
|
||||
for (ci = _curves.begin(); ci != _curves.end(); ++ci) {
|
||||
ParametricCurve *curve = (*ci);
|
||||
if (!curve->recompute()) {
|
||||
all_ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::stitch
|
||||
// Access: Published
|
||||
|
|
@ -660,13 +842,8 @@ r_add_curves(Node *node) {
|
|||
|
||||
if (node->is_of_type(ParametricCurve::get_class_type())) {
|
||||
ParametricCurve *curve = DCAST(ParametricCurve, node);
|
||||
prepare_add_curve(curve);
|
||||
_curves.push_back(curve);
|
||||
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
curve->register_drawer(drawer);
|
||||
}
|
||||
num_curves++;
|
||||
}
|
||||
|
||||
|
|
@ -719,3 +896,79 @@ unregister_drawer(ParametricCurveDrawer *drawer) {
|
|||
curve->unregister_drawer(drawer);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::determine_hpr
|
||||
// Access: Private
|
||||
// Description: Computes the orientation at the given point in time,
|
||||
// based on the tangent of the XYZ curve. Returns true
|
||||
// if the orientation can be determined, or false if it
|
||||
// cannot (in which case hpr is left unchanged).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ParametricCurveCollection::
|
||||
determine_hpr(float t, ParametricCurve *xyz_curve, LVecBase3f &hpr) const {
|
||||
float t0 = evaluate_t(t);
|
||||
|
||||
LVector3f tangent;
|
||||
if (!xyz_curve->get_tangent(t0, tangent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tangent.length_squared() == 0.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LMatrix3f mat;
|
||||
look_at(mat, tangent);
|
||||
|
||||
LVecBase3f scale;
|
||||
decompose_matrix(mat, scale, hpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::prepare_add_curve
|
||||
// Access: Private
|
||||
// Description: Registers the curve with the list of drawers that
|
||||
// share this collection, in preparation for adding it
|
||||
// to the _curves list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
prepare_add_curve(ParametricCurve *curve) {
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
curve->register_drawer(drawer);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::prepare_remove_curve
|
||||
// Access: Private
|
||||
// Description: Unregisters the curve with the list of drawers that
|
||||
// share this collection, in preparation for removing it
|
||||
// from the _curves list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
prepare_remove_curve(ParametricCurve *curve) {
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
curve->unregister_drawer(drawer);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParametricCurveCollection::redraw
|
||||
// Access: Private
|
||||
// Description: Calls redraw() on all drawers that share this
|
||||
// collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParametricCurveCollection::
|
||||
redraw() {
|
||||
DrawerList::iterator di;
|
||||
for (di = _drawers.begin(); di != _drawers.end(); ++di) {
|
||||
ParametricCurveDrawer *drawer = (*di);
|
||||
drawer->redraw();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ PUBLISHED:
|
|||
INLINE ~ParametricCurveCollection();
|
||||
|
||||
void add_curve(ParametricCurve *curve);
|
||||
void add_curve(ParametricCurve *curve, int index);
|
||||
int add_curves(Node *node);
|
||||
bool remove_curve(ParametricCurve *curve);
|
||||
void remove_curve(int index);
|
||||
|
|
@ -49,10 +50,13 @@ PUBLISHED:
|
|||
ParametricCurve *get_hpr_curve() const;
|
||||
ParametricCurve *get_default_curve() const;
|
||||
int get_num_timewarps() const;
|
||||
ParametricCurve *get_timewarp_curve(int n) const;
|
||||
|
||||
INLINE float get_max_t() const;
|
||||
|
||||
void make_even(float max_t, float segments_per_unit);
|
||||
void face_forward(float segments_per_unit);
|
||||
void reset_max_t(float max_t);
|
||||
|
||||
bool evaluate(float t, LVecBase3f &xyz, LVecBase3f &hpr) const;
|
||||
bool evaluate(float t, LMatrix4f &result, CoordinateSystem cs = CS_default) const;
|
||||
|
|
@ -61,6 +65,13 @@ PUBLISHED:
|
|||
INLINE bool evaluate_xyz(float t, LVecBase3f &xyz) const;
|
||||
INLINE bool evaluate_hpr(float t, LVecBase3f &hpr) const;
|
||||
|
||||
INLINE bool adjust_xyz(float t, float x, float y, float z);
|
||||
bool adjust_xyz(float t, const LVecBase3f &xyz);
|
||||
INLINE bool adjust_hpr(float t, float h, float p, float r);
|
||||
bool adjust_hpr(float t, const LVecBase3f &xyz);
|
||||
|
||||
bool recompute();
|
||||
|
||||
bool stitch(const ParametricCurveCollection *a,
|
||||
const ParametricCurveCollection *b);
|
||||
|
||||
|
|
@ -75,6 +86,12 @@ public:
|
|||
void register_drawer(ParametricCurveDrawer *drawer);
|
||||
void unregister_drawer(ParametricCurveDrawer *drawer);
|
||||
|
||||
private:
|
||||
bool determine_hpr(float t, ParametricCurve *xyz_curve, LVecBase3f &hpr) const;
|
||||
void prepare_add_curve(ParametricCurve *curve);
|
||||
void prepare_remove_curve(ParametricCurve *curve);
|
||||
void redraw();
|
||||
|
||||
private:
|
||||
typedef vector<PT(ParametricCurve)> ParametricCurves;
|
||||
ParametricCurves _curves;
|
||||
|
|
|
|||
|
|
@ -297,16 +297,26 @@ draw() {
|
|||
// First, remove the old drawing, if any.
|
||||
hide();
|
||||
|
||||
_drawn = true;
|
||||
|
||||
// If there's no curve, draw nothing and return false.
|
||||
if (_curves == (ParametricCurveCollection *)NULL ||
|
||||
_curves->get_default_curve() == (ParametricCurve *)NULL) {
|
||||
if (_curves == (ParametricCurveCollection *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ParametricCurve *xyz_curve = _curves->get_default_curve();
|
||||
if (xyz_curve == (ParametricCurve *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, let's go to town!
|
||||
|
||||
// Make sure the curve(s) are fresh.
|
||||
_curves->recompute();
|
||||
|
||||
int total_segs = (int)floor(_curves->get_max_t() * _num_segs + 0.5);
|
||||
|
||||
float max_t = get_max_t();
|
||||
float max_t = xyz_curve->get_max_t();
|
||||
float scale = max_t / (float)(total_segs-1);
|
||||
float t;
|
||||
LVecBase3f point;
|
||||
|
|
@ -318,7 +328,7 @@ draw() {
|
|||
for (i = 0; i < total_segs; i++) {
|
||||
t = (float)i * scale;
|
||||
|
||||
next_in = _curves->evaluate_xyz(t, point);
|
||||
next_in = xyz_curve->get_point(t, point);
|
||||
|
||||
if (!next_in || !last_in) {
|
||||
_lines.move_to(point);
|
||||
|
|
@ -329,7 +339,9 @@ draw() {
|
|||
}
|
||||
|
||||
_lines.create(_geom_node, _frame_accurate);
|
||||
_drawn = true;
|
||||
|
||||
max_t = get_max_t();
|
||||
scale = max_t / (float)(total_segs-1);
|
||||
|
||||
// Now draw the time tick marks.
|
||||
if (_num_ticks > 0.0) {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ get_2ndtangent(float t, LVecBase3f &tangent2) const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PiecewiseCurve::adjust_point
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it passes through the
|
||||
// point (px, py, pz) at time t, but keeps the same
|
||||
// tangent value at that point.
|
||||
|
|
@ -143,7 +143,7 @@ adjust_point(float t,
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PiecewiseCurve::adjust_tangent
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it has the tangent
|
||||
// (tx, ty, tz) at time t, but keeps the same position
|
||||
// at the point.
|
||||
|
|
@ -168,7 +168,7 @@ adjust_tangent(float t,
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PiecewiseCurve::adjust_pt
|
||||
// Access: Published
|
||||
// Access: Published, Virtual
|
||||
// Description: Recomputes the curve such that it passes through the
|
||||
// point (px, py, pz) with the tangent (tx, ty, tz).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ PUBLISHED:
|
|||
PiecewiseCurve();
|
||||
~PiecewiseCurve();
|
||||
|
||||
public:
|
||||
// These functions are all inherited from ParametricCurve, and need
|
||||
// not be re-published.
|
||||
virtual bool is_valid() const;
|
||||
virtual float get_max_t() const;
|
||||
|
||||
|
|
@ -30,11 +33,11 @@ PUBLISHED:
|
|||
virtual bool get_pt(float t, LVecBase3f &point, LVecBase3f &tangent) const;
|
||||
virtual bool get_2ndtangent(float t, LVecBase3f &tangent2) const;
|
||||
|
||||
bool adjust_point(float t, float px, float py, float pz);
|
||||
bool adjust_tangent(float t, float tx, float ty, float tz);
|
||||
bool adjust_pt(float t,
|
||||
float px, float py, float pz,
|
||||
float tx, float ty, float tz);
|
||||
virtual bool adjust_point(float t, float px, float py, float pz);
|
||||
virtual bool adjust_tangent(float t, float tx, float ty, float tz);
|
||||
virtual bool adjust_pt(float t,
|
||||
float px, float py, float pz,
|
||||
float tx, float ty, float tz);
|
||||
|
||||
public:
|
||||
int get_num_segs() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue