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