38 CubicCurveseg(
const LMatrix4 &basis) {
39 Bx = basis.get_col(0);
40 By = basis.get_col(1);
41 Bz = basis.get_col(2);
42 Bw = basis.get_col(3);
61 CubicCurveseg(
int order,
const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
79 PN_stdfloat t_sqrd = t*t;
80 evaluate_point(LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
89 evaluate_vector(LVecBase4(3.0f*t*t, 2.0f*t, 1.0f, 0.0f), tangent);
98 get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent)
const {
99 PN_stdfloat t_sqrd=t*t;
100 evaluate_point(LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
101 evaluate_vector(LVecBase4(3.0f*t_sqrd, t+t, 1.0f, 0.0f), tangent);
110 evaluate_vector(LVecBase4(6.0f*t, 2.0f, 0.0f, 0.0f), tangent2);
123 PN_stdfloat tlength) {
125 Mh( 2.0f, -3.0f, 0.0f, 1.0f,
126 -2.0f, 3.0f, 0.0f, 0.0f,
127 1.0f, -2.0f, 1.0f, 0.0f,
128 1.0f, -1.0f, 0.0f, 0.0f);
130 LVecBase4 Gx(cv0._p[0], cv1._p[0],
131 cv0._out[0]*tlength, cv1._in[0]*tlength);
132 LVecBase4 Gy(cv0._p[1], cv1._p[1],
133 cv0._out[1]*tlength, cv1._in[1]*tlength);
134 LVecBase4 Gz(cv0._p[2], cv1._p[2],
135 cv0._out[2]*tlength, cv1._in[2]*tlength);
151 Mb(-1.0f, 3.0f, -3.0f, 1.0f,
152 3.0f, -6.0f, 3.0f, 0.0f,
153 -3.0f, 3.0f, 0.0f, 0.0f,
154 1.0f, 0.0f, 0.0f, 0.0f);
156 LVecBase4 Gx(seg._v[0][0], seg._v[1][0], seg._v[2][0], seg._v[3][0]);
157 LVecBase4 Gy(seg._v[0][1], seg._v[1][1], seg._v[2][1], seg._v[3][1]);
158 LVecBase4 Gz(seg._v[0][2], seg._v[1][2], seg._v[2][2], seg._v[3][2]);
167 nurbs_blending_function(
int order,
int i,
int j,
168 const PN_stdfloat knots[]) {
173 if (i==order-1 && knots[i] < knots[i+1]) {
174 r.set(0.0f, 0.0f, 0.0f, 1.0f);
176 r.set(0.0f, 0.0f, 0.0f, 0.0f);
180 LVecBase4 bi0 = nurbs_blending_function(order, i, j-1, knots);
181 LVecBase4 bi1 = nurbs_blending_function(order, i+1, j-1, knots);
183 PN_stdfloat d0 = knots[i+j-1] - knots[i];
184 PN_stdfloat d1 = knots[i+j] - knots[i+1];
189 r = bi0 / d0 - bi1 / d1;
194 }
else if (d1 != 0.0f) {
198 r.set(0.0f, 0.0f, 0.0f, 0.0f);
210 r += bi0 * (- knots[i] / d0) + bi1 * (knots[i+j] / d1);
212 r += bi0 * (- knots[i] / d0);
215 }
else if (d1 != 0.0f) {
216 r += bi1 * (knots[i+j] / d1);
224 compute_nurbs_basis(
int order,
225 const PN_stdfloat knots_in[],
230 PN_stdfloat knots[8];
231 PN_stdfloat mink = knots_in[order-1];
232 PN_stdfloat maxk = knots_in[order];
236 parametrics_cat->warning()
237 <<
"Trivial NURBS curve specified." << std::endl;
238 memset((
void *)&basis, 0,
sizeof(LMatrix4));
242 for (i = 0; i<2*order; i++) {
243 knots[i] = (knots_in[i] - mink) / (maxk-mink);
248 for (i = 0; i<order; i++) {
249 b[i] = nurbs_blending_function(order, i, order, knots);
252 for (i = 0; i<order; i++) {
253 basis.set_row(i, b[i]);
256 for (i=order; i<4; i++) {
257 basis.set_row(i, LVecBase4::zero());
269 nurbs_basis(
int order,
const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
270 assert(order>=1 && order<=4);
273 compute_nurbs_basis(order, knots, B);
277 for (
int i = 0; i < 4; i++) {
278 c[i] = (i<order) ? cvs[i] : LVecBase4(0.0f, 0.0f, 0.0f, 0.0f);
281 Bx = LVecBase4(c[0][0], c[1][0], c[2][0], c[3][0]) * B;
282 By = LVecBase4(c[0][1], c[1][1], c[2][1], c[3][1]) * B;
283 Bz = LVecBase4(c[0][2], c[1][2], c[2][2], c[3][2]) * B;
284 Bw = LVecBase4(c[0][3], c[1][3], c[2][3], c[3][3]) * B;
297 Mbi(0.0f, 0.0f, 0.0f, 1.0f,
298 0.0f, 0.0f, 1.0f/3.0f, 1.0f,
299 0.0f, 1.0f/3.0f, 2.0f/3.0f, 1.0f,
300 1.0f, 1.0f, 1.0f, 1.0f);
302 LVecBase4 Gx = Bx * Mbi;
303 LVecBase4 Gy = By * Mbi;
304 LVecBase4 Gz = Bz * Mbi;
307 LVecBase4 Gw = Bw * Mbi;
308 seg._v[0].set(Gx[0]/Gw[0], Gy[0]/Gw[0], Gz[0]/Gw[0]);
309 seg._v[1].set(Gx[1]/Gw[1], Gy[1]/Gw[1], Gz[1]/Gw[1]);
310 seg._v[2].set(Gx[2]/Gw[2], Gy[2]/Gw[2], Gz[2]/Gw[2]);
311 seg._v[3].set(Gx[3]/Gw[3], Gy[3]/Gw[3], Gz[3]/Gw[3]);
313 seg._v[0].set(Gx[0], Gy[0], Gz[0]);
314 seg._v[1].set(Gx[1], Gy[1], Gz[1]);
315 seg._v[2].set(Gx[2], Gy[2], Gz[2]);
316 seg._v[3].set(Gx[3], Gy[3], Gz[3]);
324 col_mult(
const LMatrix4 &M,
const LVecBase4 &v) {
325 return LVecBase4(M(0,0)*v[0] + M(0,1)*v[1] + M(0,2)*v[2] + M(0,3)*v[3],
326 M(1,0)*v[0] + M(1,1)*v[1] + M(1,2)*v[2] + M(1,3)*v[3],
327 M(2,0)*v[0] + M(2,1)*v[1] + M(2,2)*v[2] + M(2,3)*v[3],
328 M(3,0)*v[0] + M(3,1)*v[1] + M(3,2)*v[2] + M(3,3)*v[3]);
336 compute_seg_col(
int c,
337 int rtype, PN_stdfloat t,
const LVecBase4 &v,
342 LMatrix4 &T, LMatrix4 &P) {
343 bool keep_orig = ((rtype & RT_KEEP_ORIG) != 0);
345 if (parametrics_cat.is_debug()) {
346 parametrics_cat.debug()
347 <<
"Computing col " << c <<
" type " << (rtype & RT_BASE_TYPE)
348 <<
" at " << t <<
" keep_orig = " << keep_orig
349 <<
" v = " << v <<
"\n";
352 switch (rtype & RT_BASE_TYPE) {
355 PN_stdfloat t_sqrd,t_cubed;
360 T.set_col(c, LVecBase4(t_cubed, t_sqrd, t, 1.0f));
362 LVecBase4 vec(t_cubed, t_sqrd, t, 1.0f);
363 LVecBase4 ov = col_mult(GB, vec);
364 if (parametrics_cat.is_debug()) {
365 parametrics_cat.debug()
366 <<
"orig point = " << ov <<
"\n";
378 T.set_col(c, LVecBase4(3.0f*t_sqrd, t+t, 1.0f, 0.0f));
380 LVecBase4 vec(3.0f*t_sqrd, t+t, 1.0f, 0.0f);
381 LVecBase4 ov = col_mult(GB, vec);
382 if (parametrics_cat.is_debug()) {
383 parametrics_cat.debug()
385 GB.write(parametrics_cat.debug(
false), 2);
386 parametrics_cat.debug(
false)
387 <<
"vector is " << vec <<
"\n" 388 <<
"orig tangent = " << ov <<
"\n";
399 T.set_col(c, Bi.get_col(c));
401 if (parametrics_cat.is_debug()) {
402 parametrics_cat.debug()
403 <<
"orig CV = " << G.get_col(c) <<
"\n";
405 P.set_col(c, G.get_col(c));
412 std::cerr <<
"Invalid rebuild type in compute_seg\n";
460 int rtype1, PN_stdfloat t1,
const LVecBase4 &v1,
461 int rtype2, PN_stdfloat t2,
const LVecBase4 &v2,
462 int rtype3, PN_stdfloat t3,
const LVecBase4 &v3,
488 if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
492 if (! (compute_seg_col(0, rtype0, t0, v0, B, Bi, G, GB, T, P) &&
493 compute_seg_col(1, rtype1, t1, v1, B, Bi, G, GB, T, P) &&
494 compute_seg_col(2, rtype2, t2, v2, B, Bi, G, GB, T, P) &&
495 compute_seg_col(3, rtype3, t3, v3, B, Bi, G, GB, T, P))) {
532 me->fillin(scan, manager);
542 ParametricCurve::write_datagram(manager, me);
544 Bx.write_datagram(me);
545 By.write_datagram(me);
546 Bz.write_datagram(me);
547 Bw.write_datagram(me);
558 ParametricCurve::fillin(scan, manager);
560 Bx.read_datagram(scan);
561 By.read_datagram(scan);
562 Bz.read_datagram(scan);
563 Bw.read_datagram(scan);
bool get_bool()
Extracts a boolean value.
virtual bool get_point(PN_stdfloat t, LVecBase3 &point) const
Computes the surface point at a given parametric point t.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void hermite_basis(const HermiteCurveCV &cv0, const HermiteCurveCV &cv1, PN_stdfloat tlength=1.0f)
Defines the curve segment as a Hermite.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void bezier_basis(const BezierSeg &seg)
Defines the curve segment as a Bezier.
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 ...
virtual bool get_2ndtangent(PN_stdfloat t, LVecBase3 &tangent2) const
Computes the surface 2nd-order tangent at a given parametric point t.
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors,...
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_bool(bool value)
Adds a boolean value to the datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
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.
virtual bool get_bezier_seg(BezierSeg &seg) const
Fills the BezierSeg structure with a description of the curve segment as a Bezier,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static bool compute_seg(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, const LMatrix4 &B, const LMatrix4 &Bi, LMatrix4 &G)
Given a set of four properties of a curve segment (e.g.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
A single CV of a Hermite curve.
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
void nurbs_basis(int order, const PN_stdfloat knots[], const LVecBase4 cvs[])
Defines the curve segment as a NURBS.
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
virtual bool get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent) const
Simultaneously computes the point and the tangent at the given parametric point.
virtual bool get_tangent(PN_stdfloat t, LVecBase3 &tangent) const
Computes the surface tangent at a given parametric point t.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.