Panda3D
Loading...
Searching...
No Matches
nurbsBasisVector.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file nurbsBasisVector.cxx
10 * @author drose
11 * @date 2002-12-03
12 */
13
14#include "nurbsBasisVector.h"
15
16/**
17 * Removes all the segments from the curve.
18 */
20clear(int order) {
21 _order = order;
22 _segments.clear();
23}
24
25/**
26 * Computes a NURBS basis for one segment of the curve and appends it to the
27 * set of basis matrices.
28 */
30append_segment(int vertex_index, const PN_stdfloat knots[]) {
31 int i;
32
33 // Scale the supplied knots to the range 0..1.
34 PN_stdfloat scaled_knots[8];
35 PN_stdfloat min_k = knots[_order - 1];
36 PN_stdfloat max_k = knots[_order];
37
38 nassertv(min_k != max_k);
39 for (i = 0; i < _order + _order; i++) {
40 scaled_knots[i] = (knots[i] - min_k) / (max_k - min_k);
41 }
42
43 Segment segment;
44 segment._vertex_index = vertex_index;
45 segment._from = min_k;
46 segment._to = max_k;
47
48 for (i = 0; i < _order; i++) {
49 LVecBase4 b = nurbs_blending_function(_order, i, _order, scaled_knots);
50 segment._basis.set_col(i, b);
51 }
52
53 for (i = _order; i < 4; i++) {
54 segment._basis.set_col(i, LVecBase4::zero());
55 }
56
57 _segments.push_back(segment);
58}
59
60/**
61 * Transposes the basis matrices stored in the vector.
62 */
64transpose() {
65 Segments::iterator si;
66 for (si = _segments.begin(); si != _segments.end(); ++si) {
67 (*si)._basis.transpose_in_place();
68 }
69}
70
71/**
72 * Recursively computes the appropriate blending function for the indicated
73 * knot vector.
74 */
75LVecBase4 NurbsBasisVector::
76nurbs_blending_function(int order, int i, int j, const PN_stdfloat knots[]) {
77 // This is doubly recursive. Ick.
78 LVecBase4 r;
79
80 if (j == 1) {
81 if (i == order - 1 && knots[i] < knots[i + 1]) {
82 r.set(0.0f, 0.0f, 0.0f, 1.0f);
83 } else {
84 r.set(0.0f, 0.0f, 0.0f, 0.0f);
85 }
86
87 } else {
88 LVecBase4 bi0 = nurbs_blending_function(order, i, j - 1, knots);
89 LVecBase4 bi1 = nurbs_blending_function(order, i + 1, j - 1, knots);
90
91 PN_stdfloat d0 = knots[i + j - 1] - knots[i];
92 PN_stdfloat d1 = knots[i + j] - knots[i + 1];
93
94 // First term. Division by zero is defined to equal zero.
95 if (d0 != 0.0f) {
96 if (d1 != 0.0f) {
97 r = bi0 / d0 - bi1 / d1;
98 } else {
99 r = bi0 / d0;
100 }
101
102 } else if (d1 != 0.0f) {
103 r = - bi1 / d1;
104
105 } else {
106 r.set(0.0f, 0.0f, 0.0f, 0.0f);
107 }
108
109 // scale by t.
110 r[0] = r[1];
111 r[1] = r[2];
112 r[2] = r[3];
113 r[3] = 0.0f;
114
115 // Second term.
116 if (d0 != 0.0f) {
117 if (d1 != 0.0f) {
118 r += bi0 * (- knots[i] / d0) + bi1 * (knots[i + j] / d1);
119 } else {
120 r += bi0 * (- knots[i] / d0);
121 }
122
123 } else if (d1 != 0.0f) {
124 r += bi1 * (knots[i + j] / d1);
125 }
126 }
127
128 return r;
129}
void transpose()
Transposes the basis matrices stored in the vector.
void append_segment(int vertex_index, const PN_stdfloat knots[])
Computes a NURBS basis for one segment of the curve and appends it to the set of basis matrices.
void clear(int order)
Removes all the segments from the curve.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.