Panda3D
hermiteCurve.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file hermiteCurve.cxx
10  * @author drose
11  * @date 1998-02-27
12  */
13 
14 #include "pandabase.h"
15 #include "hermiteCurve.h"
16 #include "config_parametrics.h"
17 #include "luse.h"
18 
19 #include "indent.h"
20 #include "datagram.h"
21 #include "datagramIterator.h"
22 #include "bamWriter.h"
23 #include "bamReader.h"
24 
25 #include <math.h>
26 
27 using std::ostream;
28 using std::string;
29 
30 TypeHandle HermiteCurve::_type_handle;
31 
32 static const LVecBase3 zerovec_3 = LVecBase3(0.0f, 0.0f, 0.0f);
33 // This is returned occasionally from some of the functions, and is used from
34 // time to time as an initializer.
35 
36 
37 /**
38  * This function writes a LVecBase3, with a specified number of significant
39  * dimensions.
40  */
41 static ostream &
42 show_vec3(ostream &out, int indent_level, const LVecBase3 &v,
43  int num_dimensions) {
44  indent(out, indent_level) << v[0];
45  for (int i = 1; i<num_dimensions; i++) {
46  out << " " << v[i];
47  }
48  return out;
49 }
50 
51 /**
52  *
53  */
54 HermiteCurveCV::
55 HermiteCurveCV() {
56 }
57 
58 
59 /**
60  *
61  */
62 HermiteCurveCV::
63 HermiteCurveCV(const HermiteCurveCV &c) :
64  _p(c._p), _in(c._in), _out(c._out),
65  _type(c._type), _name(c._name)
66 {
67 }
68 
69 
70 /**
71  *
72  */
73 HermiteCurveCV::
74 ~HermiteCurveCV() {
75 }
76 
77 
78 
79 /**
80  * Sets the CV's in tangent.
81  */
83 set_in(const LVecBase3 &in) {
84  _in = in;
85  /*
86  PN_stdfloat l;
87  switch (_type) {
88  case HC_G1:
89  l = _in.length();
90  if (l!=0.0f) {
91  _out = _in * _out.length() / l;
92  }
93  break;
94 
95  case HC_SMOOTH:
96  _out = _in;
97  break;
98  }
99  */
100 }
101 
102 
103 /**
104  * Sets the CV's out tangent.
105  */
106 void HermiteCurveCV::
107 set_out(const LVecBase3 &out) {
108  _out = out;
109  /*
110  PN_stdfloat l;
111  switch (_type) {
112  case HC_G1:
113  l = _out.length();
114  if (l!=0.0f) {
115  _in = _out * _in.length() / l;
116  }
117  break;
118 
119  case HC_SMOOTH:
120  _in = _out;
121  break;
122  }
123  */
124 }
125 
126 
127 /**
128  * Sets the continuity type of the CV. Values may be HC_CUT, indicating a
129  * discontinous break in the curve, HC_FREE, for unconstrained in and out
130  * tangents, HC_G1, for in and out tangents constrained to be collinear, and
131  * HC_SMOOTH, for in and out tangents constrained to be equal. Other than
132  * HC_CUT, these are for documentation only; setting this has no direct effect
133  * on the tangents.
134  */
135 void HermiteCurveCV::
136 set_type(int type) {
137  _type = type;
138  /*
139  switch (_type) {
140  case HC_G1:
141  _out = _out.length() * _in;
142  break;
143 
144  case HC_SMOOTH:
145  _out = _in;
146  break;
147  }
148  */
149 }
150 
151 
152 
153 /**
154  * Sets the name associated with the CV.
155  */
156 void HermiteCurveCV::
157 set_name(const string &name) {
158  _name = name;
159 }
160 
161 
162 /**
163  * Formats the CV for output to an egg file.
164  */
165 void HermiteCurveCV::
166 format_egg(ostream &out, int indent_level, int num_dimensions,
167  bool show_in, bool show_out,
168  PN_stdfloat scale_in, PN_stdfloat scale_out) const {
169  if (show_in) {
170  indent(out, indent_level) << "<Vertex> {\n";
171  show_vec3(out, indent_level + 2, _p - scale_in * _in / 3.0,
172  num_dimensions) << "\n";
173  indent(out, indent_level) << "}\n";
174  }
175 
176  indent(out, indent_level) << "<Vertex> {\n";
177  show_vec3(out, indent_level + 2, _p, num_dimensions) << "\n";
178 
179  indent(out, indent_level+2) << "<Scalar> continuity-type { ";
180  switch (_type) {
181  case HC_CUT:
182  out << "Cut";
183  break;
184 
185  case HC_FREE:
186  out << "Free";
187  break;
188 
189  case HC_G1:
190  out << "G1";
191  break;
192 
193  case HC_SMOOTH:
194  out << "Smooth";
195  break;
196  };
197  out << " }\n";
198 
199  indent(out, indent_level) << "}\n";
200 
201  if (show_out) {
202  indent(out, indent_level) << "<Vertex> {\n";
203  show_vec3(out, indent_level + 2, _p + scale_out * _out / 3.0,
204  num_dimensions) << "\n";
205  indent(out, indent_level) << "}\n";
206  }
207 }
208 
209 /**
210  * Function to write the important information in the particular object to a
211  * Datagram
212  */
213 void HermiteCurveCV::
215  _p.write_datagram(me);
216  _in.write_datagram(me);
217  _out.write_datagram(me);
218  me.add_int8(_type);
219  me.add_string(_name);
220 }
221 
222 /**
223  * Function that reads out of the datagram (or asks manager to read) all of
224  * the data that is needed to re-create this object and stores it in the
225  * appropiate place
226  */
227 void HermiteCurveCV::
229  _p.read_datagram(scan);
230  _in.read_datagram(scan);
231  _out.read_datagram(scan);
232 
233  _type = scan.get_int8();
234  _name = scan.get_string();
235 }
236 
237 /**
238  *
239  */
240 HermiteCurve::
241 HermiteCurve() {
242 }
243 
244 /**
245  * Constructs a Hermite from the indicated (possibly non-hermite) curve.
246  */
247 HermiteCurve::
248 HermiteCurve(const ParametricCurve &nc) {
249  if (!nc.convert_to_hermite(this)) {
250  parametrics_cat->warning()
251  << "Cannot make a Hermite from the indicated curve."
252  << std::endl;
253  }
254 }
255 
256 
257 /**
258  *
259  */
260 HermiteCurve::
261 ~HermiteCurve() {
262 }
263 
264 
265 
266 
267 
268 
269 /**
270  * Returns the number of CV's in the curve.
271  */
272 int HermiteCurve::
273 get_num_cvs() const {
274  return _points.size();
275 }
276 
277 
278 /**
279  * Inserts a new CV at the given parametric point along the curve. If this
280  * parametric point is already on the curve, the CV is assigned an index
281  * between its two neighbors and the indices of all following CV's are
282  * incremented by 1; its in and out tangents are chosen to keep the curve
283  * consistent. If the new parametric point is beyond the end of the existing
284  * curve, the curve is extended to meet it and the new CV's position, in
285  * tangent, and out tangent are set to zero.
286  *
287  * The index number of the new CV is returned.
288  */
289 int HermiteCurve::
290 insert_cv(PN_stdfloat t) {
291  if (!is_valid() || t >= get_max_t()) {
292  int n = append_cv(HC_SMOOTH, 0.0f, 0.0f, 0.0f);
293  set_cv_tstart(n, t);
294  return n;
295  }
296 
297  t = std::min(std::max(t, (PN_stdfloat)0.0), get_max_t());
298 
299  int n = find_cv(t);
300  nassertr(n+1<get_num_cvs(), 0);
301 
302  HermiteCurveCV cv;
303  LVecBase3 tan;
304  cv._type = HC_SMOOTH;
305  get_pt(t, cv._p, tan);
306  cv._out = cv._in = tan * 0.5f;
307 
308  _points.insert(_points.begin() + n + 1, cv);
309  bool result =
310  insert_curveseg(n, new CubicCurveseg, t - get_cv_tstart(n));
311  nassertr(result, 0);
312 
313  recompute_basis();
314  invalidate_all();
315 
316  return n + 1;
317 }
318 
319 
320 /**
321  * Adds a new CV to the end of the curve. The new CV is given initial in/out
322  * tangents of 0. The return value is the index of the new CV.
323  */
324 int HermiteCurve::
325 append_cv(int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
326  HermiteCurveCV cv;
327  cv.set_type(type);
328  cv.set_point(LVecBase3(x, y, z));
329  cv.set_in(zerovec_3);
330  cv.set_out(zerovec_3);
331  _points.push_back(cv);
332  if (_points.size()>1) {
333  bool result =
334  insert_curveseg(_segs.size(), new CubicCurveseg, 1.0f);
335  nassertr(result, 0);
336  }
337 
338  recompute_basis();
339  invalidate_all();
340 
341  return _points.size()-1;
342 }
343 
344 
345 /**
346  * Removes the given CV from the curve. Returns true if the CV existed, false
347  * otherwise.
348  */
349 bool HermiteCurve::
350 remove_cv(int n) {
351  if (n < 0 || n >= (int)_points.size()) {
352  return false;
353  }
354 
355  _points.erase(_points.begin() + n);
356  if (_segs.size()>0) {
357  remove_curveseg(_segs.size()-1);
358  }
359 
360  recompute_basis();
361  invalidate_all();
362  return true;
363 }
364 
365 
366 /**
367  * Removes all CV's from the curve.
368  */
369 void HermiteCurve::
371  _points.erase(_points.begin(), _points.end());
372  remove_all_curvesegs();
373 
374  invalidate_all();
375 }
376 
377 
378 
379 
380 /**
381  * Changes the given CV's continuity type. Legal values are HC_CUT, HC_FREE,
382  * HC_G1, or HC_SMOOTH.
383  *
384  * Other than HC_CUT, these have no effect on the actual curve; it remains up
385  * to user software to impose the constraints these imply.
386  *
387  * HC_CUT implies a disconnection of the curve; HC_FREE imposes no constraints
388  * on the tangents; HC_G1 forces the tangents to be collinear, and HC_SMOOTH
389  * forces the tangents to be identical. Setting type type to HC_G1 or
390  * HC_SMOOTH may adjust the out tangent to match the in tangent.
391  */
392 bool HermiteCurve::
393 set_cv_type(int n, int type) {
394  if (n < 0 || n >= (int)_points.size()) {
395  return false;
396  }
397 
398  bool changed_cut = false;
399 
400  if (type!=_points[n]._type) {
401  changed_cut = (type==HC_CUT || _points[n]._type==HC_CUT);
402  _points[n].set_type(type);
403  }
404 
405  invalidate_cv(n, changed_cut);
406  return true;
407 }
408 
409 
410 /**
411  * Changes the given CV's position.
412  */
413 bool HermiteCurve::
414 set_cv_point(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
415  if (n < 0 || n >= (int)_points.size()) {
416  return false;
417  }
418  _points[n].set_point(LVecBase3(x, y, z));
419  invalidate_cv(n, false);
420  return true;
421 }
422 
423 /**
424  * Changes the given CV's in tangent. Depending on the continuity type, this
425  * may also adjust the out tangent.
426  */
427 bool HermiteCurve::
428 set_cv_in(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
429  if (n < 0 || n >= (int)_points.size()) {
430  return false;
431  }
432  _points[n].set_in(LVecBase3(x, y, z));
433  invalidate_cv(n, false);
434  return true;
435 }
436 
437 /**
438  * Changes the given CV's out tangent. Depending on the continuity type, this
439  * may also adjust the in tangent.
440  */
441 bool HermiteCurve::
442 set_cv_out(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
443  if (n < 0 || n >= (int)_points.size()) {
444  return false;
445  }
446  _points[n].set_out(LVecBase3(x, y, z));
447  invalidate_cv(n, false);
448  return true;
449 }
450 
451 /**
452  * Changes the given CV's parametric starting time. This may affect the shape
453  * of the curve.
454  */
455 bool HermiteCurve::
456 set_cv_tstart(int n, PN_stdfloat tstart) {
457  if (n <= 0 || n >= (int)_points.size()) {
458  return false;
459  }
460  if (fabs(tstart - get_cv_tstart(n)) > 0.0001f) {
461  set_tlength(n-1, tstart - get_tstart(n-1));
462  recompute_basis();
463  invalidate_all();
464  }
465  return true;
466 }
467 
468 
469 /**
470  * Changes the name associated with a particular CV.
471  */
472 bool HermiteCurve::
473 set_cv_name(int n, const char *name) {
474  if (n < 0 || n >= (int)_points.size()) {
475  return false;
476  }
477  _points[n].set_name(name);
478  return true;
479 }
480 
481 
482 
483 /**
484  * Returns the given CV's continuity type, HC_CUT, HC_FREE, HC_G1, or
485  * HC_SMOOTH, or 0 if there is no such CV.
486  */
487 int HermiteCurve::
488 get_cv_type(int n) const {
489  if (n < 0 || n >= (int)_points.size()) {
490  return 0;
491  }
492 
493  return _points[n]._type;
494 }
495 
496 
497 /**
498  * Returns the position of the given CV.
499  */
500 const LVecBase3 &HermiteCurve::
501 get_cv_point(int n) const {
502  if (n < 0 || n >= (int)_points.size()) {
503  return zerovec_3;
504  }
505 
506  return _points[n]._p;
507 }
508 void HermiteCurve::
509 get_cv_point(int n, LVecBase3 &v) const {
510  v = get_cv_point(n);
511 }
512 
513 
514 /**
515  * Returns the in tangent of the given CV.
516  */
517 const LVecBase3 &HermiteCurve::
518 get_cv_in(int n) const {
519  if (n < 0 || n >= (int)_points.size() || _points[n-1]._type==HC_CUT) {
520  return zerovec_3;
521  }
522 
523  return _points[n]._in;
524 }
525 void HermiteCurve::
526 get_cv_in(int n, LVecBase3 &v) const {
527  v = get_cv_in(n);
528 }
529 
530 
531 /**
532  * Returns the out tangent of the given CV.
533  */
534 const LVecBase3 &HermiteCurve::
535 get_cv_out(int n) const {
536  if (n < 0 || n >= (int)_points.size() || _points[n]._type==HC_CUT) {
537  return zerovec_3;
538  }
539 
540  return _points[n]._out;
541 }
542 void HermiteCurve::
543 get_cv_out(int n, LVecBase3 &v) const {
544  v = get_cv_out(n);
545 }
546 
547 
548 /**
549  * Returns the starting point in parametric space of the given CV.
550  */
551 PN_stdfloat HermiteCurve::
552 get_cv_tstart(int n) const {
553  if (n<0) {
554  return 0.0f;
555  } else if (n >= (int)_points.size()) {
556  return get_max_t();
557  }
558 
559  return get_tstart(n);
560 }
561 
562 /**
563  * Returns the name of the given CV, or NULL.
564  */
565 string HermiteCurve::
566 get_cv_name(int n) const {
567  if (n < 0 || n >= (int)_points.size()) {
568  return string();
569  }
570 
571  return _points[n]._name;
572 }
573 
574 
575 /**
576  *
577  */
578 void HermiteCurve::
579 output(ostream &out) const {
580  PiecewiseCurve::output(out);
581 
582  out << " (";
583  switch (get_curve_type()) {
584  case PCT_T:
585  out << "in T, ";
586  break;
587 
588  case PCT_XYZ:
589  out << "in XYZ, ";
590  break;
591 
592  case PCT_HPR:
593  out << "in HPR, ";
594  break;
595 
596  default:
597  break;
598  }
599 
600  out << get_num_cvs() << " CV's)";
601 }
602 
603 /**
604  *
605  */
606 void HermiteCurve::
607 write_cv(ostream &out, int n) const {
608  out << "CV";
609  if (!get_cv_name(n).empty()) {
610  out << " " << get_cv_name(n);
611  }
612 
613  out << " at t = " << get_cv_tstart(n)
614  << "\npoint = " << get_cv_point(n)
615  << "\nin = " << get_cv_in(n) << " out = " << get_cv_out(n)
616  << "\ncontinuity type = ";
617 
618  switch (get_cv_type(n)) {
619  case HC_CUT:
620  out << "Cut";
621  break;
622 
623  case HC_FREE:
624  out << "Free";
625  break;
626 
627  case HC_G1:
628  out << "G1";
629  break;
630 
631  case HC_SMOOTH:
632  out << "Smooth";
633  break;
634 
635  default:
636  break;
637  }
638 
639  out << "\n";
640 }
641 
642 
643 /**
644  * Rebuilds the current curve segment (as selected by the most recent call to
645  * find_curve()) according to the specified properties (see
646  * CubicCurveseg::compute_seg). Returns true if possible, false if something
647  * goes horribly wrong.
648  */
649 bool HermiteCurve::
650 rebuild_curveseg(int, PN_stdfloat, const LVecBase4 &,
651  int, PN_stdfloat, const LVecBase4 &,
652  int, PN_stdfloat, const LVecBase4 &,
653  int, PN_stdfloat, const LVecBase4 &) {
654  std::cerr << "rebuild_curveseg not implemented for this curve type.\n";
655  return false;
656 }
657 
658 /**
659  * Formats the Hermite curve for output to an Egg file.
660  */
661 bool HermiteCurve::
662 format_egg(ostream &out, const string &name, const string &curve_type,
663  int indent_level) const {
664  indent(out, indent_level)
665  << "<VertexPool> " << name << ".pool {\n";
666 
667  int i;
668  for (i = 0; i < (int)_points.size(); i++) {
669  bool show_in = (i != 0);
670  bool show_out = (i != (int)_points.size()-1);
671  _points[i].format_egg(out, indent_level + 2, _num_dimensions,
672  show_in, show_out,
673  show_in ? get_tlength(i-1) : 0.0f,
674  show_out ? get_tlength(i) : 0.0f);
675  }
676  indent(out, indent_level) << "}\n";
677 
678  indent(out, indent_level) << "<BezierCurve> " << name << " {\n";
679 
680  if (!curve_type.empty()) {
681  indent(out, indent_level+2)
682  << "<Scalar> type { " << curve_type << " }\n";
683  }
684 
685  indent(out, indent_level+2) << "<TLengths> {";
686  if (_points.size() > 1) {
687  for (i = 0; i < (int)_segs.size(); i++) {
688  if (i%10 == 1) {
689  out << "\n";
690  indent(out, indent_level+3);
691  }
692  out << " " << get_tlength(i);
693  }
694  }
695  out << "\n";
696  indent(out, indent_level+2) << "}\n";
697 
698  indent(out, indent_level+2) << "<VertexRef> {";
699  for (i = 1; i <= (int)_points.size() * 3 - 2; i++) {
700  if (i%10 == 1) {
701  out << "\n";
702  indent(out, indent_level+3);
703  }
704  out << " " << i;
705  }
706  out << "\n";
707  indent(out, indent_level+4) << "<Ref> { " << name << ".pool }\n";
708  indent(out, indent_level+2) << "}\n";
709 
710  indent(out, indent_level) << "}\n";
711 
712  return true;
713 }
714 
715 
716 static void
717 wrap_hpr(const LVecBase3 &hpr1, LVecBase3 &hpr2) {
718  for (int i = 0; i < 3; i++) {
719  while ((hpr2[i] - hpr1[i]) > 180.0) {
720  hpr2[i] -= 360.0;
721  }
722 
723  while ((hpr2[i] - hpr1[i]) < -180.0) {
724  hpr2[i] += 360.0;
725  }
726  }
727 }
728 
729 /**
730  * Recomputes the CV and its neighbors appropriately after a change.
731  */
732 void HermiteCurve::
733 invalidate_cv(int n, bool redo_all) {
734  PN_stdfloat t1 = 0.0f, t2 = get_max_t();
735  if (n>0 && _points[n-1]._type!=HC_CUT) {
736  const HermiteCurveCV &p1 = _points[n-1];
737  HermiteCurveCV p2(_points[n]);
738  if (_curve_type == PCT_HPR) {
739  wrap_hpr(p1._p, p2._p);
740  }
741  get_curveseg(n-1)->hermite_basis(p1, p2, get_tlength(n-1));
742  t1 = get_cv_tstart(n-1);
743  }
744 
745  if (n+1 < (int)_points.size()) {
746  if (_points[n]._type==HC_CUT) {
747  BezierSeg seg;
748  seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
749  get_curveseg(n)->bezier_basis(seg);
750  } else {
751  const HermiteCurveCV &p1 = _points[n];
752  HermiteCurveCV p2(_points[n+1]);
753  if (_curve_type == PCT_HPR) {
754  wrap_hpr(p1._p, p2._p);
755  }
756  get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
757  t2 = get_cv_tstart(n+2);
758  }
759  }
760 
761  if (is_valid()) {
762  if (redo_all) {
763  invalidate_all();
764  } else {
765  invalidate(t1, t2);
766  }
767  }
768 }
769 
770 
771 
772 /**
773  * Finds the CV immediately preceding the given value of t.
774  */
775 int HermiteCurve::
776 find_cv(PN_stdfloat t) {
777  nassertr(is_valid(), 0);
778 
779  int n;
780  for (n = 0; n < (int)_segs.size(); n++) {
781  if (_segs[n]._tend+0.00001 > t) {
782  break;
783  }
784  }
785 
786  return n;
787 }
788 
789 
790 /**
791  * Recomputes the coefficients for all the CV's in the curve. This is
792  * intended to be called whenever the CV's have been changed in some drastic
793  * way, and it's safest just to recompute everything.
794  */
795 void HermiteCurve::
796 recompute_basis() {
797  int n;
798  for (n = 0; n < (int)_segs.size(); n++) {
799  if (_points[n]._type==HC_CUT) {
800  BezierSeg seg;
801  seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
802  get_curveseg(n)->bezier_basis(seg);
803  } else {
804  const HermiteCurveCV &p1 = _points[n];
805  HermiteCurveCV p2(_points[n+1]);
806  if (_curve_type == PCT_HPR) {
807  wrap_hpr(p1._p, p2._p);
808  }
809  get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
810  }
811  }
812 }
813 
814 
815 /**
816  * Initializes the factory for reading these things from Bam files.
817  */
818 void HermiteCurve::
820  BamReader::get_factory()->register_factory(get_class_type(), make_HermiteCurve);
821 }
822 
823 /**
824  * Factory method to generate an object of this type.
825  */
826 TypedWritable *HermiteCurve::
827 make_HermiteCurve(const FactoryParams &params) {
828  HermiteCurve *me = new HermiteCurve;
829  DatagramIterator scan;
830  BamReader *manager;
831 
832  parse_params(params, scan, manager);
833  me->fillin(scan, manager);
834  return me;
835 }
836 
837 /**
838  * Function to write the important information in the particular object to a
839  * Datagram
840  */
841 void HermiteCurve::
842 write_datagram(BamWriter *manager, Datagram &me) {
843  PiecewiseCurve::write_datagram(manager, me);
844 
845  me.add_uint32(_points.size());
846  size_t i;
847  for (i = 0; i < _points.size(); i++) {
848  _points[i].write_datagram(manager, me);
849  }
850 }
851 
852 /**
853  * Function that reads out of the datagram (or asks manager to read) all of
854  * the data that is needed to re-create this object and stores it in the
855  * appropiate place
856  */
857 void HermiteCurve::
858 fillin(DatagramIterator &scan, BamReader *manager) {
859  PiecewiseCurve::fillin(scan, manager);
860 
861  size_t num_points = scan.get_uint32();
862  _points.reserve(num_points);
863  size_t i;
864  for (i = 0; i < num_points; i++) {
865  HermiteCurveCV cv;
866  cv.fillin(scan, manager);
867  _points.push_back(cv);
868  }
869 }
bool remove_cv(int n)
Removes the given CV from the curve.
void set_name(const std::string &name)
Sets the name associated with the CV.
PN_stdfloat get_cv_tstart(int n) const
Returns the starting point in parametric space of the given CV.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
A virtual base class for parametric curves.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int insert_cv(PN_stdfloat t)
Inserts a new CV at the given parametric point along the curve.
int get_cv_type(int n) const
Returns the given CV's continuity type, HC_CUT, HC_FREE, HC_G1, or HC_SMOOTH, or 0 if there is no suc...
bool set_cv_name(int n, const char *name)
Changes the name associated with a particular CV.
bool set_cv_out(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's out tangent.
void fillin(DatagramIterator &scan, BamReader *manager)
Function that reads out of the datagram (or asks manager to read) all of the data that is needed to r...
int append_cv(int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Adds a new CV to the end of the curve.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool convert_to_hermite(HermiteCurve *hc) const
Stores an equivalent curve representation in the indicated Hermite curve, if possible.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
bool set_cv_point(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's position.
int get_num_cvs() const
Returns the number of CV's in the curve.
void set_in(const LVecBase3 &in)
Sets the CV's in tangent.
A parametric curve defined by a sequence of control vertices, each with an in and out tangent.
Definition: hermiteCurve.h:83
std::string get_string()
Extracts a variable-length string.
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors,...
Definition: cubicCurveseg.h:50
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
std::string get_cv_name(int n) const
Returns the name of the given CV, or NULL.
void set_out(const LVecBase3 &out)
Sets the CV's out tangent.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition: datagram.I:42
void set_type(int type)
Sets the continuity type of the CV.
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
void remove_all_cvs()
Removes all CV's from the curve.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
void wrap_hpr()
Resets each HPR data point so that the maximum delta between any two consecutive points is 180 degree...
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:219
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
const LVecBase3 & get_cv_in(int n) const
Returns the in tangent of the given CV.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void format_egg(std::ostream &out, int indent, int num_dimensions, bool show_in, bool show_out, PN_stdfloat scale_in, PN_stdfloat scale_out) const
Formats the CV for output to an egg file.
bool set_cv_type(int n, int type)
Changes the given CV's continuity type.
const LVecBase3 & get_cv_point(int n) const
Returns the position of the given CV.
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...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
bool set_cv_tstart(int n, PN_stdfloat tstart)
Changes the given CV's parametric starting time.
A single CV of a Hermite curve.
Definition: hermiteCurve.h:50
A class to retrieve the individual data elements previously stored in a Datagram.
int8_t get_int8()
Extracts a signed 8-bit integer.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void write_datagram(BamWriter *manager, Datagram &me) const
Function to write the important information in the particular object to a Datagram.
bool set_cv_in(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's in tangent.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
const LVecBase3 & get_cv_out(int n) const
Returns the out tangent of the given CV.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.