Panda3D
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  */
20 clear(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  */
30 append_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  */
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  */
75 LVecBase4 NurbsBasisVector::
76 nurbs_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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear(int order)
Removes all the segments from the curve.