Panda3D
 All Classes Functions Variables Enumerations
cubicCurveseg.h
00001 // Filename: cubicCurveseg.h
00002 // Created by:  drose (04Mar01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef CUBICCURVESEG_H
00016 #define CUBICCURVESEG_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "parametricCurve.h"
00021 
00022 
00023 // These symbols are used to define the shape of the curve segment to
00024 // CubicCurveseg::compute_seg().
00025 
00026 #define RT_POINT       0x01
00027 #define RT_TANGENT     0x02
00028 #define RT_CV          0x03
00029 #define RT_BASE_TYPE   0xff
00030 
00031 #define RT_KEEP_ORIG  0x100
00032 
00033 
00034 ////////////////////////////////////////////////////////////////////
00035 //       Class : CubicCurveseg
00036 // Description : A CubicCurveseg is any curve that can be completely
00037 //               described by four 4-valued basis vectors, one for
00038 //               each dimension in three-space, and one for the
00039 //               homogeneous coordinate.  This includes Beziers,
00040 //               Hermites, and NURBS.
00041 //
00042 //               This class encapsulates a single curve segment of the
00043 //               cubic curve.  Normally, when we think of Bezier and
00044 //               Hermite curves, we think of a piecewise collection of
00045 //               such segments.
00046 //
00047 //               Although this class includes methods such as
00048 //               hermite_basis() and nurbs_basis(), to generate a
00049 //               Hermite and NURBS curve segment, respectively, only
00050 //               the final basis vectors are stored: the product of
00051 //               the basis matrix of the corresponding curve type, and
00052 //               its geometry vectors.  This is the minimum
00053 //               information needed to evaluate the curve.  However,
00054 //               the individual CV's that were used to compute these
00055 //               basis vectors are not retained; this might be handled
00056 //               in a subclass (for instance, HermiteCurve).
00057 ////////////////////////////////////////////////////////////////////
00058 class EXPCL_PANDA_PARAMETRICS CubicCurveseg : public ParametricCurve {
00059 PUBLISHED:
00060   virtual bool get_point(PN_stdfloat t, LVecBase3 &point) const;
00061   virtual bool get_tangent(PN_stdfloat t, LVecBase3 &tangent) const;
00062   virtual bool get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent) const;
00063   virtual bool get_2ndtangent(PN_stdfloat t, LVecBase3 &tangent2) const;
00064 
00065 public:
00066   CubicCurveseg();
00067   CubicCurveseg(const LMatrix4 &basis);
00068   CubicCurveseg(const BezierSeg &seg);
00069   CubicCurveseg(int order, const PN_stdfloat knots[], const LVecBase4 cvs[]);
00070 
00071   virtual ~CubicCurveseg();
00072 
00073   void hermite_basis(const HermiteCurveCV &cv0,
00074                      const HermiteCurveCV &cv1,
00075                      PN_stdfloat tlength = 1.0f);
00076   void bezier_basis(const BezierSeg &seg);
00077   void nurbs_basis(int order, const PN_stdfloat knots[], const LVecBase4 cvs[]);
00078 
00079   // evaluate_point() and evaluate_vector() both evaluate the curve at
00080   // a given point by applying the basis vector against the vector
00081   // [t3 t2 t 1] (or some derivative).  The difference between the
00082   // two is that evaluate_point() is called only with the vector
00083   // [t3 t2 t 1] and computes a point in three-space and will scale by
00084   // the homogeneous coordinate when the curve demands it (e.g. a
00085   // NURBS), while evaluate_vector() is called with some derivative
00086   // vector like [3t2 2t 1 0] and computes a vector difference between
00087   // points, and will never scale by the homogeneous coordinate (which
00088   // would be zero anyway).
00089 
00090   void evaluate_point(const LVecBase4 &tv, LVecBase3 &result) const {
00091     PN_stdfloat recip_h = (rational) ? 1.0f/tv.dot(Bw) : 1.0f;
00092     result.set(tv.dot(Bx) * recip_h,
00093                tv.dot(By) * recip_h,
00094                tv.dot(Bz) * recip_h);
00095   }
00096 
00097   void evaluate_vector(const LVecBase4 &tv, LVecBase3 &result) const {
00098     result.set(tv.dot(Bx),
00099                tv.dot(By),
00100                tv.dot(Bz));
00101   }
00102 
00103   virtual bool get_bezier_seg(BezierSeg &seg) const;
00104 
00105   static bool compute_seg(int rtype0, PN_stdfloat t0, const LVecBase4 &v0,
00106                           int rtype1, PN_stdfloat t1, const LVecBase4 &v1,
00107                           int rtype2, PN_stdfloat t2, const LVecBase4 &v2,
00108                           int rtype3, PN_stdfloat t3, const LVecBase4 &v3,
00109                           const LMatrix4 &B,
00110                           const LMatrix4 &Bi,
00111                           LMatrix4 &G);
00112 
00113   LVecBase4 Bx, By, Bz, Bw;
00114   bool rational;
00115 
00116 
00117 // TypedWritable stuff
00118 public:
00119   static void register_with_read_factory();
00120 
00121 protected:
00122   static TypedWritable *make_CubicCurveseg(const FactoryParams &params);
00123   virtual void write_datagram(BamWriter *manager, Datagram &me);
00124   void fillin(DatagramIterator &scan, BamReader *manager);
00125 
00126 public:
00127   static TypeHandle get_class_type() {
00128     return _type_handle;
00129   }
00130   static void init_type() {
00131     ParametricCurve::init_type();
00132     register_type(_type_handle, "CubicCurveseg",
00133                   ParametricCurve::get_class_type());
00134   }
00135   virtual TypeHandle get_type() const {
00136     return get_class_type();
00137   }
00138   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00139 
00140 private:
00141   static TypeHandle _type_handle;
00142 };
00143 
00144 // This function is used internally to build the NURBS basis matrix
00145 // based on a given knot sequence.
00146 void compute_nurbs_basis(int order,
00147                          const PN_stdfloat knots_in[],
00148                          LMatrix4 &basis);
00149 
00150 
00151 #endif
 All Classes Functions Variables Enumerations