From 8911e805e3326300bef2786b693b111ccd3bed8d Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 6 Feb 2001 00:52:49 +0000 Subject: [PATCH] *** empty log message *** --- dtool/src/dtoolutil/filename.I | 20 ++++ dtool/src/dtoolutil/filename.cxx | 2 +- dtool/src/dtoolutil/filename.h | 1 + panda/src/egg2sg/Sources.pp | 2 +- panda/src/egg2sg/eggLoader.cxx | 72 +++++++++++++- panda/src/egg2sg/eggLoader.h | 2 + panda/src/parametrics/curve.h | 12 +-- panda/src/parametrics/curveDrawer.cxx | 16 ++-- panda/src/parametrics/curveDrawer.h | 12 +-- panda/src/parametrics/curveFitter.cxx | 92 +++++++++++++++--- panda/src/parametrics/curveFitter.h | 11 ++- panda/src/parametrics/nurbsCurve.cxx | 129 +++++++++++++++----------- panda/src/parametrics/nurbsCurve.h | 10 +- 13 files changed, 282 insertions(+), 99 deletions(-) diff --git a/dtool/src/dtoolutil/filename.I b/dtool/src/dtoolutil/filename.I index 0002b4ddd1..265b0407c9 100644 --- a/dtool/src/dtoolutil/filename.I +++ b/dtool/src/dtoolutil/filename.I @@ -386,6 +386,26 @@ is_local() const { return _filename.empty() || _filename[0] != '/'; } +//////////////////////////////////////////////////////////////////// +// Function: Filename::is_fully_qualified +// Access: Public +// Description: Returns true if the filename is fully qualified, +// e.g. begins with a slash. This is almost, but not +// quite, the same thing as !is_local(). It's not +// exactly the same because a special case is made for +// filenames that begin with a single dot followed by a +// slash--these are considered to be fully qualified +// (they are explicitly relative to the current +// directory, and do not refer to a filename on a search +// path somewhere). +//////////////////////////////////////////////////////////////////// +INLINE bool Filename:: +is_fully_qualified() const { + return + (_filename.size() > 2 && _filename[0] == '.' && _filename[1] == '/') || + (!_filename.empty() && _filename[0] == '/'); +} + //////////////////////////////////////////////////////////////////// // Function: Filename::Equality operator // Access: Public diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index 42864682ac..3e4e7591ea 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -827,7 +827,7 @@ resolve_filename(const DSearchPath &searchpath, const string &default_extension) { string found; - if (is_local()) { + if (!is_fully_qualified()) { found = searchpath.find_file(get_fullpath()); if (found.empty()) { diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 40d8fe32c4..6a27d96fc2 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -119,6 +119,7 @@ PUBLISHED: // The following functions deal with the outside world. INLINE bool is_local() const; + INLINE bool is_fully_qualified() const; void make_absolute(); void make_absolute(const Filename &start_directory); diff --git a/panda/src/egg2sg/Sources.pp b/panda/src/egg2sg/Sources.pp index f3f6cfe646..e9febc59f7 100644 --- a/panda/src/egg2sg/Sources.pp +++ b/panda/src/egg2sg/Sources.pp @@ -4,7 +4,7 @@ #begin lib_target #define TARGET egg2sg #define LOCAL_LIBS \ - cull collide egg builder loader chan char switchnode + parametrics cull collide egg builder loader chan char switchnode #define SOURCES \ animBundleMaker.cxx animBundleMaker.h characterMaker.cxx \ diff --git a/panda/src/egg2sg/eggLoader.cxx b/panda/src/egg2sg/eggLoader.cxx index f53463596d..4d9821c4ff 100644 --- a/panda/src/egg2sg/eggLoader.cxx +++ b/panda/src/egg2sg/eggLoader.cxx @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -1063,7 +1065,9 @@ setup_bucket(BuilderBucket &bucket, NamedNode *parent, //////////////////////////////////////////////////////////////////// RenderRelation *EggLoader:: make_node(EggNode *egg_node, NamedNode *parent) { - if (egg_node->is_of_type(EggPrimitive::get_class_type())) { + if (egg_node->is_of_type(EggNurbsCurve::get_class_type())) { + return make_node(DCAST(EggNurbsCurve, egg_node), parent); + } else if (egg_node->is_of_type(EggPrimitive::get_class_type())) { return make_node(DCAST(EggPrimitive, egg_node), parent); } else if (egg_node->is_of_type(EggBin::get_class_type())) { return make_node(DCAST(EggBin, egg_node), parent); @@ -1078,6 +1082,72 @@ make_node(EggNode *egg_node, NamedNode *parent) { return (RenderRelation *)NULL; } +//////////////////////////////////////////////////////////////////// +// Function: EggLoader::make_node (EggNurbsCurve) +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +RenderRelation *EggLoader:: +make_node(EggNurbsCurve *egg_curve, NamedNode *parent) { + assert(parent != NULL); + assert(!parent->is_of_type(GeomNode::get_class_type())); + + PT(NurbsCurve) curve = new NurbsCurve; + + if (egg_curve->get_order() < 1 || egg_curve->get_order() > 4) { + egg2sg_cat.error() + << "Invalid NURBSCurve order for " << egg_curve->get_name() << ": " + << egg_curve->get_order() << "\n"; + return (RenderRelation *)NULL; + } + + curve->set_order(egg_curve->get_order()); + + EggPrimitive::const_iterator pi; + for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) { + curve->append_cv(LCAST(float, (*pi)->get_pos4())); + } + + int num_knots = egg_curve->get_num_knots(); + if (num_knots != curve->get_num_knots()) { + egg2sg_cat.error() + << "Invalid NURBSCurve number of knots for " + << egg_curve->get_name() << ": got " << num_knots + << " knots, expected " << curve->get_num_knots() << "\n"; + return (RenderRelation *)NULL; + } + + for (int i = 0; i < num_knots; i++) { + curve->set_knot(i, egg_curve->get_knot(i)); + } + + switch (egg_curve->get_curve_type()) { + case EggCurve::CT_xyz: + curve->set_curve_type(PCT_XYZ); + break; + + case EggCurve::CT_hpr: + curve->set_curve_type(PCT_HPR); + break; + + case EggCurve::CT_t: + curve->set_curve_type(PCT_T); + break; + + default: + break; + } + curve->set_name(egg_curve->get_name()); + + if (!curve->recompute()) { + egg2sg_cat.error() + << "Invalid NURBSCurve " << egg_curve->get_name() << "\n"; + return (RenderRelation *)NULL; + } + + return new RenderRelation(parent, curve); +} + //////////////////////////////////////////////////////////////////// // Function: EggLoader::make_node (EggPrimitive) // Access: Private diff --git a/panda/src/egg2sg/eggLoader.h b/panda/src/egg2sg/eggLoader.h index 6ba545cf69..9981ac3e64 100644 --- a/panda/src/egg2sg/eggLoader.h +++ b/panda/src/egg2sg/eggLoader.h @@ -26,6 +26,7 @@ class EggNode; class EggBin; class EggTable; +class EggNurbsCurve; class EggPrimitive; class EggPolygon; class ComputedVerticesMaker; @@ -77,6 +78,7 @@ private: EggPrimitive *egg_prim); RenderRelation *make_node(EggNode *egg_node, NamedNode *parent); + RenderRelation *make_node(EggNurbsCurve *egg_curve, NamedNode *parent); RenderRelation *make_node(EggPrimitive *egg_prim, NamedNode *parent); RenderRelation *make_node(EggBin *egg_bin, NamedNode *parent); RenderRelation *make_node(EggGroup *egg_group, NamedNode *parent); diff --git a/panda/src/parametrics/curve.h b/panda/src/parametrics/curve.h index bc53fb1acd..af6421512d 100644 --- a/panda/src/parametrics/curve.h +++ b/panda/src/parametrics/curve.h @@ -25,8 +25,7 @@ #include #include -#include "typedWriteableReferenceCount.h" -#include "namable.h" +#include "namedNode.h" #include "luse.h" @@ -81,8 +80,7 @@ class NurbsCurve; // This encapsulates all curves in 3-d space defined // for a single parameter t in the range [0,get_max_t()]. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA ParametricCurve : public TypedWriteableReferenceCount, - public Namable { +class EXPCL_PANDA ParametricCurve : public NamedNode { PUBLISHED: ParametricCurve(); virtual ~ParametricCurve(); @@ -153,11 +151,9 @@ public: return _type_handle; } static void init_type() { - TypedWriteableReferenceCount::init_type(); - Namable::init_type(); + NamedNode::init_type(); register_type(_type_handle, "ParametricCurve", - TypedWriteableReferenceCount::get_class_type(), - Namable::get_class_type()); + NamedNode::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/parametrics/curveDrawer.cxx b/panda/src/parametrics/curveDrawer.cxx index 809ccd8bf5..6da5c580c9 100644 --- a/panda/src/parametrics/curveDrawer.cxx +++ b/panda/src/parametrics/curveDrawer.cxx @@ -34,8 +34,8 @@ ParametricCurveDrawer(ParametricCurve *curve) { _lines.set_color(1.0, 1.0, 1.0); _ticks.set_color(1.0, 0.0, 0.0); _tick_scale = 0.1; - _num_segs = 100; - _num_ticks = 0; + _num_segs = 100.0; + _num_ticks = 0.0; _frame_accurate = false; _geom_node = new GeomNode; _drawn = false; @@ -168,7 +168,7 @@ detach_geom_node() { // curve will be get_max_t() * get_num_segs(). //////////////////////////////////////////////////////////////////// void ParametricCurveDrawer:: -set_num_segs(int num_segs) { +set_num_segs(double num_segs) { _num_segs = num_segs; if (_drawn) { draw(); @@ -184,7 +184,7 @@ set_num_segs(int num_segs) { // is drawn. The total number of segments drawn for the // curve will be get_max_t() * get_num_segs(). //////////////////////////////////////////////////////////////////// -int ParametricCurveDrawer:: +double ParametricCurveDrawer:: get_num_segs() const { return _num_segs; } @@ -202,7 +202,7 @@ get_num_segs() const { // of tick marks. //////////////////////////////////////////////////////////////////// void ParametricCurveDrawer:: -set_num_ticks(int num_ticks) { +set_num_ticks(double num_ticks) { _num_ticks = num_ticks; if (_drawn) { draw(); @@ -215,7 +215,7 @@ set_num_ticks(int num_ticks) { // Description: Returns the number of time tick marks per unit of // time drawn. //////////////////////////////////////////////////////////////////// -int ParametricCurveDrawer:: +double ParametricCurveDrawer:: get_num_ticks() const { return _num_ticks; } @@ -330,7 +330,7 @@ draw() { _drawn = true; // Now draw the time tick marks. - if (_num_ticks > 0) { + if (_num_ticks > 0.0) { LVecBase3f tangent2; int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5); @@ -424,7 +424,7 @@ recompute(double t1, double t2, ParametricCurve *curve) { } } - if (_num_ticks > 0) { + if (_num_ticks > 0.0) { LVecBase3f tangent2; int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5); diff --git a/panda/src/parametrics/curveDrawer.h b/panda/src/parametrics/curveDrawer.h index cfc9b497a5..2aa9c2b973 100644 --- a/panda/src/parametrics/curveDrawer.h +++ b/panda/src/parametrics/curveDrawer.h @@ -71,11 +71,11 @@ PUBLISHED: GeomNode *get_geom_node(); GeomNode *detach_geom_node(); - void set_num_segs(int num_segs); - int get_num_segs() const; + void set_num_segs(double num_segs); + double get_num_segs() const; - void set_num_ticks(int num_ticks); - int get_num_ticks() const; + void set_num_ticks(double num_ticks); + double get_num_ticks() const; void set_color(float r, float g, float b); void set_tick_color(float r, float g, float b); @@ -119,11 +119,11 @@ protected: static void get_tick_marks(const LVecBase3f &tangent, LVecBase3f &t1, LVecBase3f &t2); PT(GeomNode) _geom_node; - int _num_segs; + double _num_segs; ParametricCurve *_curve, *_time_curve; LineSegs _lines, _ticks; bool _drawn; - int _num_ticks; + double _num_ticks; double _tick_scale; bool _frame_accurate; LVecBase3fMapper *_mapper; diff --git a/panda/src/parametrics/curveFitter.cxx b/panda/src/parametrics/curveFitter.cxx index a509791b6f..e8d70abf76 100644 --- a/panda/src/parametrics/curveFitter.cxx +++ b/panda/src/parametrics/curveFitter.cxx @@ -65,6 +65,74 @@ add_point(double t, const LVecBase3f &point) { _data.push_back(dp); } +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::get_num_samples +// Access: Public +// Description: Returns the number of sample points that have been +// added. +//////////////////////////////////////////////////////////////////// +int CurveFitter:: +get_num_samples() const { + return _data.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::get_sample_t +// Access: Public +// Description: Returns the parametric value of the nth sample added. +//////////////////////////////////////////////////////////////////// +double CurveFitter:: +get_sample_t(int n) const { + nassertr(n >= 0 && n < (int)_data.size(), 0.0); + return _data[n]._t; +} + +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::get_sample_point +// Access: Public +// Description: Returns the point in space of the nth sample added. +//////////////////////////////////////////////////////////////////// +const LVecBase3f &CurveFitter:: +get_sample_point(int n) const { +#ifndef NDEBUG + static const LVecBase3f zero(0.0, 0.0, 0.0); + nassertr(n >= 0 && n < (int)_data.size(), zero); +#endif + return _data[n]._point; +} + +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::get_sample_tangent +// Access: Public +// Description: Returns the tangent associated with the nth sample +// added. This is only meaningful if compute_tangents() +// has already been called. +//////////////////////////////////////////////////////////////////// +const LVecBase3f &CurveFitter:: +get_sample_tangent(int n) const { +#ifndef NDEBUG + static const LVecBase3f zero(0.0, 0.0, 0.0); + nassertr(n >= 0 && n < (int)_data.size(), zero); +#endif + return _data[n]._tangent; +} + +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::remove_samples +// Access: Public +// Description: Eliminates all samples from index begin, up to but not +// including index end, from the database. +//////////////////////////////////////////////////////////////////// +void CurveFitter:: +remove_samples(int begin, int end) { + begin = max(0, min((int)_data.size(), begin)); + end = max(0, min((int)_data.size(), end)); + + nassertv(begin <= end); + + _data.erase(_data.begin() + begin, _data.begin() + end); +} + //////////////////////////////////////////////////////////////////// // Function: CurveFitter::sample // Access: Public @@ -451,16 +519,6 @@ make_nurbs() const { #endif } -//////////////////////////////////////////////////////////////////// -// Function: CurveFitter::print -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void CurveFitter:: -print() const { - output(cerr); -} - //////////////////////////////////////////////////////////////////// // Function: CurveFitter::output // Access: Public @@ -468,10 +526,20 @@ print() const { //////////////////////////////////////////////////////////////////// void CurveFitter:: output(ostream &out) const { + out << "CurveFitter, " << _data.size() << " samples.\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: CurveFitter::write +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void CurveFitter:: +write(ostream &out) const { + out << "CurveFitter, " << _data.size() << " samples:\n"; Data::const_iterator di; - for (di = _data.begin(); di != _data.end(); ++di) { - out << (*di) << "\n"; + out << " " << (*di) << "\n"; } } diff --git a/panda/src/parametrics/curveFitter.h b/panda/src/parametrics/curveFitter.h index 888b7ac200..c04cf780f4 100644 --- a/panda/src/parametrics/curveFitter.h +++ b/panda/src/parametrics/curveFitter.h @@ -36,6 +36,12 @@ PUBLISHED: void reset(); void add_point(double t, const LVecBase3f &point); + int get_num_samples() const; + double get_sample_t(int n) const; + const LVecBase3f &get_sample_point(int n) const; + const LVecBase3f &get_sample_tangent(int n) const; + void remove_samples(int begin, int end); + void sample(ParametricCurve *curve, int count, bool even); void generate_even(int count, double net_distance, double net_time); @@ -48,11 +54,10 @@ PUBLISHED: PT(HermiteCurve) make_hermite() const; PT(NurbsCurve) make_nurbs() const; - void print() const; + void output(ostream &out) const; + void write(ostream &out) const; public: - void output(ostream &out) const; - class DataPoint { public: DataPoint() : _t(0.0), _point(0.0, 0.0, 0.0), _tangent(0.0, 0.0, 0.0) { } diff --git a/panda/src/parametrics/nurbsCurve.cxx b/panda/src/parametrics/nurbsCurve.cxx index eaa3a3d32f..d01988429c 100644 --- a/panda/src/parametrics/nurbsCurve.cxx +++ b/panda/src/parametrics/nurbsCurve.cxx @@ -15,6 +15,8 @@ #include "nurbsCurve.h" #include "config_parametrics.h" +#include + //////////////////////////////////////////////////////////////////// // Statics //////////////////////////////////////////////////////////////////// @@ -26,20 +28,6 @@ static const LVecBase3f zero = LVecBase3f(0.0, 0.0, 0.0); // used from time to time as an initializer. -//////////////////////////////////////////////////////////////////// -// Function: Indent -// Description: This function duplicates a similar function declared -// in eggBasics.C. It prints a specified number of -// spaces to indent each line of output. -//////////////////////////////////////////////////////////////////// -static ostream & -Indent(ostream &out, int indent) { - for (int i=0; i= (int)_cvs.size()) { - cout << "No such CV: " << n << "\n"; + out << "No such CV: " << n << "\n"; } else { LVecBase3f p = (const LVecBase3f &)_cvs[n]._p / _cvs[n]._p[3]; - cout << "CV " << n << ": " << p << ", weight " - << _cvs[n]._p[3] << "\n"; + out << "CV " << n << ": " << p << ", weight " + << _cvs[n]._p[3] << "\n"; } - cout << flush; } @@ -692,12 +679,12 @@ rebuild_curveseg(int rtype0, double t0, const LVecBase4f &v0, // Returns true if the file is successfully written. //////////////////////////////////////////////////////////////////// bool NurbsCurve:: -write_egg(const char *filename) { +write_egg(const char *filename, CoordinateSystem cs) { const char *basename = strrchr(filename, '/'); basename = (basename==NULL) ? filename : basename+1; ofstream out(filename, ios::app); - return write_egg(out, basename); + return write_egg(out, basename, cs); } //////////////////////////////////////////////////////////////////// @@ -708,7 +695,7 @@ write_egg(const char *filename) { // successfully written. //////////////////////////////////////////////////////////////////// bool NurbsCurve:: -write_egg(ostream &out, const char *basename) { +write_egg(ostream &out, const char *basename, CoordinateSystem cs) { if (get_name().empty()) { // If we don't have a name, come up with one. int len = strlen(basename); @@ -738,7 +725,7 @@ write_egg(ostream &out, const char *basename) { set_name(name); } - Output(out); + format_egg(out, cs, 0); if (out) { return true; @@ -804,26 +791,59 @@ splice(double t, const NurbsCurve &other) { //////////////////////////////////////////////////////////////////// -// Function: NurbsCurve::Output +// Function: NurbsCurve::format_egg // Access: Public // Description: Formats the Nurbs curve for output to an Egg file. //////////////////////////////////////////////////////////////////// void NurbsCurve:: -Output(ostream &out, int indent) const { - Indent(out, indent) +format_egg(ostream &out, CoordinateSystem cs, int indent_level) const { + if (cs == CS_default) { + cs = default_coordinate_system; + } + + if (cs != CS_invalid) { + indent(out, indent_level) + << " { "; + switch (cs) { + case CS_zup_right: + out << "Z-Up"; + break; + + case CS_yup_right: + out << "Y-Up"; + break; + + case CS_zup_left: + out << "Z-Up-Left"; + break; + + case CS_yup_left: + out << "Y-Up-Left"; + break; + + default: + break; + } + out << " }\n\n"; + } + + indent(out, indent_level) << " " << get_name() << ".pool {\n"; int cv; for (cv = 0; cv < (int)_cvs.size(); cv++) { - Indent(out, indent+2) << " " << cv << " { " - << _cvs[cv]._p << " }\n"; + indent(out, indent_level+2) + << " " << cv << " { " << _cvs[cv]._p << " }\n"; } - Indent(out, indent) << "}\n"; + indent(out, indent_level) + << "}\n"; - Indent(out, indent) << " " << get_name() << " {\n"; + indent(out, indent_level) + << " " << get_name() << " {\n"; if (_curve_type!=PCT_NONE) { - Indent(out, indent+2) << " type { "; + indent(out, indent_level+2) + << " type { "; switch (_curve_type) { case PCT_XYZ: out << "XYZ"; @@ -840,35 +860,36 @@ Output(ostream &out, int indent) const { out << " }\n"; } - Indent(out, indent+2) << " { " << _order << " }\n"; + indent(out, indent_level+2) << " { " << _order << " }\n"; - Indent(out, indent+2) << " {"; + indent(out, indent_level+2) << " {"; int k; int num_knots = _cvs.size() + _order; for (k = 0; k < num_knots; k++) { if (k%6 == 0) { out << "\n"; - Indent(out, indent+4); + indent(out, indent_level+4); } out << GetKnot(k) << " "; } out << "\n"; - Indent(out, indent+2) << "}\n"; + indent(out, indent_level+2) << "}\n"; - Indent(out, indent+2) << " {"; + indent(out, indent_level+2) << " {"; for (cv = 0; cv < (int)_cvs.size(); cv++) { - if (cv%10 == 1) { + if (cv%10 == 0) { out << "\n"; - Indent(out, indent+3); + indent(out, indent_level+3); } out << " " << cv; } out << "\n"; - Indent(out, indent+4) << " { " << get_name() << ".pool }\n"; - Indent(out, indent+2) << "}\n"; + indent(out, indent_level+4) + << " { " << get_name() << ".pool }\n"; + indent(out, indent_level+2) << "}\n"; - Indent(out, indent) << "}\n"; + indent(out, indent_level) << "}\n"; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/parametrics/nurbsCurve.h b/panda/src/parametrics/nurbsCurve.h index ff978e6d21..626c0895b7 100644 --- a/panda/src/parametrics/nurbsCurve.h +++ b/panda/src/parametrics/nurbsCurve.h @@ -87,15 +87,15 @@ PUBLISHED: bool set_knot(int n, double t); double get_knot(int n) const; - void print() const; - void print_cv(int n) const; + void write(ostream &out) const; + void write_cv(ostream &out, int n) const; bool recompute(); void normalize_tlength(); - bool write_egg(const char *filename); - bool write_egg(ostream &out, const char *basename); + bool write_egg(const char *filename, CoordinateSystem cs = CS_default); + bool write_egg(ostream &out, const char *basename, CoordinateSystem cs); void splice(double t, const NurbsCurve &other); @@ -124,7 +124,7 @@ public: } } - void Output(ostream &out, int indent=0) const; + void format_egg(ostream &out, CoordinateSystem cs, int indent_level) const; protected: int FindCV(double t);