Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/parametrics/nurbsMatrixVector.cxx

Go to the documentation of this file.
00001 // Filename: nurbsMatrixVector.cxx
00002 // Created by:  drose (03Dec02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "nurbsMatrixVector.h"
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: NurbsMatrixVector::clear
00023 //       Access: Public
00024 //  Description: Removes all the segments from the curve.
00025 ////////////////////////////////////////////////////////////////////
00026 void NurbsMatrixVector::
00027 clear() {
00028   _segments.clear();
00029 }
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: NurbsMatrixVector::append_segment
00033 //       Access: Public
00034 //  Description: Computes a NURBS basis for one segment of the curve
00035 //               and appends it to the set of basis matrices.
00036 ////////////////////////////////////////////////////////////////////
00037 void NurbsMatrixVector::
00038 append_segment(int order, int vertex_index, const float knots[]) {
00039   int i;
00040 
00041   // Scale the supplied knots to the range 0..1.
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 //     Function: NurbsMatrixVector::compose_segment
00070 //       Access: Public
00071 //  Description: Appends a new segment to the vector by composing the
00072 //               indicated geometry matrix with the indicated basis
00073 //               matrix from the given vector.
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 //     Function: NurbsMatrixVector::nurbs_blending_function
00092 //       Access: Private, Static
00093 //  Description: Recursively computes the appropriate blending
00094 //               function for the indicated knot vector.
00095 ////////////////////////////////////////////////////////////////////
00096 LVecBase4f NurbsMatrixVector::
00097 nurbs_blending_function(int order, int i, int j, const float knots[]) {
00098   // This is doubly recursive.  Ick.
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     // First term.  Division by zero is defined to equal zero.
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     // scale by t.
00131     r[0] = r[1];
00132     r[1] = r[2];
00133     r[2] = r[3];
00134     r[3] = 0.0f;
00135 
00136     // Second term.
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 }

Generated on Fri May 2 00:40:46 2003 for Panda by doxygen1.3