32 static const LVecBase3 zerovec_3 = LVecBase3(0.0f, 0.0f, 0.0f);
42 show_vec3(ostream &out,
int indent_level,
const LVecBase3 &v,
44 indent(out, indent_level) << v[0];
45 for (
int i = 1; i<num_dimensions; i++) {
64 _p(c._p), _in(c._in), _out(c._out),
65 _type(c._type), _name(c._name)
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 {
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";
176 indent(out, indent_level) <<
"<Vertex> {\n";
177 show_vec3(out, indent_level + 2, _p, num_dimensions) <<
"\n";
179 indent(out, indent_level+2) <<
"<Scalar> continuity-type { ";
199 indent(out, indent_level) <<
"}\n";
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";
215 _p.write_datagram(me);
216 _in.write_datagram(me);
217 _out.write_datagram(me);
229 _p.read_datagram(scan);
230 _in.read_datagram(scan);
231 _out.read_datagram(scan);
250 parametrics_cat->warning()
251 <<
"Cannot make a Hermite from the indicated curve." 274 return _points.size();
291 if (!is_valid() || t >= get_max_t()) {
292 int n = append_cv(HC_SMOOTH, 0.0f, 0.0f, 0.0f);
297 t = std::min(std::max(t, (PN_stdfloat)0.0), get_max_t());
300 nassertr(n+1<get_num_cvs(), 0);
304 cv._type = HC_SMOOTH;
305 get_pt(t, cv._p, tan);
306 cv._out = cv._in = tan * 0.5f;
308 _points.insert(_points.begin() + n + 1, cv);
325 append_cv(
int type, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
328 cv.set_point(LVecBase3(x, y, z));
331 _points.push_back(cv);
332 if (_points.size()>1) {
341 return _points.size()-1;
351 if (n < 0 || n >= (
int)_points.size()) {
355 _points.erase(_points.begin() + n);
356 if (_segs.size()>0) {
357 remove_curveseg(_segs.size()-1);
371 _points.erase(_points.begin(), _points.end());
372 remove_all_curvesegs();
394 if (n < 0 || n >= (
int)_points.size()) {
398 bool changed_cut =
false;
400 if (type!=_points[n]._type) {
401 changed_cut = (type==HC_CUT || _points[n]._type==HC_CUT);
402 _points[n].set_type(type);
405 invalidate_cv(n, changed_cut);
415 if (n < 0 || n >= (
int)_points.size()) {
418 _points[n].set_point(LVecBase3(x, y, z));
419 invalidate_cv(n,
false);
428 set_cv_in(
int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
429 if (n < 0 || n >= (
int)_points.size()) {
432 _points[n].set_in(LVecBase3(x, y, z));
433 invalidate_cv(n,
false);
442 set_cv_out(
int n, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
443 if (n < 0 || n >= (
int)_points.size()) {
446 _points[n].set_out(LVecBase3(x, y, z));
447 invalidate_cv(n,
false);
457 if (n <= 0 || n >= (
int)_points.size()) {
460 if (fabs(tstart - get_cv_tstart(n)) > 0.0001f) {
461 set_tlength(n-1, tstart - get_tstart(n-1));
474 if (n < 0 || n >= (
int)_points.size()) {
477 _points[n].set_name(name);
489 if (n < 0 || n >= (
int)_points.size()) {
493 return _points[n]._type;
502 if (n < 0 || n >= (
int)_points.size()) {
506 return _points[n]._p;
519 if (n < 0 || n >= (
int)_points.size() || _points[n-1]._type==HC_CUT) {
523 return _points[n]._in;
536 if (n < 0 || n >= (
int)_points.size() || _points[n]._type==HC_CUT) {
540 return _points[n]._out;
555 }
else if (n >= (
int)_points.size()) {
559 return get_tstart(n);
567 if (n < 0 || n >= (
int)_points.size()) {
571 return _points[n]._name;
579 output(ostream &out)
const {
580 PiecewiseCurve::output(out);
583 switch (get_curve_type()) {
600 out << get_num_cvs() <<
" CV's)";
607 write_cv(ostream &out,
int n)
const {
609 if (!get_cv_name(n).empty()) {
610 out <<
" " << get_cv_name(n);
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 = ";
618 switch (get_cv_type(n)) {
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";
662 format_egg(ostream &out,
const string &name,
const string &curve_type,
663 int indent_level)
const {
665 <<
"<VertexPool> " << name <<
".pool {\n";
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,
673 show_in ? get_tlength(i-1) : 0.0f,
674 show_out ? get_tlength(i) : 0.0f);
676 indent(out, indent_level) <<
"}\n";
678 indent(out, indent_level) <<
"<BezierCurve> " << name <<
" {\n";
680 if (!curve_type.empty()) {
681 indent(out, indent_level+2)
682 <<
"<Scalar> type { " << curve_type <<
" }\n";
685 indent(out, indent_level+2) <<
"<TLengths> {";
686 if (_points.size() > 1) {
687 for (i = 0; i < (int)_segs.size(); i++) {
690 indent(out, indent_level+3);
692 out <<
" " << get_tlength(i);
696 indent(out, indent_level+2) <<
"}\n";
698 indent(out, indent_level+2) <<
"<VertexRef> {";
699 for (i = 1; i <= (int)_points.size() * 3 - 2; i++) {
702 indent(out, indent_level+3);
707 indent(out, indent_level+4) <<
"<Ref> { " << name <<
".pool }\n";
708 indent(out, indent_level+2) <<
"}\n";
710 indent(out, indent_level) <<
"}\n";
717 wrap_hpr(
const LVecBase3 &hpr1, LVecBase3 &hpr2) {
718 for (
int i = 0; i < 3; i++) {
719 while ((hpr2[i] - hpr1[i]) > 180.0) {
723 while ((hpr2[i] - hpr1[i]) < -180.0) {
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) {
738 if (_curve_type == PCT_HPR) {
741 get_curveseg(n-1)->hermite_basis(p1, p2, get_tlength(n-1));
742 t1 = get_cv_tstart(n-1);
745 if (n+1 < (
int)_points.size()) {
746 if (_points[n]._type==HC_CUT) {
748 seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
749 get_curveseg(n)->bezier_basis(seg);
753 if (_curve_type == PCT_HPR) {
756 get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
757 t2 = get_cv_tstart(n+2);
776 find_cv(PN_stdfloat t) {
777 nassertr(is_valid(), 0);
780 for (n = 0; n < (int)_segs.size(); n++) {
781 if (_segs[n]._tend+0.00001 > t) {
798 for (n = 0; n < (int)_segs.size(); n++) {
799 if (_points[n]._type==HC_CUT) {
801 seg._v[0] = seg._v[1] = seg._v[2] = seg._v[3] = _points[n]._p;
802 get_curveseg(n)->bezier_basis(seg);
806 if (_curve_type == PCT_HPR) {
809 get_curveseg(n)->hermite_basis(p1, p2, get_tlength(n));
833 me->fillin(scan, manager);
843 PiecewiseCurve::write_datagram(manager, me);
847 for (i = 0; i < _points.size(); i++) {
848 _points[i].write_datagram(manager, me);
859 PiecewiseCurve::fillin(scan, manager);
862 _points.reserve(num_points);
864 for (i = 0; i < num_points; i++) {
867 _points.push_back(cv);
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...
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.
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 ...
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.
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,...
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
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 ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
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.
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.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
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.
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.
bool set_cv_tstart(int n, PN_stdfloat tstart)
Changes the given CV's parametric starting time.
A single CV of a Hermite curve.
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.
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 ...
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.