15 #include "pandabase.h"
16 #include "hermiteCurve.h"
17 #include "config_parametrics.h"
22 #include "datagramIterator.h"
23 #include "bamWriter.h"
24 #include "bamReader.h"
41 show_vec3(ostream &out,
int indent_level,
const LVecBase3 &v,
43 indent(out, indent_level) << v[0];
44 for (
int i = 1; i<num_dimensions; i++) {
67 _p(c._p), _in(c._in), _out(c._out),
68 _type(c._type), _name(c._name)
183 format_egg(ostream &out,
int indent_level,
int num_dimensions,
184 bool show_in,
bool show_out,
185 PN_stdfloat scale_in, PN_stdfloat scale_out)
const {
187 indent(out, indent_level) <<
"<Vertex> {\n";
188 show_vec3(out, indent_level + 2, _p - scale_in * _in / 3.0,
189 num_dimensions) <<
"\n";
190 indent(out, indent_level) <<
"}\n";
193 indent(out, indent_level) <<
"<Vertex> {\n";
194 show_vec3(out, indent_level + 2, _p, num_dimensions) <<
"\n";
196 indent(out, indent_level+2) <<
"<Scalar> continuity-type { ";
216 indent(out, indent_level) <<
"}\n";
219 indent(out, indent_level) <<
"<Vertex> {\n";
220 show_vec3(out, indent_level + 2, _p + scale_out * _out / 3.0,
221 num_dimensions) <<
"\n";
222 indent(out, indent_level) <<
"}\n";
234 _p.write_datagram(me);
235 _in.write_datagram(me);
236 _out.write_datagram(me);
251 _p.read_datagram(scan);
252 _in.read_datagram(scan);
253 _out.read_datagram(scan);
277 parametrics_cat->warning()
278 <<
"Cannot make a Hermite from the indicated curve."
305 return _points.size();
327 if (!is_valid() || t >= get_max_t()) {
328 int n = append_cv(HC_SMOOTH, 0.0f, 0.0f, 0.0f);
333 t = min(max(t, (PN_stdfloat)0.0), get_max_t());
336 nassertr(n+1<get_num_cvs(), 0);
340 cv._type = HC_SMOOTH;
341 get_pt(t, cv._p, tan);
342 cv._out = cv._in = tan * 0.5f;
344 _points.insert(_points.begin() + n + 1, cv);
364 append_cv(
int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
370 _points.push_back(cv);
371 if (_points.size()>1) {
380 return _points.size()-1;
392 if (n < 0 || n >= (
int)_points.size()) {
396 _points.erase(_points.begin() + n);
397 if (_segs.size()>0) {
398 remove_curveseg(_segs.size()-1);
414 _points.erase(_points.begin(), _points.end());
415 remove_all_curvesegs();
442 if (n < 0 || n >= (
int)_points.size()) {
446 bool changed_cut =
false;
448 if (type!=_points[n]._type) {
449 changed_cut = (type==HC_CUT || _points[n]._type==HC_CUT);
450 _points[n].set_type(type);
453 invalidate_cv(n, changed_cut);
465 if (n < 0 || n >= (
int)_points.size()) {
468 _points[n].set_point(
LVecBase3(x, y, z));
469 invalidate_cv(n,
false);
481 set_cv_in(
int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
482 if (n < 0 || n >= (
int)_points.size()) {
486 invalidate_cv(n,
false);
498 set_cv_out(
int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
499 if (n < 0 || n >= (
int)_points.size()) {
503 invalidate_cv(n,
false);
515 if (n <= 0 || n >= (
int)_points.size()) {
518 if (fabs(tstart - get_cv_tstart(n)) > 0.0001f) {
519 set_tlength(n-1, tstart - get_tstart(n-1));
534 if (n < 0 || n >= (
int)_points.size()) {
537 _points[n].set_name(name);
552 if (n < 0 || n >= (
int)_points.size()) {
556 return _points[n]._type;
567 if (n < 0 || n >= (
int)_points.size()) {
571 return _points[n]._p;
586 if (n < 0 || n >= (
int)_points.size() || _points[n-1]._type==HC_CUT) {
590 return _points[n]._in;
605 if (n < 0 || n >= (
int)_points.size() || _points[n]._type==HC_CUT) {
609 return _points[n]._out;
627 }
else if (n >= (
int)_points.size()) {
631 return get_tstart(n);
641 if (n < 0 || n >= (
int)_points.size()) {
645 return _points[n]._name;
655 output(ostream &out)
const {
656 PiecewiseCurve::output(out);
659 switch (get_curve_type()) {
676 out << get_num_cvs() <<
" CV's)";
685 write_cv(ostream &out,
int n)
const {
687 if (!get_cv_name(n).empty()) {
688 out <<
" " << get_cv_name(n);
691 out <<
" at t = " << get_cv_tstart(n)
692 <<
"\npoint = " << get_cv_point(n)
693 <<
"\nin = " << get_cv_in(n) <<
" out = " << get_cv_out(n)
694 <<
"\ncontinuity type = ";
696 switch (get_cv_type(n)) {
735 cerr <<
"rebuild_curveseg not implemented for this curve type.\n";
745 format_egg(ostream &out,
const string &name,
const string &curve_type,
746 int indent_level)
const {
747 indent(out, indent_level)
748 <<
"<VertexPool> " << name <<
".pool {\n";
751 for (i = 0; i < (int)_points.size(); i++) {
752 bool show_in = (i != 0);
753 bool show_out = (i != (int)_points.size()-1);
754 _points[i].format_egg(out, indent_level + 2, _num_dimensions,
756 show_in ? get_tlength(i-1) : 0.0f,
757 show_out ? get_tlength(i) : 0.0f);
759 indent(out, indent_level) <<
"}\n";
761 indent(out, indent_level) <<
"<BezierCurve> " << name <<
" {\n";
763 if (!curve_type.empty()) {
764 indent(out, indent_level+2)
765 <<
"<Scalar> type { " << curve_type <<
" }\n";
768 indent(out, indent_level+2) <<
"<TLengths> {";
769 if (_points.size() > 1) {
770 for (i = 0; i < (int)_segs.size(); i++) {
773 indent(out, indent_level+3);
775 out <<
" " << get_tlength(i);
779 indent(out, indent_level+2) <<
"}\n";
781 indent(out, indent_level+2) <<
"<VertexRef> {";
782 for (i = 1; i <= (int)_points.size() * 3 - 2; i++) {
785 indent(out, indent_level+3);
790 indent(out, indent_level+4) <<
"<Ref> { " << name <<
".pool }\n";
791 indent(out, indent_level+2) <<
"}\n";
793 indent(out, indent_level) <<
"}\n";
801 for (
int i = 0; i < 3; i++) {
802 while ((hpr2[i] - hpr1[i]) > 180.0) {
806 while ((hpr2[i] - hpr1[i]) < -180.0) {
819 invalidate_cv(
int n,
bool redo_all) {
820 PN_stdfloat t1 = 0.0f, t2 = get_max_t();
821 if (n>0 && _points[n-1]._type!=HC_CUT) {
824 if (_curve_type == PCT_HPR) {
827 get_curveseg(n-1)->hermite_basis(p1, p2, get_tlength(n-1));
828 t1 = get_cv_tstart(n-1);
831 if (n+1 < (
int)_points.size()) {
832 if (_points[n]._type==HC_CUT) {
834 seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
835 get_curveseg(n)->bezier_basis(seg);
839 if (_curve_type == PCT_HPR) {
842 get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
843 t2 = get_cv_tstart(n+2);
865 find_cv(PN_stdfloat t) {
866 nassertr(is_valid(), 0);
869 for (n = 0; n < (int)_segs.size(); n++) {
870 if (_segs[n]._tend+0.00001 > t) {
890 for (n = 0; n < (int)_segs.size(); n++) {
891 if (_points[n]._type==HC_CUT) {
893 seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
894 get_curveseg(n)->bezier_basis(seg);
898 if (_curve_type == PCT_HPR) {
901 get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
929 parse_params(params, scan, manager);
930 me->fillin(scan, manager);
942 PiecewiseCurve::write_datagram(manager, me);
946 for (i = 0; i < _points.size(); i++) {
947 _points[i].write_datagram(manager, me);
961 PiecewiseCurve::fillin(scan, manager);
964 _points.reserve(num_points);
966 for (i = 0; i < num_points; i++) {
969 _points.push_back(cv);
bool remove_cv(int n)
Removes the given CV from the curve.
PN_int8 get_int8()
Extracts a signed 8-bit integer.
int get_num_cvs() const
Returns the number of CV's in the curve.
This is the base class for all three-component vectors and points.
void add_string(const string &str)
Adds a variable-length string to the datagram.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
A virtual base class for parametric curves.
int insert_cv(PN_stdfloat t)
Inserts a new CV at the given parametric point along the curve.
void add_int8(PN_int8 value)
Adds a signed 8-bit integer to the datagram.
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.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
bool set_cv_point(int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Changes the given CV's position.
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...
string get_string()
Extracts a variable-length string.
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors...
void format_egg(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 set_out(const LVecBase3 &out)
Sets the CV's out tangent.
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.
void wrap_hpr()
Resets each HPR data point so that the maximum delta between any two consecutive points is 180 degree...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
const LVecBase3 & get_cv_point(int n) const
Returns the position of the given CV.
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...
PN_stdfloat get_cv_tstart(int n) const
Returns the starting point in parametric space of the given CV.
bool set_cv_type(int n, int type)
Changes the given CV's continuity type.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
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...
This is the base class for all three-component vectors and points.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
bool set_cv_tstart(int n, PN_stdfloat tstart)
Changes the given CV's parametric starting time.
A single CV of a Hermite curve.
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
virtual bool convert_to_hermite(HermiteCurve *hc) const
Stores an equivalent curve representation in the indicated Hermite curve, if possible.
void set_name(const string &name)
Sets the name associated with the CV.
A class to retrieve the individual data elements previously stored in a Datagram. ...
const LVecBase3 & get_cv_out(int n) const
Returns the out tangent of the given CV.
TypeHandle is the identifier used to differentiate C++ class types.
const LVecBase3 & get_cv_in(int n) const
Returns the in tangent of the given CV.
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.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void write_datagram(BamWriter *manager, Datagram &me) const
Function to write the important information in the particular object to a Datagram.