Panda3D
Loading...
Searching...
No Matches
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
27using std::ostream;
28using std::string;
29
30TypeHandle HermiteCurve::_type_handle;
31
32static 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 */
41static ostream &
42show_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 */
54HermiteCurveCV::
55HermiteCurveCV() {
56}
57
58
59/**
60 *
61 */
62HermiteCurveCV::
63HermiteCurveCV(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 */
73HermiteCurveCV::
74~HermiteCurveCV() {
75}
76
77
78
79/**
80 * Sets the CV's in tangent.
81 */
83set_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 */
107set_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 */
136set_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 */
157set_name(const string &name) {
158 _name = name;
159}
160
161
162/**
163 * Formats the CV for output to an egg file.
164 */
166format_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 */
214write_datagram(BamWriter *, Datagram &me) const {
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 */
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 */
240HermiteCurve::
241HermiteCurve() {
242}
243
244/**
245 * Constructs a Hermite from the indicated (possibly non-hermite) curve.
246 */
247HermiteCurve::
248HermiteCurve(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 */
260HermiteCurve::
261~HermiteCurve() {
262}
263
264
265
266
267
268
269/**
270 * Returns the number of CV's in the curve.
271 */
273get_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 */
290insert_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
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 =
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 */
325append_cv(int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
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 */
350remove_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 */
371 _points.erase(_points.begin(), _points.end());
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 */
393set_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 */
414set_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 */
428set_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 */
442set_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 */
456set_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 */
473set_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 */
488get_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 */
500const LVecBase3 &HermiteCurve::
501get_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}
509get_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 */
517const LVecBase3 &HermiteCurve::
518get_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}
526get_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 */
534const LVecBase3 &HermiteCurve::
535get_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}
543get_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 */
551PN_stdfloat HermiteCurve::
552get_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 */
566get_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 */
578void HermiteCurve::
579output(ostream &out) const {
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 */
606void HermiteCurve::
607write_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 */
650rebuild_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 */
661bool HermiteCurve::
662format_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
716static void
717wrap_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 */
732void HermiteCurve::
733invalidate_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 */
775int HermiteCurve::
776find_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 */
795void HermiteCurve::
796recompute_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 */
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 */
826TypedWritable *HermiteCurve::
827make_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 */
841void HermiteCurve::
842write_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 */
857void HermiteCurve::
858fillin(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++) {
866 cv.fillin(scan, manager);
867 _points.push_back(cv);
868 }
869}
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors,...
void bezier_basis(const BezierSeg &seg)
Defines the curve segment as a Bezier.
void hermite_basis(const HermiteCurveCV &cv0, const HermiteCurveCV &cv1, PN_stdfloat tlength=1.0f)
Defines the curve segment as a Hermite.
A class to retrieve the individual data elements previously stored in a Datagram.
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
int8_t get_int8()
Extracts a signed 8-bit integer.
std::string get_string()
Extracts a variable-length string.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition datagram.I:94
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Definition datagram.I:219
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition datagram.I:42
An instance of this class is passed to the Factory when requesting it to do its business and construc...
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
A single CV of a Hermite curve.
void write_datagram(BamWriter *manager, Datagram &me) const
Function to write the important information in the particular object to a Datagram.
void set_in(const LVecBase3 &in)
Sets the CV's in tangent.
void set_type(int type)
Sets the continuity type of the CV.
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.
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...
void set_out(const LVecBase3 &out)
Sets the CV's out tangent.
void set_name(const std::string &name)
Sets the name associated with the CV.
A parametric curve defined by a sequence of control vertices, each with an in and out tangent.
int append_cv(int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Adds a new CV to the end of the curve.
PN_stdfloat get_cv_tstart(int n) const
Returns the starting point in parametric space of the given CV.
bool set_cv_out(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's out tangent.
bool set_cv_tstart(int n, PN_stdfloat tstart)
Changes the given CV's parametric starting time.
const LVecBase3 & get_cv_point(int n) const
Returns the position of the given CV.
bool set_cv_name(int n, const char *name)
Changes the name associated with a particular CV.
int insert_cv(PN_stdfloat t)
Inserts a new CV at the given parametric point along the curve.
const LVecBase3 & get_cv_out(int n) const
Returns the out tangent of the given CV.
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.
std::string get_cv_name(int n) const
Returns the name of the given CV, or NULL.
bool set_cv_in(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's in tangent.
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...
void remove_all_cvs()
Removes all CV's from the curve.
bool remove_cv(int n)
Removes the given CV from the curve.
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
bool set_cv_type(int n, int type)
Changes the given CV's continuity type.
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...
const LVecBase3 & get_cv_in(int n) const
Returns the in tangent of the given CV.
void output(std::ostream &out) const
Outputs the Namable.
Definition namable.I:61
A virtual base class for parametric curves.
int get_curve_type() const
Returns the flag indicating the use to which the curve is intended to be put.
virtual bool convert_to_hermite(HermiteCurve *hc) const
Stores an equivalent curve representation in the indicated Hermite curve, if possible.
void remove_all_curvesegs()
Removes all curve segments from the curve.
bool insert_curveseg(int ti, ParametricCurve *seg, PN_stdfloat tlength)
Inserts a new curve segment at the indicated index.
virtual bool is_valid() const
Returns true if the curve is defined.
PN_stdfloat get_tlength(int ti) const
Returns the parametric length of the given segment of the curve.
bool set_tlength(int ti, PN_stdfloat tlength)
Sets the parametric length of the given segment of the curve.
virtual PN_stdfloat get_max_t() const
Returns the upper bound of t for the entire curve.
bool remove_curveseg(int ti)
Removes the given curve segment from the curve and frees it.
PN_stdfloat get_tstart(int ti) const
Returns the parametric start of the given segment of the curve.
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.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.