Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/parametrics/cubicCurveseg.cxx

Go to the documentation of this file.
00001 // Filename: cubicCurveseg.cxx
00002 // Created by:  drose (04Mar01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "piecewiseCurve.h"
00020 
00021 #include "config_parametrics.h"
00022 #include "hermiteCurve.h"
00023 
00024 #include <datagram.h>
00025 #include <datagramIterator.h>
00026 #include <bamWriter.h>
00027 #include <bamReader.h>
00028 
00029 TypeHandle CubicCurveseg::_type_handle;
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: CubicCurveseg::Constructor
00033 //       Access: Public
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 CubicCurveseg::
00037 CubicCurveseg() {
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: CubicCurveseg::Constructor
00042 //       Access: Public
00043 //  Description: Creates the curveseg given the four basis vectors
00044 //               (the columns of the matrix) explicitly.
00045 ////////////////////////////////////////////////////////////////////
00046 CubicCurveseg::
00047 CubicCurveseg(const LMatrix4f &basis) {
00048   Bx = basis.get_col(0);
00049   By = basis.get_col(1);
00050   Bz = basis.get_col(2);
00051   Bw = basis.get_col(3);
00052   rational = true;
00053 }
00054 
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: CubicCurveseg::Constructor
00058 //       Access: Public
00059 //  Description: Creates the curveseg as a Bezier segment.
00060 ////////////////////////////////////////////////////////////////////
00061 CubicCurveseg::
00062 CubicCurveseg(const BezierSeg &seg) {
00063   bezier_basis(seg);
00064 }
00065 
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: CubicCurveseg::Constructor
00069 //       Access: Public
00070 //  Description: Creates the curveseg as a NURBS segment.  See
00071 //               nurbs_basis for a description of the parameters.
00072 ////////////////////////////////////////////////////////////////////
00073 CubicCurveseg::
00074 CubicCurveseg(int order, const float knots[], const LVecBase4f cvs[]) {
00075   nurbs_basis(order, knots, cvs);
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: CubicCurveseg::Destructor
00080 //       Access: Protected
00081 //  Description:
00082 ////////////////////////////////////////////////////////////////////
00083 CubicCurveseg::
00084 ~CubicCurveseg() {
00085 }
00086 
00087 
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: CubicCurveseg::get_point
00091 //       Access: Published, Virtual
00092 //  Description: Computes the surface point at a given parametric
00093 //               point t.
00094 ////////////////////////////////////////////////////////////////////
00095 bool CubicCurveseg::
00096 get_point(float t, LVecBase3f &point) const {
00097   float t_sqrd = t*t;
00098   evaluate_point(LVecBase4f(t*t_sqrd, t_sqrd, t, 1.0f), point);
00099   return true;
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: CubicCurveseg::get_tangent
00104 //       Access: Published, Virtual
00105 //  Description: Computes the surface tangent at a given parametric
00106 //               point t.
00107 ////////////////////////////////////////////////////////////////////
00108 bool CubicCurveseg::
00109 get_tangent(float t, LVecBase3f &tangent) const {
00110   evaluate_vector(LVecBase4f(3.0f*t*t, 2.0f*t, 1.0f, 0.0f), tangent);
00111   return true;
00112 }
00113 
00114 ////////////////////////////////////////////////////////////////////
00115 //     Function: CubicCurveseg::get_pt
00116 //       Access: Published, Virtual
00117 //  Description: Simultaneously computes the point and the tangent at
00118 //               the given parametric point.
00119 ////////////////////////////////////////////////////////////////////
00120 bool CubicCurveseg::
00121 get_pt(float t, LVecBase3f &point, LVecBase3f &tangent) const {
00122   float t_sqrd=t*t;
00123   evaluate_point(LVecBase4f(t*t_sqrd, t_sqrd, t, 1.0f), point);
00124   evaluate_vector(LVecBase4f(3.0f*t_sqrd, /*2.0f*t*/t+t, 1.0f, 0.0f), tangent);
00125   return true;
00126 }
00127 
00128 ////////////////////////////////////////////////////////////////////
00129 //     Function: CubicCurveseg::get_2ndtangent
00130 //       Access: Published, Virtual
00131 //  Description: Computes the surface 2nd-order tangent at a given
00132 //               parametric point t.
00133 ////////////////////////////////////////////////////////////////////
00134 bool CubicCurveseg::
00135 get_2ndtangent(float t, LVecBase3f &tangent2) const {
00136   evaluate_vector(LVecBase4f(6.0f*t, 2.0f, 0.0f, 0.0f), tangent2);
00137   return true;
00138 }
00139 
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: CubicCurveseg::hermite_basis
00143 //       Access: Public
00144 //  Description: Defines the curve segment as a Hermite.  This only
00145 //               sets up the basis vectors, so the curve will be
00146 //               computed correctly; it does not retain the CV's.
00147 ////////////////////////////////////////////////////////////////////
00148 void CubicCurveseg::
00149 hermite_basis(const HermiteCurveCV &cv0,
00150               const HermiteCurveCV &cv1,
00151               float tlength) {
00152   static LMatrix4f
00153     Mh( 2.0f, -3.0f, 0.0f, 1.0f,
00154        -2.0f,  3.0f, 0.0f, 0.0f,
00155         1.0f, -2.0f, 1.0f, 0.0f,
00156         1.0f, -1.0f, 0.0f, 0.0f);
00157 
00158   LVecBase4f Gx(cv0._p[0], cv1._p[0],
00159                 cv0._out[0]*tlength, cv1._in[0]*tlength);
00160   LVecBase4f Gy(cv0._p[1], cv1._p[1],
00161                 cv0._out[1]*tlength, cv1._in[1]*tlength);
00162   LVecBase4f Gz(cv0._p[2], cv1._p[2],
00163                 cv0._out[2]*tlength, cv1._in[2]*tlength);
00164 
00165   Bx = Gx * Mh;
00166   By = Gy * Mh;
00167   Bz = Gz * Mh;
00168   rational = false;
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: CubicCurveseg::bezier_basis
00173 //       Access: Public
00174 //  Description: Defines the curve segment as a Bezier.  This only
00175 //               sets up the basis vectors, so the curve will be
00176 //               computed correctly; it does not retain the CV's.
00177 ////////////////////////////////////////////////////////////////////
00178 void CubicCurveseg::
00179 bezier_basis(const BezierSeg &seg) {
00180   static LMatrix4f
00181     Mb(-1.0f,  3.0f, -3.0f, 1.0f,
00182         3.0f, -6.0f,  3.0f, 0.0f,
00183        -3.0f,  3.0f,  0.0f, 0.0f,
00184         1.0f,  0.0f,  0.0f, 0.0f);
00185 
00186   LVecBase4f Gx(seg._v[0][0], seg._v[1][0], seg._v[2][0], seg._v[3][0]);
00187   LVecBase4f Gy(seg._v[0][1], seg._v[1][1], seg._v[2][1], seg._v[3][1]);
00188   LVecBase4f Gz(seg._v[0][2], seg._v[1][2], seg._v[2][2], seg._v[3][2]);
00189 
00190   Bx = Gx * Mb;
00191   By = Gy * Mb;
00192   Bz = Gz * Mb;
00193   rational = false;
00194 }
00195 
00196 static LVecBase4f
00197 nurbs_blending_function(int order, int i, int j,
00198                         const float knots[]) {
00199   // This is doubly recursive.  Ick.
00200   LVecBase4f r;
00201 
00202   if (j==1) {
00203     if (i==order-1 && knots[i] < knots[i+1]) {
00204       r.set(0.0f, 0.0f, 0.0f, 1.0f);
00205     } else {
00206       r.set(0.0f, 0.0f, 0.0f, 0.0f);
00207     }
00208 
00209   } else {
00210     LVecBase4f bi0 = nurbs_blending_function(order, i, j-1, knots);
00211     LVecBase4f bi1 = nurbs_blending_function(order, i+1, j-1, knots);
00212 
00213     float d0 = knots[i+j-1] - knots[i];
00214     float d1 = knots[i+j] - knots[i+1];
00215 
00216     // First term.  Division by zero is defined to equal zero.
00217     if (d0 != 0.0f) {
00218       if (d1 != 0.0f) {
00219         r = bi0 / d0 - bi1 / d1;
00220       } else {
00221         r = bi0 / d0;
00222       }
00223 
00224     } else if (d1 != 0.0f) {
00225       r = - bi1 / d1;
00226 
00227     } else {
00228       r.set(0.0f, 0.0f, 0.0f, 0.0f);
00229     }
00230 
00231     // scale by t.
00232     r[0] = r[1];
00233     r[1] = r[2];
00234     r[2] = r[3];
00235     r[3] = 0.0f;
00236 
00237     // Second term.
00238     if (d0 != 0.0f) {
00239       if (d1 != 0.0f) {
00240         r += bi0 * (- knots[i] / d0) + bi1 * (knots[i+j] / d1);
00241       } else {
00242         r += bi0 * (- knots[i] / d0);
00243       }
00244 
00245     } else if (d1 != 0.0f) {
00246       r += bi1 * (knots[i+j] / d1);
00247     }
00248   }
00249 
00250   return r;
00251 }
00252 
00253 void
00254 compute_nurbs_basis(int order,
00255                     const float knots_in[],
00256                     LMatrix4f &basis) {
00257   int i;
00258 
00259   // Scale the supplied knots to the range 0..1.
00260   float knots[8];
00261   float mink = knots_in[order-1];
00262   float maxk = knots_in[order];
00263 
00264   if (mink==maxk) {
00265     // Huh.  What were you thinking?  This is a trivial NURBS.
00266     parametrics_cat->warning()
00267       << "Trivial NURBS curve specified." << endl;
00268     memset((void *)&basis, 0, sizeof(LMatrix4f));
00269     return;
00270   }
00271 
00272   for (i = 0; i<2*order; i++) {
00273     knots[i] = (knots_in[i] - mink) / (maxk-mink);
00274   }
00275 
00276 
00277   LVecBase4f b[4];
00278   for (i = 0; i<order; i++) {
00279     b[i] = nurbs_blending_function(order, i, order, knots);
00280   }
00281 
00282   for (i = 0; i<order; i++) {
00283     basis.set_row(i, b[i]);
00284   }
00285 
00286   for (i=order; i<4; i++) {
00287     basis.set_row(i, LVecBase4f::zero());
00288   }
00289 }
00290 
00291 
00292 
00293 ////////////////////////////////////////////////////////////////////
00294 //     Function: CubicCurveseg::nurbs_basis
00295 //       Access: Public
00296 //  Description: Defines the curve segment as a NURBS.  Order is one
00297 //               more than the degree, and must be 1, 2, 3, or 4;
00298 //               knots is an array of order*2 values, and cvs is an
00299 //               array of order values.
00300 ////////////////////////////////////////////////////////////////////
00301 void CubicCurveseg::
00302 nurbs_basis(int order, const float knots[], const LVecBase4f cvs[]) {
00303   assert(order>=1 && order<=4);
00304 
00305   LMatrix4f B;
00306   compute_nurbs_basis(order, knots, B);
00307 
00308   // Create a local copy of our CV's, so we can zero out the unused
00309   // elements.
00310   LVecBase4f c[4];
00311   for (int i = 0; i < 4; i++) {
00312     c[i] = (i<order) ? cvs[i] : LVecBase4f(0.0f, 0.0f, 0.0f, 0.0f);
00313   }
00314 
00315   Bx = LVecBase4f(c[0][0], c[1][0], c[2][0], c[3][0]) * B;
00316   By = LVecBase4f(c[0][1], c[1][1], c[2][1], c[3][1]) * B;
00317   Bz = LVecBase4f(c[0][2], c[1][2], c[2][2], c[3][2]) * B;
00318   Bw = LVecBase4f(c[0][3], c[1][3], c[2][3], c[3][3]) * B;
00319 
00320   rational = true;
00321 }
00322 
00323 ////////////////////////////////////////////////////////////////////
00324 //     Function: CubicCurveseg::get_bezier_seg
00325 //       Access: Public, Virtual
00326 //  Description: Fills the BezierSeg structure with a description of
00327 //               the curve segment as a Bezier, if possible, but does
00328 //               not change the _t member of the structure.  Returns
00329 //               true if successful, false otherwise.
00330 ////////////////////////////////////////////////////////////////////
00331 bool CubicCurveseg::
00332 get_bezier_seg(BezierSeg &seg) const {
00333   static LMatrix4f
00334     Mbi(0.0f, 0.0f, 0.0f, 1.0f,
00335         0.0f, 0.0f, 1.0f/3.0f, 1.0f,
00336         0.0f, 1.0f/3.0f, 2.0f/3.0f, 1.0f,
00337         1.0f, 1.0f, 1.0f, 1.0f);
00338 
00339   LVecBase4f Gx = Bx * Mbi;
00340   LVecBase4f Gy = By * Mbi;
00341   LVecBase4f Gz = Bz * Mbi;
00342 
00343   if (rational) {
00344     LVecBase4f Gw = Bw * Mbi;
00345     seg._v[0].set(Gx[0]/Gw[0], Gy[0]/Gw[0], Gz[0]/Gw[0]);
00346     seg._v[1].set(Gx[1]/Gw[1], Gy[1]/Gw[1], Gz[1]/Gw[1]);
00347     seg._v[2].set(Gx[2]/Gw[2], Gy[2]/Gw[2], Gz[2]/Gw[2]);
00348     seg._v[3].set(Gx[3]/Gw[3], Gy[3]/Gw[3], Gz[3]/Gw[3]);
00349   } else {
00350     seg._v[0].set(Gx[0], Gy[0], Gz[0]);
00351     seg._v[1].set(Gx[1], Gy[1], Gz[1]);
00352     seg._v[2].set(Gx[2], Gy[2], Gz[2]);
00353     seg._v[3].set(Gx[3], Gy[3], Gz[3]);
00354   }
00355 
00356   return true;
00357 }
00358 
00359 // We need this operator since Performer didn't supply it.
00360 inline LVecBase4f
00361 col_mult(const LMatrix4f &M, const LVecBase4f &v) {
00362   return LVecBase4f(M(0,0)*v[0] + M(0,1)*v[1] + M(0,2)*v[2] + M(0,3)*v[3],
00363                 M(1,0)*v[0] + M(1,1)*v[1] + M(1,2)*v[2] + M(1,3)*v[3],
00364                 M(2,0)*v[0] + M(2,1)*v[1] + M(2,2)*v[2] + M(2,3)*v[3],
00365                 M(3,0)*v[0] + M(3,1)*v[1] + M(3,2)*v[2] + M(3,3)*v[3]);
00366 }
00367 
00368 ////////////////////////////////////////////////////////////////////
00369 //     Function: compute_seg_col
00370 //  Description: Interprets the parameters for a particular column of
00371 //               compute_seg.  Builds the indicated column of T
00372 //               and P.
00373 ////////////////////////////////////////////////////////////////////
00374 static bool
00375 compute_seg_col(int c,
00376                 int rtype, float t, const LVecBase4f &v,
00377                 const LMatrix4f &B,
00378                 const LMatrix4f &Bi,
00379                 const LMatrix4f &G,
00380                 const LMatrix4f &GB,
00381                 LMatrix4f &T, LMatrix4f &P) {
00382   bool keep_orig = ((rtype & RT_KEEP_ORIG) != 0);
00383 
00384   if (parametrics_cat.is_debug()) {
00385     parametrics_cat.debug()
00386       << "Computing col " << c << " type " << (rtype & RT_BASE_TYPE)
00387       << " at " << t << " keep_orig = " << keep_orig
00388       << " v = " << v << "\n";
00389   }
00390 
00391   switch (rtype & RT_BASE_TYPE) {
00392     // RT_point defines the point on the curve at t.  This is the vector
00393     // [ t^3 t^2 t^1 t^0 ].
00394     float t_sqrd,t_cubed;
00395 
00396   case RT_POINT:
00397     t_sqrd = t*t;
00398     t_cubed = t_sqrd*t;
00399     T.set_col(c, LVecBase4f(t_cubed, t_sqrd, t, 1.0f));
00400     if (keep_orig) {
00401       LVecBase4f vec(t_cubed, t_sqrd, t, 1.0f);
00402       LVecBase4f ov = col_mult(GB, vec);
00403       if (parametrics_cat.is_debug()) {
00404         parametrics_cat.debug()
00405           << "orig point = " << ov << "\n";
00406       }
00407       P.set_col(c, ov);
00408     } else {
00409       P.set_col(c, v);
00410     }
00411     break;
00412 
00413     // RT_tangent defines the tangent to the curve at t.  This is
00414     // the vector [ 3t^2 2t 1 0 ].
00415   case RT_TANGENT:
00416     t_sqrd = t*t;
00417     T.set_col(c, LVecBase4f(3.0f*t_sqrd, t+t, 1.0f, 0.0f));
00418     if (keep_orig) {
00419       LVecBase4f vec(3.0f*t_sqrd, /*2.0f*t*/t+t, 1.0f, 0.0f);
00420       LVecBase4f ov = col_mult(GB, vec);
00421       if (parametrics_cat.is_debug()) {
00422         parametrics_cat.debug()
00423           << "Matrix is:\n";
00424         GB.write(parametrics_cat.debug(false), 2);
00425         parametrics_cat.debug(false)
00426           << "vector is " << vec << "\n"
00427           << "orig tangent = " << ov << "\n";
00428       }
00429       P.set_col(c, ov);
00430     } else {
00431       P.set_col(c, v);
00432     }
00433     break;
00434 
00435     // RT_cv defines the cth control point.  This is the cth column
00436     // vector from Bi.
00437   case RT_CV:
00438     T.set_col(c, Bi.get_col(c));
00439     if (keep_orig) {
00440       if (parametrics_cat.is_debug()) {
00441         parametrics_cat.debug()
00442           << "orig CV = " << G.get_col(c) << "\n";
00443       }
00444       P.set_col(c, G.get_col(c));
00445     } else {
00446       P.set_col(c, v);
00447     }
00448     break;
00449 
00450   default:
00451     cerr << "Invalid rebuild type in compute_seg\n";
00452     return false;
00453   }
00454 
00455   return true;
00456 }
00457 
00458 ////////////////////////////////////////////////////////////////////
00459 //     Function: CubicCurveseg::compute_seg
00460 //       Access: Public, Static
00461 //  Description: Given a set of four properties of a curve segment
00462 //               (e.g. four points, four tangent values, four control
00463 //               points, or any combination), and a basis matrix,
00464 //               computes the corresponding geometry matrix that
00465 //               (together with the basis matrix) represents the curve
00466 //               that satisfies the four properties.
00467 //
00468 //               The basis matrix is passed in as B, and its inverse
00469 //               must be precomputed and passed in as Bi.
00470 //
00471 //               The result is returned in the matrix G, each column
00472 //               of which represents the cth control vertex.  If any
00473 //               of the four properties has RT_KEEP_ORIG set (see
00474 //               below), G's input value is used to define the
00475 //               original shape of the curve; otherwise, G's input
00476 //               value is ignored.
00477 //
00478 //               Each property is defined by an rtype, which may be
00479 //               any of RT_POINT, RT_TANGENT, or RT_CV, and may or may
00480 //               not be or'ed with RT_KEEP_ORIG.  The meanings of the
00481 //               types are as follows:
00482 //
00483 //               RT_POINT defines a specific point which the curve
00484 //               segment must pass through.  t is in the range [0,1]
00485 //               and represents the parametric value at which the
00486 //               curve segment will intersect the given point.  If
00487 //               RT_KEEP_ORIG is not set, v defines the point;
00488 //               otherwise, v is ignored and the original curve at
00489 //               point t defines the point.
00490 //
00491 //               RT_TANGENT defines a specific tangent value which the
00492 //               curve segment must have at point t.  As with
00493 //               RT_POINT, if RT_KEEP_ORIG is not set, v defines the
00494 //               tangent; otherwise, v is ignored and the original
00495 //               curve defines the tangent.
00496 //
00497 //               RT_CV defines a specific control vertex which the
00498 //               curve segment must have.  In this case, t is ignored.
00499 //               The position within the argument list determines
00500 //               which control vertex is applicable; e.g. rtype0 =
00501 //               RT_CV defines control vertex 0, and rtype2 = RT_CV
00502 //               defines control vertex 2.  If RT_KEEP_ORIG is not
00503 //               set, v defines the new control vertex; otherwise, the
00504 //               control vertex is taken from G.
00505 //
00506 //               The return value is true if all the parameters are
00507 //               sensible, or false if there is some error.
00508 ////////////////////////////////////////////////////////////////////
00509 bool CubicCurveseg::
00510 compute_seg(int rtype0, float t0, const LVecBase4f &v0,
00511             int rtype1, float t1, const LVecBase4f &v1,
00512             int rtype2, float t2, const LVecBase4f &v2,
00513             int rtype3, float t3, const LVecBase4f &v3,
00514             const LMatrix4f &B,
00515             const LMatrix4f &Bi,
00516             LMatrix4f &G) {
00517 
00518   // We can define a cubic curve segment given four arbitrary
00519   // properties of the segment: any point along the curve, any tangent
00520   // along the curve, any control point.  Given any four such
00521   // properties, a single cubic curve segment is defined.
00522 
00523   // For a given cubic curve segment so defined, and given a basis
00524   // matrix B, we can define the four control vertices that represent
00525   // the segment with the basis matrix.  That is, we can define the
00526   // matrix G such that G * B * tc, where tc is [ t^3 t^2 t^1 t^0 ]
00527   // for t in [ 0..1 ], represents the point on the curve segment
00528   // corresponding to t.
00529 
00530   // First, we build a matrix T, such that each of the four columns of
00531   // T contains the vector that would compute the corresponding
00532   // property.  We also build a corresponding matrix P, such that each
00533   // of its columns contains the vector that is the solution of the
00534   // corresponding column in T.
00535 
00536   LMatrix4f T, P, GB;
00537 
00538   // GB is G * B, but we only need to compute this if any of the
00539   // columns wants the value from the original G.
00540   if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
00541     GB = G * B;
00542   }
00543 
00544   if (! (compute_seg_col(0, rtype0, t0, v0, B, Bi, G, GB, T, P) &&
00545          compute_seg_col(1, rtype1, t1, v1, B, Bi, G, GB, T, P) &&
00546          compute_seg_col(2, rtype2, t2, v2, B, Bi, G, GB, T, P) &&
00547          compute_seg_col(3, rtype3, t3, v3, B, Bi, G, GB, T, P))) {
00548     return false;
00549   }
00550 
00551   LMatrix4f Ti;
00552   Ti = invert(T);
00553 
00554   // Now we have T and P such that P represents the solution of T,
00555   // when T is applied to the geometry and basis matrices.  That is,
00556   // each column of P represents the solution computed by the
00557   // corresponding column of T.  P = G * B * T.
00558 
00559   // We simply solve for G and get G = P * T^(-1) * B^(-1).
00560 
00561   G = P * Ti * Bi;
00562 
00563   return true;
00564 }
00565 
00566 ////////////////////////////////////////////////////////////////////
00567 //     Function: CubicCurveseg::register_with_factory
00568 //       Access: Public, Static
00569 //  Description: Initializes the factory for reading these things from
00570 //               Bam files.
00571 ////////////////////////////////////////////////////////////////////
00572 void CubicCurveseg::
00573 register_with_read_factory() {
00574   BamReader::get_factory()->register_factory(get_class_type(), make_CubicCurveseg);
00575 }
00576 
00577 ////////////////////////////////////////////////////////////////////
00578 //     Function: CubicCurveseg::make_CubicCurveseg
00579 //       Access: Protected
00580 //  Description: Factory method to generate an object of this type.
00581 ////////////////////////////////////////////////////////////////////
00582 TypedWritable *CubicCurveseg::
00583 make_CubicCurveseg(const FactoryParams &params) {
00584   CubicCurveseg *me = new CubicCurveseg;
00585   DatagramIterator scan;
00586   BamReader *manager;
00587 
00588   parse_params(params, scan, manager);
00589   me->fillin(scan, manager);
00590   return me;
00591 }
00592 
00593 ////////////////////////////////////////////////////////////////////
00594 //     Function: CubicCurveseg::write_datagram
00595 //       Access: Protected, Virtual
00596 //  Description: Function to write the important information in
00597 //               the particular object to a Datagram
00598 ////////////////////////////////////////////////////////////////////
00599 void CubicCurveseg::
00600 write_datagram(BamWriter *manager, Datagram &me) {
00601   ParametricCurve::write_datagram(manager, me);
00602 
00603   Bx.write_datagram(me);
00604   By.write_datagram(me);
00605   Bz.write_datagram(me);
00606   Bw.write_datagram(me);
00607   me.add_bool(rational);
00608 }
00609 
00610 ////////////////////////////////////////////////////////////////////
00611 //     Function: CubicCurveseg::fillin
00612 //       Access: Protected
00613 //  Description: Function that reads out of the datagram (or asks
00614 //               manager to read) all of the data that is needed to
00615 //               re-create this object and stores it in the appropiate
00616 //               place
00617 ////////////////////////////////////////////////////////////////////
00618 void CubicCurveseg::
00619 fillin(DatagramIterator &scan, BamReader *manager) {
00620   ParametricCurve::fillin(scan, manager);
00621 
00622   Bx.read_datagram(scan);
00623   By.read_datagram(scan);
00624   Bz.read_datagram(scan);
00625   Bw.read_datagram(scan);
00626   rational = scan.get_bool();
00627 }

Generated on Fri May 2 00:40:41 2003 for Panda by doxygen1.3