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 }
NurbsBasisVector::clear
void clear(int order)
Removes all the segments from the curve.
Definition: nurbsBasisVector.cxx:20
nurbsBasisVector.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NurbsBasisVector::transpose
void transpose()
Transposes the basis matrices stored in the vector.
Definition: nurbsBasisVector.cxx:64
NurbsBasisVector::append_segment
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.
Definition: nurbsBasisVector.cxx:30