Panda3D

nurbsBasisVector.cxx

00001 // Filename: nurbsBasisVector.cxx
00002 // Created by:  drose (03Dec02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "nurbsBasisVector.h"
00016 
00017 ////////////////////////////////////////////////////////////////////
00018 //     Function: NurbsBasisVector::clear
00019 //       Access: Public
00020 //  Description: Removes all the segments from the curve.
00021 ////////////////////////////////////////////////////////////////////
00022 void NurbsBasisVector::
00023 clear(int order) {
00024   _order = order;
00025   _segments.clear();
00026 }
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: NurbsBasisVector::append_segment
00030 //       Access: Public
00031 //  Description: Computes a NURBS basis for one segment of the curve
00032 //               and appends it to the set of basis matrices.
00033 ////////////////////////////////////////////////////////////////////
00034 void NurbsBasisVector::
00035 append_segment(int vertex_index, const PN_stdfloat knots[]) {
00036   int i;
00037 
00038   // Scale the supplied knots to the range 0..1.
00039   PN_stdfloat scaled_knots[8];
00040   PN_stdfloat min_k = knots[_order - 1];
00041   PN_stdfloat max_k = knots[_order];
00042 
00043   nassertv(min_k != max_k);
00044   for (i = 0; i < _order + _order; i++) {
00045     scaled_knots[i] = (knots[i] - min_k) / (max_k - min_k);
00046   }
00047 
00048   Segment segment;
00049   segment._vertex_index = vertex_index;
00050   segment._from = min_k;
00051   segment._to = max_k;
00052 
00053   for (i = 0; i < _order; i++) {
00054     LVecBase4 b = nurbs_blending_function(_order, i, _order, scaled_knots);
00055     segment._basis.set_col(i, b);
00056   }
00057 
00058   for (i = _order; i < 4; i++) {
00059     segment._basis.set_col(i, LVecBase4::zero());
00060   }
00061 
00062   _segments.push_back(segment);
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: NurbsBasisVector::transpose
00067 //       Access: Public
00068 //  Description: Transposes the basis matrices stored in the vector.
00069 ////////////////////////////////////////////////////////////////////
00070 void NurbsBasisVector::
00071 transpose() {
00072   Segments::iterator si;
00073   for (si = _segments.begin(); si != _segments.end(); ++si) {
00074     (*si)._basis.transpose_in_place();
00075   }
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: NurbsBasisVector::nurbs_blending_function
00080 //       Access: Private, Static
00081 //  Description: Recursively computes the appropriate blending
00082 //               function for the indicated knot vector.
00083 ////////////////////////////////////////////////////////////////////
00084 LVecBase4 NurbsBasisVector::
00085 nurbs_blending_function(int order, int i, int j, const PN_stdfloat knots[]) {
00086   // This is doubly recursive.  Ick.
00087   LVecBase4 r;
00088 
00089   if (j == 1) {
00090     if (i == order - 1 && knots[i] < knots[i + 1]) {
00091       r.set(0.0f, 0.0f, 0.0f, 1.0f);
00092     } else {
00093       r.set(0.0f, 0.0f, 0.0f, 0.0f);
00094     }
00095 
00096   } else {
00097     LVecBase4 bi0 = nurbs_blending_function(order, i, j - 1, knots);
00098     LVecBase4 bi1 = nurbs_blending_function(order, i + 1, j - 1, knots);
00099 
00100     PN_stdfloat d0 = knots[i + j - 1] - knots[i];
00101     PN_stdfloat d1 = knots[i + j] - knots[i + 1];
00102 
00103     // First term.  Division by zero is defined to equal zero.
00104     if (d0 != 0.0f) {
00105       if (d1 != 0.0f) {
00106         r = bi0 / d0 - bi1 / d1;
00107       } else {
00108         r = bi0 / d0;
00109       }
00110 
00111     } else if (d1 != 0.0f) {
00112       r = - bi1 / d1;
00113 
00114     } else {
00115       r.set(0.0f, 0.0f, 0.0f, 0.0f);
00116     }
00117 
00118     // scale by t.
00119     r[0] = r[1];
00120     r[1] = r[2];
00121     r[2] = r[3];
00122     r[3] = 0.0f;
00123 
00124     // Second term.
00125     if (d0 != 0.0f) {
00126       if (d1 != 0.0f) {
00127         r += bi0 * (- knots[i] / d0) + bi1 * (knots[i + j] / d1);
00128       } else {
00129         r += bi0 * (- knots[i] / d0);
00130       }
00131 
00132     } else if (d1 != 0.0f) {
00133       r += bi1 * (knots[i + j] / d1);
00134     }
00135   }
00136 
00137   return r;
00138 }
 All Classes Functions Variables Enumerations