Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/parametrics/piecewiseCurve.cxx

Go to the documentation of this file.
00001 // Filename: piecewiseCurve.cxx
00002 // Created by:  drose (04Mar01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "piecewiseCurve.h"
00020 #include "cubicCurveseg.h"
00021 #include "config_parametrics.h"
00022 
00023 #include <datagram.h>
00024 #include <datagramIterator.h>
00025 #include <bamWriter.h>
00026 #include <bamReader.h>
00027 
00028 TypeHandle PiecewiseCurve::_type_handle;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: PiecewiseCurve::Constructor
00032 //       Access: Public
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 PiecewiseCurve::
00036 PiecewiseCurve() {
00037   _last_ti = 0;
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: PiecewiseCurve::Destructor
00042 //       Access: Protected
00043 //  Description:
00044 ////////////////////////////////////////////////////////////////////
00045 PiecewiseCurve::
00046 ~PiecewiseCurve() {
00047   remove_all_curvesegs();
00048 }
00049 
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: PiecewiseCurve::is_valid
00053 //       Access: Published, Virtual
00054 //  Description: Returns true if the curve is defined.  In the case of
00055 //               a PiecewiseCurve, this means we have at least one
00056 //               segment.
00057 ////////////////////////////////////////////////////////////////////
00058 bool PiecewiseCurve::
00059 is_valid() const {
00060   return !_segs.empty();
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: PiecewiseCurve::get_max_t
00065 //       Access: Published, Virtual
00066 //  Description: Returns the upper bound of t for the entire curve.
00067 //               The curve is defined in the range 0.0f <= t <=
00068 //               get_max_t().
00069 ////////////////////////////////////////////////////////////////////
00070 float PiecewiseCurve::
00071 get_max_t() const {
00072   return _segs.empty() ? 0.0f : _segs.back()._tend;
00073 }
00074 
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: PiecewiseCurve::get_point
00078 //       Access: Published, Virtual
00079 //  Description: Returns the point of the curve at a given parametric
00080 //               point t.  Returns true if t is in the valid range 0.0f
00081 //               <= t <= get_max_t(); if t is outside this range, sets
00082 //               point to the value of the curve at the beginning or
00083 //               end (whichever is nearer) and returns false.
00084 ////////////////////////////////////////////////////////////////////
00085 bool PiecewiseCurve::
00086 get_point(float t, LVecBase3f &point) const {
00087   const ParametricCurve *curve;
00088   bool result = find_curve(curve, t);
00089 
00090   // We use | instead of || so we won't short-circuit this calculation.
00091   return result | curve->get_point(t, point);
00092 }
00093 
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: PiecewiseCurve::get_tangent
00097 //       Access: Published, Virtual
00098 //  Description: Returns the tangent of the curve at a given parametric
00099 //               point t.
00100 ////////////////////////////////////////////////////////////////////
00101 bool PiecewiseCurve::
00102 get_tangent(float t, LVecBase3f &tangent) const {
00103   const ParametricCurve *curve;
00104   bool result = find_curve(curve, t);
00105 
00106   // We use | instead of || so we won't short-circuit this calculation.
00107   return result | curve->get_tangent(t, tangent);
00108 }
00109 
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: PiecewiseCurve::get_2ndtangent
00113 //       Access: Published, Virtual
00114 //  Description: Returns the tangent of the first derivative of the
00115 //               curve at the point t.
00116 ////////////////////////////////////////////////////////////////////
00117 bool PiecewiseCurve::
00118 get_2ndtangent(float t, LVecBase3f &tangent2) const {
00119   const ParametricCurve *curve;
00120   bool result = find_curve(curve, t);
00121 
00122   // We use | instead of || so we won't short-circuit this calculation.
00123   return result | curve->get_2ndtangent(t, tangent2);
00124 }
00125 
00126 ////////////////////////////////////////////////////////////////////
00127 //     Function: PiecewiseCurve::adjust_point
00128 //       Access: Published, Virtual
00129 //  Description: Recomputes the curve such that it passes through the
00130 //               point (px, py, pz) at time t, but keeps the same
00131 //               tangent value at that point.
00132 ////////////////////////////////////////////////////////////////////
00133 bool PiecewiseCurve::
00134 adjust_point(float t,
00135              float px, float py, float pz) {
00136   if (parametrics_cat.is_debug()) {
00137     parametrics_cat.debug()
00138       << "Adjusting point at " << t << " to " << px << " " << py << " "
00139       << pz << "\n";
00140   }
00141 
00142   const ParametricCurve *curve;
00143   bool result = find_curve(curve, t);
00144 
00145   if (!result) {
00146     cerr << "No curve segment at t = " << t << "\n";
00147     return false;
00148   }
00149 
00150   rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f(),
00151                    RT_POINT, t, LVecBase4f(px, py, pz, 1.0f),
00152                    RT_TANGENT | RT_KEEP_ORIG, t, LVecBase4f(),
00153                    RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f());
00154   return true;
00155 }
00156 
00157 ////////////////////////////////////////////////////////////////////
00158 //     Function: PiecewiseCurve::adjust_tangent
00159 //       Access: Published, Virtual
00160 //  Description: Recomputes the curve such that it has the tangent
00161 //               (tx, ty, tz) at time t, but keeps the same position
00162 //               at the point.
00163 ////////////////////////////////////////////////////////////////////
00164 bool PiecewiseCurve::
00165 adjust_tangent(float t,
00166                float tx, float ty, float tz) {
00167   const ParametricCurve *curve;
00168   bool result = find_curve(curve, t);
00169 
00170   if (!result) {
00171     cerr << "No curve segment at t = " << t << "\n";
00172     return false;
00173   }
00174 
00175   rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f(),
00176                    RT_POINT | RT_KEEP_ORIG, t, LVecBase4f(),
00177                    RT_TANGENT, t, LVecBase4f(tx, ty, tz, 0.0f),
00178                    RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f());
00179   return true;
00180 }
00181 
00182 ////////////////////////////////////////////////////////////////////
00183 //     Function: PiecewiseCurve::adjust_pt
00184 //       Access: Published, Virtual
00185 //  Description: Recomputes the curve such that it passes through the
00186 //               point (px, py, pz) with the tangent (tx, ty, tz).
00187 ////////////////////////////////////////////////////////////////////
00188 bool PiecewiseCurve::
00189 adjust_pt(float t,
00190           float px, float py, float pz,
00191           float tx, float ty, float tz) {
00192   const ParametricCurve *curve;
00193   bool result = find_curve(curve, t);
00194 
00195   if (!result) {
00196     cerr << "No curve segment at t = " << t << "\n";
00197     return false;
00198   }
00199 
00200   rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f(),
00201                    RT_POINT, t, LVecBase4f(px, py, pz, 1.0f),
00202                    RT_TANGENT, t, LVecBase4f(tx, ty, tz, 0.0f),
00203                    RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4f());
00204   return true;
00205 }
00206 
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: PiecewiseCurve::get_pt
00210 //       Access: Published, Virtual
00211 //  Description: Simultaneously returns the point and tangent of the
00212 //               curve at a given parametric point t.
00213 ////////////////////////////////////////////////////////////////////
00214 bool PiecewiseCurve::
00215 get_pt(float t, LVecBase3f &point, LVecBase3f &tangent) const {
00216   const ParametricCurve *curve;
00217   bool result = find_curve(curve, t);
00218 
00219   // We use | instead of || so we won't short-circuit this calculation.
00220   return result | curve->get_pt(t, point, tangent);
00221 }
00222 
00223 
00224 ////////////////////////////////////////////////////////////////////
00225 //     Function: PiecewiseCurve::get_num_segs
00226 //       Access: Public
00227 //  Description: Returns the number of curve segments that make up the
00228 //               Piecewise curve.
00229 ////////////////////////////////////////////////////////////////////
00230 int PiecewiseCurve::
00231 get_num_segs() const {
00232   return _segs.size();
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: PiecewiseCurve::get_curveseg
00237 //       Access: Public
00238 //  Description: Returns the curve segment corresponding to the given
00239 //               index.
00240 ////////////////////////////////////////////////////////////////////
00241 ParametricCurve *PiecewiseCurve::
00242 get_curveseg(int ti) {
00243   assert(ti >= 0 && ti < (int)_segs.size());
00244   return _segs[ti]._curve;
00245 }
00246 
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: PiecewiseCurve::insert_curveseg
00250 //       Access: Public
00251 //  Description: Inserts a new curve segment at the indicated index.
00252 //               The curve segment must have been allocated via
00253 //               new; it will be freed using delete when it is removed
00254 //               or the PiecewiseCurve destructs.
00255 //
00256 //               If the curve segment is not inserted at the end, its
00257 //               tlength is subtracted from that of the following
00258 //               segment, so that the overall length of the curve is
00259 //               not changed.
00260 ////////////////////////////////////////////////////////////////////
00261 bool PiecewiseCurve::
00262 insert_curveseg(int ti, ParametricCurve *seg, float tlength) {
00263   if (ti < 0 || ti > (int)_segs.size()) {
00264     return false;
00265   }
00266 
00267   if (ti == (int)_segs.size()) {
00268     _segs.push_back(Curveseg(seg, get_max_t() + tlength));
00269 
00270   } else if (ti==0) {
00271     _segs.insert(_segs.begin(),
00272                  Curveseg(seg, tlength));
00273 
00274   } else {
00275     _segs.insert(_segs.begin() + ti,
00276                  Curveseg(seg, _segs[ti-1]._tend + tlength));
00277   }
00278 
00279   return true;
00280 }
00281 
00282 
00283 ////////////////////////////////////////////////////////////////////
00284 //     Function: PiecewiseCurve::remove_curveseg
00285 //       Access: Public
00286 //  Description: Removes the given curve segment from the curve and
00287 //               frees it.  Returns true if the segment was defined,
00288 //               false otherwise.
00289 ////////////////////////////////////////////////////////////////////
00290 bool PiecewiseCurve::
00291 remove_curveseg(int ti) {
00292   if (ti < 0 || ti >= (int)_segs.size()) {
00293     return false;
00294   }
00295 
00296   float tlength = get_tlength(ti);
00297   _segs.erase(_segs.begin() + ti);
00298 
00299   // Now update the _tend figures for everything after the one we
00300   // removed.
00301   while (ti < (int)_segs.size()) {
00302     _segs[ti]._tend -= tlength;
00303     ti++;
00304   }
00305 
00306   _last_ti = 0;
00307   return true;
00308 }
00309 
00310 ////////////////////////////////////////////////////////////////////
00311 //     Function: PiecewiseCurve::remove_all_curvesegs
00312 //       Access: Public
00313 //  Description: Removes all curve segments from the curve.
00314 ////////////////////////////////////////////////////////////////////
00315 void PiecewiseCurve::
00316 remove_all_curvesegs() {
00317   _segs.erase(_segs.begin(), _segs.end());
00318   _last_ti = 0;
00319 }
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //     Function: PiecewiseCurve::get_tlength
00323 //       Access: Public
00324 //  Description: Returns the parametric length of the given segment of
00325 //               the curve.
00326 ////////////////////////////////////////////////////////////////////
00327 float PiecewiseCurve::
00328 get_tlength(int ti) const {
00329   assert(ti >= 0 && ti < (int)_segs.size());
00330   return (ti==0) ? _segs[ti]._tend : _segs[ti]._tend - _segs[ti-1]._tend;
00331 }
00332 
00333 ////////////////////////////////////////////////////////////////////
00334 //     Function: PiecewiseCurve::get_tstart
00335 //       Access: Public
00336 //  Description: Returns the parametric start of the given segment of
00337 //               the curve.
00338 ////////////////////////////////////////////////////////////////////
00339 float PiecewiseCurve::
00340 get_tstart(int ti) const {
00341   assert(ti >= 0 && ti <= (int)_segs.size());
00342   return (ti==0) ? 0.0f : _segs[ti-1]._tend;
00343 }
00344 
00345 ////////////////////////////////////////////////////////////////////
00346 //     Function: PiecewiseCurve::get_tend
00347 //       Access: Public
00348 //  Description: Returns the parametric end of the given segment of
00349 //               the curve.
00350 ////////////////////////////////////////////////////////////////////
00351 float PiecewiseCurve::
00352 get_tend(int ti) const {
00353   assert(ti >= 0 && ti < (int)_segs.size());
00354   return _segs[ti]._tend;
00355 }
00356 
00357 
00358 ////////////////////////////////////////////////////////////////////
00359 //     Function: PiecewiseCurve::set_tlength
00360 //       Access: Public
00361 //  Description: Sets the parametric length of the given segment of
00362 //               the curve.  The length of the following segment is
00363 //               lengthened by the corresponding amount to keep the
00364 //               overall length of the curve the same.
00365 ////////////////////////////////////////////////////////////////////
00366 bool PiecewiseCurve::
00367 set_tlength(int ti, float tlength) {
00368   if (ti < 0 || ti >= (int)_segs.size()) {
00369     return false;
00370   }
00371 
00372   _segs[ti]._tend += tlength - get_tlength(ti);
00373   return true;
00374 }
00375 
00376 
00377 
00378 ////////////////////////////////////////////////////////////////////
00379 //     Function: PiecewiseCurve::make_nurbs
00380 //       Access: Public
00381 //  Description: Defines the curve as a general NURBS curve.  The
00382 //               order is the degree plus one and must be 1, 2, 3, or
00383 //               4; cvs is an array of num_cvs points each with a
00384 //               homogeneous coordinate; knots is an array of
00385 //               num_cvs+order knot values.
00386 //
00387 //               This creates the individual curve segments and sets
00388 //               up the basis matrices, but does not store the CV's or
00389 //               knot values so the curve shape is not later
00390 //               modifiable.
00391 ////////////////////////////////////////////////////////////////////
00392 void PiecewiseCurve::
00393 make_nurbs(int order, int num_cvs,
00394            const float knots[], const LVecBase4f cvs[]) {
00395   remove_all_curvesegs();
00396 
00397   for (int i=0; i<num_cvs - order + 1; i++) {
00398     if (knots[i+order] > knots[i+order-1]) {
00399       int ti = get_num_segs();
00400       bool result =
00401         insert_curveseg(ti, new CubicCurveseg(order, knots+i, cvs+i),
00402                         knots[i+order] - knots[i+order-1]);
00403       assert(result);
00404     }
00405   }
00406 }
00407 
00408 
00409 ////////////////////////////////////////////////////////////////////
00410 //     Function: PiecewiseCurve::get_bezier_segs
00411 //       Access: Public, Virtual
00412 //  Description: Fills up the indicated vector with a list of
00413 //               BezierSeg structs that describe the curve.  This
00414 //               assumes the curve is a PiecewiseCurve of
00415 //               CubicCurvesegs.  Returns true if successful, false
00416 //               otherwise.
00417 ////////////////////////////////////////////////////////////////////
00418 bool PiecewiseCurve::
00419 get_bezier_segs(BezierSegs &bz_segs) const {
00420   bz_segs.erase(bz_segs.begin(), bz_segs.end());
00421   int i;
00422   BezierSeg seg;
00423   for (i = 0; i < (int)_segs.size(); i++) {
00424     if (!_segs[i]._curve->get_bezier_seg(seg)) {
00425       return false;
00426     }
00427     seg._t = _segs[i]._tend;
00428     bz_segs.push_back(seg);
00429   }
00430 
00431   return true;
00432 }
00433 
00434 ////////////////////////////////////////////////////////////////////
00435 //     Function: PiecewiseCurve::rebuild_curveseg
00436 //       Access: Public, Virtual
00437 //  Description: Rebuilds the current curve segment (as selected by
00438 //               the most recent call to find_curve()) according to
00439 //               the specified properties (see
00440 //               CubicCurveseg::compute_seg).  Returns true if
00441 //               possible, false if something goes horribly wrong.
00442 ////////////////////////////////////////////////////////////////////
00443 bool PiecewiseCurve::
00444 rebuild_curveseg(int, float, const LVecBase4f &,
00445                  int, float, const LVecBase4f &,
00446                  int, float, const LVecBase4f &,
00447                  int, float, const LVecBase4f &) {
00448   cerr << "rebuild_curveseg not implemented for this curve type.\n";
00449   return false;
00450 }
00451 
00452 ////////////////////////////////////////////////////////////////////
00453 //     Function: PiecewiseCurve::find_curve
00454 //       Access: Protected
00455 //  Description: Finds the curve corresponding to the given value of
00456 //               t.  If t is inside the curve's defined range, sets
00457 //               curve to the appropriate segment, translates t to
00458 //               [0,1] to index into the segment's coordinate system,
00459 //               and returns true.  If t is outside the curve's
00460 //               defined range, sets curve to the nearest segment and
00461 //               t to the nearest point on this segment, and returns
00462 //               false.
00463 ////////////////////////////////////////////////////////////////////
00464 bool PiecewiseCurve::
00465 find_curve(const ParametricCurve *&curve, float &t) const {
00466   // Check the index computed by the last call to find_curve().  If
00467   // it's still a reasonable starting value, start searching from
00468   // there.  This way, we take advantage of locality of reference: the
00469   // search is trivial it is the same segment as last time, or the
00470   // next segment after the last one.
00471   if (_last_ti>0 && _segs[_last_ti-1]._tend>=t) {
00472     // However, if the new t value precedes that of last time, we'll
00473     // have to start over.
00474 
00475     // We do some messy casting so we can get away with assigning a
00476     // value to a member within a const function.  This assignment
00477     // doesn't really count as a const violation since we're just
00478     // updating a cached value, not changing any real data of the
00479     // class.
00480     ((PiecewiseCurve *)this)->_last_ti = 0;
00481   }
00482 
00483   int ti;
00484   for (ti = _last_ti; ti < (int)_segs.size(); ti++) {
00485     if (_segs[ti]._tend+0.00001f > t) {
00486       break;
00487     }
00488   }
00489 
00490   if (ti < (int)_segs.size()) {
00491     // Adjust t to the range [0,1).
00492     if (ti > 0) {
00493       t = (t - _segs[ti-1]._tend) / (_segs[ti]._tend - _segs[ti-1]._tend);
00494     } else {
00495       t /= _segs[0]._tend;
00496     }
00497   }
00498 
00499   if (t < 0) {
00500     // Oops.
00501     curve = _segs[0]._curve;
00502     t = 0.0f;
00503     return false;
00504   }
00505 
00506   if (ti >= (int)_segs.size() || !_segs[ti]._curve->is_valid()) {
00507     assert(ti <= (int)_segs.size());
00508 
00509     // If we're out of bounds, or the curve is undefined, we're probably
00510     // screwed.  There's one exception: if we were right on a border between
00511     // curves, try the curve before.
00512 
00513     if (ti > 0 && t < _segs[ti-1]._tend+0.0001f) {
00514       ti--;
00515       t = 1.0f;
00516     }
00517 
00518     if (ti >= (int)_segs.size()) {
00519       if (_segs.empty()) {
00520         curve = NULL;
00521         t = 0.0f;
00522         return false;
00523       } else {
00524         curve = _segs.back()._curve;
00525         t = 1.0f;
00526         return false;
00527       }
00528     } else if (!_segs[ti]._curve->is_valid()) {
00529       curve = _segs[ti]._curve;
00530       return false;
00531     }
00532   }
00533 
00534   // Again, some messy casting so we can get away with updating the
00535   // cached index value for next time.
00536   ((PiecewiseCurve *)this)->_last_ti = ti;
00537 
00538   // Now scale t back into the curve's own valid range.
00539   t *= _segs[ti]._curve->get_max_t();
00540   curve = _segs[ti]._curve;
00541   return true;
00542 }
00543 
00544 
00545 ////////////////////////////////////////////////////////////////////
00546 //     Function: PiecewiseCurve::current_seg_range
00547 //       Access: Protected
00548 //  Description: Returns a number in the range [0,1], representing the
00549 //               conversion of t into the current segment's coordinate
00550 //               system (the segment last returned by find_curve).
00551 //               This operation is already performed automatically on
00552 //               the t passed into find_seg; this function is useful
00553 //               only to adjust a different value into the same range.
00554 //
00555 //               It is an error to call this function if find_curve()
00556 //               has not yet been called, or if find_curve() returned
00557 //               false from its previous call.
00558 ////////////////////////////////////////////////////////////////////
00559 float PiecewiseCurve::
00560 current_seg_range(float t) const {
00561   int ti = _last_ti;
00562 
00563   assert(ti < (int)_segs.size());
00564 
00565   // Adjust t to the range [0,1).
00566   if (ti > 0) {
00567     t = (t - _segs[ti-1]._tend) / (_segs[ti]._tend - _segs[ti-1]._tend);
00568   } else {
00569     t /= _segs[0]._tend;
00570   }
00571 
00572   return t;
00573 }
00574 
00575 ////////////////////////////////////////////////////////////////////
00576 //     Function: PiecewiseCurve::write_datagram
00577 //       Access: Protected, Virtual
00578 //  Description: Function to write the important information in
00579 //               the particular object to a Datagram
00580 ////////////////////////////////////////////////////////////////////
00581 void PiecewiseCurve::
00582 write_datagram(BamWriter *manager, Datagram &me) {
00583   ParametricCurve::write_datagram(manager, me);
00584 
00585   me.add_uint32(_segs.size());
00586   size_t i;
00587   for (i = 0; i < _segs.size(); i++) {
00588     const Curveseg &seg = _segs[i];
00589     manager->write_pointer(me, seg._curve);
00590     me.add_float64(seg._tend);
00591   }
00592 
00593   _last_ti = 0;
00594 }
00595 
00596 ////////////////////////////////////////////////////////////////////
00597 //     Function: PiecewiseCurve::fillin
00598 //       Access: Protected
00599 //  Description: Function that reads out of the datagram (or asks
00600 //               manager to read) all of the data that is needed to
00601 //               re-create this object and stores it in the appropiate
00602 //               place
00603 ////////////////////////////////////////////////////////////////////
00604 void PiecewiseCurve::
00605 fillin(DatagramIterator &scan, BamReader *manager) {
00606   ParametricCurve::fillin(scan, manager);
00607 
00608   size_t num_segs = scan.get_uint32();
00609   _segs.reserve(num_segs);
00610   size_t i;
00611   for (i = 0; i < num_segs; i++) {
00612     Curveseg seg;
00613     manager->read_pointer(scan);
00614     seg._curve = (ParametricCurve *)NULL;
00615     seg._tend = scan.get_float64();
00616     _segs.push_back(seg);
00617   }
00618 }
00619 
00620 ////////////////////////////////////////////////////////////////////
00621 //     Function: PiecewiseCurve::complete_pointers
00622 //       Access: Protected, Virtual
00623 //  Description: Takes in a vector of pointes to TypedWritable
00624 //               objects that correspond to all the requests for
00625 //               pointers that this object made to BamReader.
00626 ////////////////////////////////////////////////////////////////////
00627 int PiecewiseCurve::
00628 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00629   int used = ParametricCurve::complete_pointers(p_list, manager);
00630 
00631   size_t i;
00632   for (i = 0; i < _segs.size(); i++) {
00633     _segs[i]._curve = DCAST(ParametricCurve, p_list[used + i]);
00634   }
00635 
00636   return used + _segs.size();
00637 }

Generated on Fri May 2 00:40:51 2003 for Panda by doxygen1.3