15 #include "nurbsCurveResult.h" 16 #include "nurbsVertex.h" 37 _composed.reserve(num_segments);
38 for (
int i = 0; i < num_segments; i++) {
40 nassertv(vi >= 0 && vi + order - 1 < num_vertices);
46 geom.
set_row(ci, vecs[vi + ci]);
57 result.multiply(_basis.
get_basis(i), geom);
58 _composed.push_back(result);
85 PN_stdfloat weight = tvec.dot(_composed[segment].get_col(3));
87 point.set(tvec.dot(_composed[segment].get_col(0)) / weight,
88 tvec.dot(_composed[segment].get_col(1)) / weight,
89 tvec.dot(_composed[segment].get_col(2)) / weight);
102 PN_stdfloat t2 = t*t;
103 LVecBase4 tvec(3.0 * t2, 2.0 * t, 1.0f, 0.0f);
105 tangent.set(tvec.dot(_composed[segment].get_col(0)),
106 tvec.dot(_composed[segment].get_col(1)),
107 tvec.dot(_composed[segment].get_col(2)));
121 PN_stdfloat t2 = t*t;
124 PN_stdfloat weight = tvec.dot(_composed[segment].get_col(3));
149 return tvec.dot(composed_geom) / weight;
163 PN_stdfloat result[],
int num_values)
const {
166 PN_stdfloat t2 = t*t;
169 PN_stdfloat weight = tvec.dot(_composed[segment].get_col(3));
177 for (
int n = 0; n < num_values; n++) {
194 result[n] = tvec.dot(composed_geom) / weight;
212 PN_stdfloat tolerance_2 = tolerance * tolerance;
213 _adaptive_result.clear();
218 for (
int segment = 0; segment < num_segments; ++segment) {
223 _adaptive_result.push_back(AdaptiveSample(_basis.
get_from(segment), p0));
229 r_adaptive_sample(segment, 0.0f, p0, 1.0f, p1, tolerance_2);
240 int NurbsCurveResult::
241 find_segment(PN_stdfloat t) {
251 if (_last_segment != -1 && (t >= _last_from && t < _last_to)) {
252 return _last_segment;
258 _last_segment = segment;
259 _last_from = _basis.
get_from(segment);
260 _last_to = _basis.
get_to(segment);
273 int NurbsCurveResult::
274 r_find_segment(PN_stdfloat t,
int top,
int bot)
const {
279 int mid = (top + bot) / 2;
282 PN_stdfloat from = _basis.
get_from(mid);
283 PN_stdfloat to = _basis.
get_to(mid);
286 return r_find_segment(t, top, mid - 1);
288 }
else if (to <= t) {
290 return r_find_segment(t, mid + 1, bot);
306 void NurbsCurveResult::
307 r_adaptive_sample(
int segment, PN_stdfloat t0,
const LPoint3 &p0,
308 PN_stdfloat t1,
const LPoint3 &p1, PN_stdfloat tolerance_2) {
309 PN_stdfloat tmid = (t0 + t1) * 0.5f;
313 if (sqr_dist_to_line(pmid, p0, p1 - p0) > tolerance_2) {
315 r_adaptive_sample(segment, t0, p0, tmid, pmid, tolerance_2);
316 r_adaptive_sample(segment, tmid, pmid, t1, p1, tolerance_2);
320 _adaptive_result.push_back(AdaptiveSample(_basis.
scale_t(segment, t1), p1));
331 PN_stdfloat NurbsCurveResult::
338 PN_stdfloat leg = d.dot(norm);
339 return hyp_2 - leg * leg;
float length_squared() const
Returns the square of the vector's length, cheap and easy.
void eval_segment_extended_points(int segment, PN_stdfloat t, int d, PN_stdfloat result[], int num_values) const
Simultaneously performs eval_extended_point on a contiguous sequence of dimensions.
This is the base class for all three-component vectors and points.
PN_stdfloat eval_segment_extended_point(int segment, PN_stdfloat t, int d) const
Evaluates the curve in n-dimensional space according to the extended vertices associated with the cur...
const LMatrix4 & get_basis(int segment) const
Returns the basis matrix associated with the nth segment.
int get_num_segments() const
Returns the number of piecewise continuous segments in the curve.
PN_stdfloat get_from(int segment) const
Returns the t value of the beginning of this segment.
int get_vertex_index(int segment) const
Returns the vertex index of the nth segment.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
PN_stdfloat get_to(int segment) const
Returns the t value of the end of this segment.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
void eval_segment_tangent(int segment, PN_stdfloat t, LVecBase3 &tangent) const
As eval_segment_point, but computes the tangent to the curve at the indicated point.
bool almost_equal(const LVecBase3f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
void eval_segment_point(int segment, PN_stdfloat t, LVecBase3 &point) const
Evaluates the point on the curve corresponding to the indicated value in parametric time within the i...
This represents a single control vertex in a NurbsEvaluator.
NurbsCurveResult(const NurbsBasisVector &basis, const LVecBase4 vecs[], const NurbsVertex *verts, int num_vertices)
The constructor automatically builds up the result as the product of the indicated set of basis matri...
int get_order() const
Returns the order of the segments in the curve.
This encapsulates a series of matrices that are used to represent the sequential segments of a NurbsC...
This is a 4-by-4 transform matrix.
PN_stdfloat scale_t(int segment, PN_stdfloat t) const
Scales the value of t into the range [0, 1] corresponding to [from, to].
PN_stdfloat get_start_t() const
Returns the first legal value of t on the curve.
This is the base class for all three-component vectors and points.
PN_stdfloat get_extended_vertex(int d) const
Returns an n-dimensional vertex value.
LVecBase4f get_row(int row) const
Retrieves the indicated row of the matrix as a 4-component vector.
PN_stdfloat get_end_t() const
Returns the last legal value of t on the curve.
void adaptive_sample(PN_stdfloat tolerance)
Determines the set of subdivisions necessary to approximate the curve with a set of linear segments...
void set_row(int row, const LVecBase4f &v)
Replaces the indicated row of the matrix.
bool normalize()
Normalizes the vector in place.
static const LVecBase4f & zero()
Returns a zero-length vector.