Panda3D
 All Classes Functions Variables Enumerations
piecewiseCurve.cxx
1 // Filename: piecewiseCurve.cxx
2 // Created by: drose (04Mar01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "piecewiseCurve.h"
16 #include "cubicCurveseg.h"
17 #include "config_parametrics.h"
18 
19 #include "datagram.h"
20 #include "datagramIterator.h"
21 #include "bamWriter.h"
22 #include "bamReader.h"
23 
24 TypeHandle PiecewiseCurve::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: PiecewiseCurve::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 PiecewiseCurve::
32 PiecewiseCurve() {
33  _last_ti = 0;
34 }
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: PiecewiseCurve::Destructor
38 // Access: Protected
39 // Description:
40 ////////////////////////////////////////////////////////////////////
41 PiecewiseCurve::
42 ~PiecewiseCurve() {
44 }
45 
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: PiecewiseCurve::is_valid
49 // Access: Published, Virtual
50 // Description: Returns true if the curve is defined. In the case of
51 // a PiecewiseCurve, this means we have at least one
52 // segment.
53 ////////////////////////////////////////////////////////////////////
55 is_valid() const {
56  return !_segs.empty();
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: PiecewiseCurve::get_max_t
61 // Access: Published, Virtual
62 // Description: Returns the upper bound of t for the entire curve.
63 // The curve is defined in the range 0.0f <= t <=
64 // get_max_t().
65 ////////////////////////////////////////////////////////////////////
66 PN_stdfloat PiecewiseCurve::
67 get_max_t() const {
68  return _segs.empty() ? 0.0f : _segs.back()._tend;
69 }
70 
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: PiecewiseCurve::get_point
74 // Access: Published, Virtual
75 // Description: Returns the point of the curve at a given parametric
76 // point t. Returns true if t is in the valid range 0.0f
77 // <= t <= get_max_t(); if t is outside this range, sets
78 // point to the value of the curve at the beginning or
79 // end (whichever is nearer) and returns false.
80 ////////////////////////////////////////////////////////////////////
82 get_point(PN_stdfloat t, LVecBase3 &point) const {
83  const ParametricCurve *curve;
84  bool result = find_curve(curve, t);
85  if (curve == NULL){
86  return false;
87  }
88  // We use | instead of || so we won't short-circuit this calculation.
89  return result | curve->get_point(t, point);
90 }
91 
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function: PiecewiseCurve::get_tangent
95 // Access: Published, Virtual
96 // Description: Returns the tangent of the curve at a given parametric
97 // point t.
98 ////////////////////////////////////////////////////////////////////
100 get_tangent(PN_stdfloat t, LVecBase3 &tangent) const {
101  const ParametricCurve *curve;
102  bool result = find_curve(curve, t);
103 
104  // We use | instead of || so we won't short-circuit this calculation.
105  return result | curve->get_tangent(t, tangent);
106 }
107 
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: PiecewiseCurve::get_2ndtangent
111 // Access: Published, Virtual
112 // Description: Returns the tangent of the first derivative of the
113 // curve at the point t.
114 ////////////////////////////////////////////////////////////////////
115 bool PiecewiseCurve::
116 get_2ndtangent(PN_stdfloat t, LVecBase3 &tangent2) const {
117  const ParametricCurve *curve;
118  bool result = find_curve(curve, t);
119 
120  // We use | instead of || so we won't short-circuit this calculation.
121  return result | curve->get_2ndtangent(t, tangent2);
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: PiecewiseCurve::adjust_point
126 // Access: Published, Virtual
127 // Description: Recomputes the curve such that it passes through the
128 // point (px, py, pz) at time t, but keeps the same
129 // tangent value at that point.
130 ////////////////////////////////////////////////////////////////////
131 bool PiecewiseCurve::
132 adjust_point(PN_stdfloat t,
133  PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz) {
134  if (parametrics_cat.is_debug()) {
135  parametrics_cat.debug()
136  << "Adjusting point at " << t << " to " << px << " " << py << " "
137  << pz << "\n";
138  }
139 
140  const ParametricCurve *curve;
141  bool result = find_curve(curve, t);
142 
143  if (!result) {
144  cerr << "No curve segment at t = " << t << "\n";
145  return false;
146  }
147 
148  rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4(),
149  RT_POINT, t, LVecBase4(px, py, pz, 1.0f),
150  RT_TANGENT | RT_KEEP_ORIG, t, LVecBase4(),
151  RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4());
152  return true;
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: PiecewiseCurve::adjust_tangent
157 // Access: Published, Virtual
158 // Description: Recomputes the curve such that it has the tangent
159 // (tx, ty, tz) at time t, but keeps the same position
160 // at the point.
161 ////////////////////////////////////////////////////////////////////
162 bool PiecewiseCurve::
163 adjust_tangent(PN_stdfloat t,
164  PN_stdfloat tx, PN_stdfloat ty, PN_stdfloat tz) {
165  const ParametricCurve *curve;
166  bool result = find_curve(curve, t);
167 
168  if (!result) {
169  cerr << "No curve segment at t = " << t << "\n";
170  return false;
171  }
172 
173  rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4(),
174  RT_POINT | RT_KEEP_ORIG, t, LVecBase4(),
175  RT_TANGENT, t, LVecBase4(tx, ty, tz, 0.0f),
176  RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4());
177  return true;
178 }
179 
180 ////////////////////////////////////////////////////////////////////
181 // Function: PiecewiseCurve::adjust_pt
182 // Access: Published, Virtual
183 // Description: Recomputes the curve such that it passes through the
184 // point (px, py, pz) with the tangent (tx, ty, tz).
185 ////////////////////////////////////////////////////////////////////
186 bool PiecewiseCurve::
187 adjust_pt(PN_stdfloat t,
188  PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz,
189  PN_stdfloat tx, PN_stdfloat ty, PN_stdfloat tz) {
190  const ParametricCurve *curve;
191  bool result = find_curve(curve, t);
192 
193  if (!result) {
194  cerr << "No curve segment at t = " << t << "\n";
195  return false;
196  }
197 
198  rebuild_curveseg(RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4(),
199  RT_POINT, t, LVecBase4(px, py, pz, 1.0f),
200  RT_TANGENT, t, LVecBase4(tx, ty, tz, 0.0f),
201  RT_CV | RT_KEEP_ORIG, 0.0f, LVecBase4());
202  return true;
203 }
204 
205 
206 ////////////////////////////////////////////////////////////////////
207 // Function: PiecewiseCurve::get_pt
208 // Access: Published, Virtual
209 // Description: Simultaneously returns the point and tangent of the
210 // curve at a given parametric point t.
211 ////////////////////////////////////////////////////////////////////
212 bool PiecewiseCurve::
213 get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent) const {
214  const ParametricCurve *curve;
215  bool result = find_curve(curve, t);
216 
217  // We use | instead of || so we won't short-circuit this calculation.
218  return result | curve->get_pt(t, point, tangent);
219 }
220 
221 
222 ////////////////////////////////////////////////////////////////////
223 // Function: PiecewiseCurve::get_num_segs
224 // Access: Public
225 // Description: Returns the number of curve segments that make up the
226 // Piecewise curve.
227 ////////////////////////////////////////////////////////////////////
229 get_num_segs() const {
230  return _segs.size();
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: PiecewiseCurve::get_curveseg
235 // Access: Public
236 // Description: Returns the curve segment corresponding to the given
237 // index.
238 ////////////////////////////////////////////////////////////////////
240 get_curveseg(int ti) {
241  assert(ti >= 0 && ti < (int)_segs.size());
242  return _segs[ti]._curve;
243 }
244 
245 
246 ////////////////////////////////////////////////////////////////////
247 // Function: PiecewiseCurve::insert_curveseg
248 // Access: Public
249 // Description: Inserts a new curve segment at the indicated index.
250 // The curve segment must have been allocated via
251 // new; it will be freed using delete when it is removed
252 // or the PiecewiseCurve destructs.
253 //
254 // If the curve segment is not inserted at the end, its
255 // tlength is subtracted from that of the following
256 // segment, so that the overall length of the curve is
257 // not changed.
258 ////////////////////////////////////////////////////////////////////
259 bool PiecewiseCurve::
260 insert_curveseg(int ti, ParametricCurve *seg, PN_stdfloat tlength) {
261  if (ti < 0 || ti > (int)_segs.size()) {
262  return false;
263  }
264 
265  if (ti == (int)_segs.size()) {
266  _segs.push_back(Curveseg(seg, get_max_t() + tlength));
267 
268  } else if (ti==0) {
269  _segs.insert(_segs.begin(),
270  Curveseg(seg, tlength));
271 
272  } else {
273  _segs.insert(_segs.begin() + ti,
274  Curveseg(seg, _segs[ti-1]._tend + tlength));
275  }
276 
277  return true;
278 }
279 
280 
281 ////////////////////////////////////////////////////////////////////
282 // Function: PiecewiseCurve::remove_curveseg
283 // Access: Public
284 // Description: Removes the given curve segment from the curve and
285 // frees it. Returns true if the segment was defined,
286 // false otherwise.
287 ////////////////////////////////////////////////////////////////////
288 bool PiecewiseCurve::
290  if (ti < 0 || ti >= (int)_segs.size()) {
291  return false;
292  }
293 
294  PN_stdfloat tlength = get_tlength(ti);
295  _segs.erase(_segs.begin() + ti);
296 
297  // Now update the _tend figures for everything after the one we
298  // removed.
299  while (ti < (int)_segs.size()) {
300  _segs[ti]._tend -= tlength;
301  ti++;
302  }
303 
304  _last_ti = 0;
305  return true;
306 }
307 
308 ////////////////////////////////////////////////////////////////////
309 // Function: PiecewiseCurve::remove_all_curvesegs
310 // Access: Public
311 // Description: Removes all curve segments from the curve.
312 ////////////////////////////////////////////////////////////////////
313 void PiecewiseCurve::
315  _segs.erase(_segs.begin(), _segs.end());
316  _last_ti = 0;
317 }
318 
319 ////////////////////////////////////////////////////////////////////
320 // Function: PiecewiseCurve::get_tlength
321 // Access: Public
322 // Description: Returns the parametric length of the given segment of
323 // the curve.
324 ////////////////////////////////////////////////////////////////////
325 PN_stdfloat PiecewiseCurve::
326 get_tlength(int ti) const {
327  assert(ti >= 0 && ti < (int)_segs.size());
328  return (ti==0) ? _segs[ti]._tend : _segs[ti]._tend - _segs[ti-1]._tend;
329 }
330 
331 ////////////////////////////////////////////////////////////////////
332 // Function: PiecewiseCurve::get_tstart
333 // Access: Public
334 // Description: Returns the parametric start of the given segment of
335 // the curve.
336 ////////////////////////////////////////////////////////////////////
337 PN_stdfloat PiecewiseCurve::
338 get_tstart(int ti) const {
339  assert(ti >= 0 && ti <= (int)_segs.size());
340  return (ti==0) ? 0.0f : _segs[ti-1]._tend;
341 }
342 
343 ////////////////////////////////////////////////////////////////////
344 // Function: PiecewiseCurve::get_tend
345 // Access: Public
346 // Description: Returns the parametric end of the given segment of
347 // the curve.
348 ////////////////////////////////////////////////////////////////////
349 PN_stdfloat PiecewiseCurve::
350 get_tend(int ti) const {
351  assert(ti >= 0 && ti < (int)_segs.size());
352  return _segs[ti]._tend;
353 }
354 
355 
356 ////////////////////////////////////////////////////////////////////
357 // Function: PiecewiseCurve::set_tlength
358 // Access: Public
359 // Description: Sets the parametric length of the given segment of
360 // the curve. The length of the following segment is
361 // lengthened by the corresponding amount to keep the
362 // overall length of the curve the same.
363 ////////////////////////////////////////////////////////////////////
364 bool PiecewiseCurve::
365 set_tlength(int ti, PN_stdfloat tlength) {
366  if (ti < 0 || ti >= (int)_segs.size()) {
367  return false;
368  }
369 
370  _segs[ti]._tend += tlength - get_tlength(ti);
371  return true;
372 }
373 
374 
375 
376 ////////////////////////////////////////////////////////////////////
377 // Function: PiecewiseCurve::make_nurbs
378 // Access: Public
379 // Description: Defines the curve as a general NURBS curve. The
380 // order is the degree plus one and must be 1, 2, 3, or
381 // 4; cvs is an array of num_cvs points each with a
382 // homogeneous coordinate; knots is an array of
383 // num_cvs+order knot values.
384 //
385 // This creates the individual curve segments and sets
386 // up the basis matrices, but does not store the CV's or
387 // knot values so the curve shape is not later
388 // modifiable.
389 ////////////////////////////////////////////////////////////////////
390 void PiecewiseCurve::
391 make_nurbs(int order, int num_cvs,
392  const PN_stdfloat knots[], const LVecBase4 cvs[]) {
394 
395  for (int i=0; i<num_cvs - order + 1; i++) {
396  if (knots[i+order] > knots[i+order-1]) {
397  int ti = get_num_segs();
398  bool result =
399  insert_curveseg(ti, new CubicCurveseg(order, knots+i, cvs+i),
400  knots[i+order] - knots[i+order-1]);
401  assert(result);
402  }
403  }
404 }
405 
406 
407 ////////////////////////////////////////////////////////////////////
408 // Function: PiecewiseCurve::get_bezier_segs
409 // Access: Public, Virtual
410 // Description: Fills up the indicated vector with a list of
411 // BezierSeg structs that describe the curve. This
412 // assumes the curve is a PiecewiseCurve of
413 // CubicCurvesegs. Returns true if successful, false
414 // otherwise.
415 ////////////////////////////////////////////////////////////////////
416 bool PiecewiseCurve::
417 get_bezier_segs(BezierSegs &bz_segs) const {
418  bz_segs.erase(bz_segs.begin(), bz_segs.end());
419  int i;
420  BezierSeg seg;
421  for (i = 0; i < (int)_segs.size(); i++) {
422  if (!_segs[i]._curve->get_bezier_seg(seg)) {
423  return false;
424  }
425  seg._t = _segs[i]._tend;
426  bz_segs.push_back(seg);
427  }
428 
429  return true;
430 }
431 
432 ////////////////////////////////////////////////////////////////////
433 // Function: PiecewiseCurve::rebuild_curveseg
434 // Access: Public, Virtual
435 // Description: Rebuilds the current curve segment (as selected by
436 // the most recent call to find_curve()) according to
437 // the specified properties (see
438 // CubicCurveseg::compute_seg). Returns true if
439 // possible, false if something goes horribly wrong.
440 ////////////////////////////////////////////////////////////////////
441 bool PiecewiseCurve::
442 rebuild_curveseg(int, PN_stdfloat, const LVecBase4 &,
443  int, PN_stdfloat, const LVecBase4 &,
444  int, PN_stdfloat, const LVecBase4 &,
445  int, PN_stdfloat, const LVecBase4 &) {
446  cerr << "rebuild_curveseg not implemented for this curve type.\n";
447  return false;
448 }
449 
450 ////////////////////////////////////////////////////////////////////
451 // Function: PiecewiseCurve::find_curve
452 // Access: Protected
453 // Description: Finds the curve corresponding to the given value of
454 // t. If t is inside the curve's defined range, sets
455 // curve to the appropriate segment, translates t to
456 // [0,1] to index into the segment's coordinate system,
457 // and returns true. If t is outside the curve's
458 // defined range, sets curve to the nearest segment and
459 // t to the nearest point on this segment, and returns
460 // false.
461 ////////////////////////////////////////////////////////////////////
462 bool PiecewiseCurve::
463 find_curve(const ParametricCurve *&curve, PN_stdfloat &t) const {
464  // Check the index computed by the last call to find_curve(). If
465  // it's still a reasonable starting value, start searching from
466  // there. This way, we take advantage of locality of reference: the
467  // search is trivial it is the same segment as last time, or the
468  // next segment after the last one.
469  if (_last_ti>0 && _segs[_last_ti-1]._tend>=t) {
470  // However, if the new t value precedes that of last time, we'll
471  // have to start over.
472 
473  // We do some messy casting so we can get away with assigning a
474  // value to a member within a const function. This assignment
475  // doesn't really count as a const violation since we're just
476  // updating a cached value, not changing any real data of the
477  // class.
478  ((PiecewiseCurve *)this)->_last_ti = 0;
479  }
480 
481  int ti;
482  for (ti = _last_ti; ti < (int)_segs.size(); ti++) {
483  if (_segs[ti]._tend+0.00001f > t) {
484  break;
485  }
486  }
487 
488  if (ti < (int)_segs.size()) {
489  // Adjust t to the range [0,1).
490  if (ti > 0) {
491  t = (t - _segs[ti-1]._tend) / (_segs[ti]._tend - _segs[ti-1]._tend);
492  } else {
493  t /= _segs[0]._tend;
494  }
495  }
496 
497  if (t < 0) {
498  // Oops.
499  curve = _segs[0]._curve;
500  t = 0.0f;
501  return false;
502  }
503 
504  if (ti >= (int)_segs.size() || !_segs[ti]._curve->is_valid()) {
505  assert(ti <= (int)_segs.size());
506 
507  // If we're out of bounds, or the curve is undefined, we're probably
508  // screwed. There's one exception: if we were right on a border between
509  // curves, try the curve before.
510 
511  if (ti > 0 && t < _segs[ti-1]._tend+0.0001f) {
512  ti--;
513  t = 1.0f;
514  }
515 
516  if (ti >= (int)_segs.size()) {
517  if (_segs.empty()) {
518  curve = NULL;
519  t = 0.0f;
520  return false;
521  } else {
522  curve = _segs.back()._curve;
523  t = 1.0f;
524  return false;
525  }
526  } else if (!_segs[ti]._curve->is_valid()) {
527  curve = _segs[ti]._curve;
528  return false;
529  }
530  }
531 
532  // Again, some messy casting so we can get away with updating the
533  // cached index value for next time.
534  ((PiecewiseCurve *)this)->_last_ti = ti;
535 
536  // Now scale t back into the curve's own valid range.
537  t *= _segs[ti]._curve->get_max_t();
538  curve = _segs[ti]._curve;
539  return true;
540 }
541 
542 
543 ////////////////////////////////////////////////////////////////////
544 // Function: PiecewiseCurve::current_seg_range
545 // Access: Protected
546 // Description: Returns a number in the range [0,1], representing the
547 // conversion of t into the current segment's coordinate
548 // system (the segment last returned by find_curve).
549 // This operation is already performed automatically on
550 // the t passed into find_seg; this function is useful
551 // only to adjust a different value into the same range.
552 //
553 // It is an error to call this function if find_curve()
554 // has not yet been called, or if find_curve() returned
555 // false from its previous call.
556 ////////////////////////////////////////////////////////////////////
557 PN_stdfloat PiecewiseCurve::
558 current_seg_range(PN_stdfloat t) const {
559  int ti = _last_ti;
560 
561  assert(ti < (int)_segs.size());
562 
563  // Adjust t to the range [0,1).
564  if (ti > 0) {
565  t = (t - _segs[ti-1]._tend) / (_segs[ti]._tend - _segs[ti-1]._tend);
566  } else {
567  t /= _segs[0]._tend;
568  }
569 
570  return t;
571 }
572 
573 ////////////////////////////////////////////////////////////////////
574 // Function: PiecewiseCurve::write_datagram
575 // Access: Protected, Virtual
576 // Description: Function to write the important information in
577 // the particular object to a Datagram
578 ////////////////////////////////////////////////////////////////////
579 void PiecewiseCurve::
580 write_datagram(BamWriter *manager, Datagram &me) {
581  ParametricCurve::write_datagram(manager, me);
582 
583  me.add_uint32(_segs.size());
584  size_t i;
585  for (i = 0; i < _segs.size(); i++) {
586  const Curveseg &seg = _segs[i];
587  manager->write_pointer(me, seg._curve);
588  me.add_float64(seg._tend);
589  }
590 
591  _last_ti = 0;
592 }
593 
594 ////////////////////////////////////////////////////////////////////
595 // Function: PiecewiseCurve::fillin
596 // Access: Protected
597 // Description: Function that reads out of the datagram (or asks
598 // manager to read) all of the data that is needed to
599 // re-create this object and stores it in the appropiate
600 // place
601 ////////////////////////////////////////////////////////////////////
602 void PiecewiseCurve::
603 fillin(DatagramIterator &scan, BamReader *manager) {
604  ParametricCurve::fillin(scan, manager);
605 
606  size_t num_segs = scan.get_uint32();
607  _segs.reserve(num_segs);
608  size_t i;
609  for (i = 0; i < num_segs; i++) {
610  Curveseg seg;
611  manager->read_pointer(scan);
612  seg._curve = (ParametricCurve *)NULL;
613  seg._tend = scan.get_float64();
614  _segs.push_back(seg);
615  }
616 }
617 
618 ////////////////////////////////////////////////////////////////////
619 // Function: PiecewiseCurve::complete_pointers
620 // Access: Protected, Virtual
621 // Description: Takes in a vector of pointes to TypedWritable
622 // objects that correspond to all the requests for
623 // pointers that this object made to BamReader.
624 ////////////////////////////////////////////////////////////////////
625 int PiecewiseCurve::
626 complete_pointers(TypedWritable **p_list, BamReader *manager) {
627  int used = ParametricCurve::complete_pointers(p_list, manager);
628 
629  size_t i;
630  for (i = 0; i < _segs.size(); i++) {
631  _segs[i]._curve = DCAST(ParametricCurve, p_list[used + i]);
632  }
633 
634  return used + _segs.size();
635 }
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
ParametricCurve * get_curveseg(int ti)
Returns the curve segment corresponding to the given index.
void remove_all_curvesegs()
Removes all curve segments from the curve.
void add_float64(PN_float64 value)
Adds a 64-bit floating-point number to the datagram.
Definition: datagram.I:228
virtual bool adjust_point(PN_stdfloat t, PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz)
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.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
A virtual base class for parametric curves.
bool insert_curveseg(int ti, ParametricCurve *seg, PN_stdfloat tlength)
Inserts a new curve segment at the indicated index.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
virtual bool is_valid() const
Returns true if the curve is defined.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
virtual bool adjust_tangent(PN_stdfloat t, PN_stdfloat tx, PN_stdfloat ty, PN_stdfloat tz)
Recomputes the curve such that it has the tangent (tx, ty, tz) at time t, but keeps the same position...
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors...
Definition: cubicCurveseg.h:58
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
virtual bool get_point(PN_stdfloat t, LVecBase3 &point) const
Returns the point of the curve at a given parametric point t.
virtual PN_stdfloat get_max_t() const
Returns the upper bound of t for the entire curve.
A PiecewiseCurve is a curve made up of several curve segments, connected in a head-to-tail fashion...
PN_stdfloat get_tend(int ti) const
Returns the parametric end of the given segment of the curve.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager-&gt;read_pointer() was called in fillin()...
PN_stdfloat get_tstart(int ti) const
Returns the parametric start of the given segment of the curve.
virtual bool get_bezier_segs(BezierSegs &bz_segs) const
Fills up the indicated vector with a list of BezierSeg structs that describe the curve.
virtual bool adjust_pt(PN_stdfloat t, PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat tx, PN_stdfloat ty, PN_stdfloat tz)
Recomputes the curve such that it passes through the point (px, py, pz) with the tangent (tx...
bool set_tlength(int ti, PN_stdfloat tlength)
Sets the parametric length of the given segment of the curve.
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
PN_float64 get_float64()
Extracts a 64-bit floating-point number.
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
virtual bool get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent) const
Simultaneously returns the point and tangent of the curve at a given parametric point t...
virtual bool get_tangent(PN_stdfloat t, LVecBase3 &tangent) const
Returns the tangent of the curve at a given parametric point t.
virtual bool get_2ndtangent(PN_stdfloat t, LVecBase3 &tangent2) const
Returns the tangent of the first derivative of the curve at the point t.
PN_stdfloat get_tlength(int ti) const
Returns the parametric length of the given segment of the curve.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void make_nurbs(int order, int num_cvs, const PN_stdfloat knots[], const LVecBase4 cvs[])
Defines the curve as a general NURBS curve.
bool remove_curveseg(int ti)
Removes the given curve segment from the curve and frees it.
virtual bool rebuild_curveseg(int rtype0, PN_stdfloat t0, const LVecBase4 &v0, int rtype1, PN_stdfloat t1, const LVecBase4 &v1, int rtype2, PN_stdfloat t2, const LVecBase4 &v2, int rtype3, PN_stdfloat t3, const LVecBase4 &v3)
Rebuilds the current curve segment (as selected by the most recent call to find_curve()) according to...
int get_num_segs() const
Returns the number of curve segments that make up the Piecewise curve.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:652