00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "nurbsMatrixVector.h"
00020
00021
00022
00023
00024
00025
00026 void NurbsMatrixVector::
00027 clear() {
00028 _segments.clear();
00029 }
00030
00031
00032
00033
00034
00035
00036
00037 void NurbsMatrixVector::
00038 append_segment(int order, int vertex_index, const float knots[]) {
00039 int i;
00040
00041
00042 float scaled_knots[8];
00043 float min_k = knots[order - 1];
00044 float max_k = knots[order];
00045
00046 nassertv(min_k != max_k);
00047 for (i = 0; i < order + order; i++) {
00048 scaled_knots[i] = (knots[i] - min_k) / (max_k - min_k);
00049 }
00050
00051 Segment segment;
00052 segment._vertex_index = vertex_index;
00053 segment._from = min_k;
00054 segment._to = max_k;
00055
00056 for (i = 0; i < order; i++) {
00057 LVecBase4f b = nurbs_blending_function(order, i, order, scaled_knots);
00058 segment._matrix.set_col(i, b);
00059 }
00060
00061 for (i = order; i < 4; i++) {
00062 segment._matrix.set_col(i, LVecBase4f::zero());
00063 }
00064
00065 _segments.push_back(segment);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 void NurbsMatrixVector::
00076 compose_segment(const NurbsMatrixVector &basis, int segment,
00077 const LMatrix4f &geom) {
00078 nassertv(segment >= 0 && segment < (int)basis._segments.size());
00079 const Segment &source = basis._segments[segment];
00080
00081 Segment dest;
00082 dest._vertex_index = source._vertex_index;
00083 dest._from = source._from;
00084 dest._to = source._to;
00085 dest._matrix = source._matrix * geom;
00086
00087 _segments.push_back(dest);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 LVecBase4f NurbsMatrixVector::
00097 nurbs_blending_function(int order, int i, int j, const float knots[]) {
00098
00099 LVecBase4f r;
00100
00101 if (j == 1) {
00102 if (i == order-1 && knots[i] < knots[i+1]) {
00103 r.set(0.0f, 0.0f, 0.0f, 1.0f);
00104 } else {
00105 r.set(0.0f, 0.0f, 0.0f, 0.0f);
00106 }
00107
00108 } else {
00109 LVecBase4f bi0 = nurbs_blending_function(order, i, j - 1, knots);
00110 LVecBase4f bi1 = nurbs_blending_function(order, i + 1, j - 1, knots);
00111
00112 float d0 = knots[i + j - 1] - knots[i];
00113 float d1 = knots[i + j] - knots[i + 1];
00114
00115
00116 if (d0 != 0.0f) {
00117 if (d1 != 0.0f) {
00118 r = bi0 / d0 - bi1 / d1;
00119 } else {
00120 r = bi0 / d0;
00121 }
00122
00123 } else if (d1 != 0.0f) {
00124 r = - bi1 / d1;
00125
00126 } else {
00127 r.set(0.0f, 0.0f, 0.0f, 0.0f);
00128 }
00129
00130
00131 r[0] = r[1];
00132 r[1] = r[2];
00133 r[2] = r[3];
00134 r[3] = 0.0f;
00135
00136
00137 if (d0 != 0.0f) {
00138 if (d1 != 0.0f) {
00139 r += bi0 * (- knots[i] / d0) + bi1 * (knots[i + j] / d1);
00140 } else {
00141 r += bi0 * (- knots[i] / d0);
00142 }
00143
00144 } else if (d1 != 0.0f) {
00145 r += bi1 * (knots[i + j] / d1);
00146 }
00147 }
00148
00149 return r;
00150 }