mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
first pass at NurbsCurveEvaluator
This commit is contained in:
parent
23d9bf4583
commit
340d20717e
@ -11,23 +11,33 @@
|
|||||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
classicNurbsCurve.I classicNurbsCurve.h config_parametrics.h \
|
classicNurbsCurve.I classicNurbsCurve.h config_parametrics.h \
|
||||||
cubicCurveseg.h parametricCurveDrawer.I \
|
cubicCurveseg.h parametricCurveDrawer.I \
|
||||||
parametricCurveDrawer.h curveFitter.I curveFitter.h \
|
parametricCurveDrawer.h curveFitter.I curveFitter.h \
|
||||||
hermiteCurve.h nurbsCurve.h nurbsCurveDrawer.I \
|
hermiteCurve.h nurbsCurve.h \
|
||||||
nurbsCurveDrawer.h nurbsCurveInterface.I \
|
nurbsCurveDrawer.I nurbsCurveDrawer.h \
|
||||||
nurbsCurveInterface.h parametricCurve.h \
|
nurbsCurveEvaluator.h \
|
||||||
parametricCurveCollection.I parametricCurveCollection.h \
|
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||||
piecewiseCurve.h \
|
nurbsCurveResult.I nurbsCurveResult.h \
|
||||||
$[if $[HAVE_NURBSPP], nurbsPPCurve.cxx nurbsPPCurve.h]
|
nurbsMatrixVector.I nurbsMatrixVector.h \
|
||||||
|
nurbsVertex.h nurbsVertex.I \
|
||||||
|
parametricCurve.h \
|
||||||
|
parametricCurveCollection.I parametricCurveCollection.h \
|
||||||
|
piecewiseCurve.h \
|
||||||
|
$[if $[HAVE_NURBSPP], nurbsPPCurve.cxx nurbsPPCurve.h]
|
||||||
|
|
||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
classicNurbsCurve.cxx config_parametrics.cxx cubicCurveseg.cxx \
|
classicNurbsCurve.cxx config_parametrics.cxx cubicCurveseg.cxx \
|
||||||
parametricCurveDrawer.cxx curveFitter.cxx hermiteCurve.cxx \
|
parametricCurveDrawer.cxx curveFitter.cxx hermiteCurve.cxx \
|
||||||
nurbsCurveDrawer.cxx nurbsCurveInterface.cxx \
|
nurbsCurveDrawer.cxx \
|
||||||
parametricCurve.cxx parametricCurveCollection.cxx \
|
nurbsCurveEvaluator.cxx \
|
||||||
piecewiseCurve.cxx
|
nurbsCurveResult.cxx \
|
||||||
|
nurbsCurveInterface.cxx \
|
||||||
|
nurbsMatrixVector.cxx \
|
||||||
|
nurbsVertex.cxx \
|
||||||
|
parametricCurve.cxx parametricCurveCollection.cxx \
|
||||||
|
piecewiseCurve.cxx
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
classicNurbsCurve.I classicNurbsCurve.h \
|
classicNurbsCurve.I classicNurbsCurve.h \
|
||||||
@ -38,7 +48,11 @@
|
|||||||
hermiteCurve.h \
|
hermiteCurve.h \
|
||||||
nurbsCurve.h \
|
nurbsCurve.h \
|
||||||
nurbsCurveDrawer.I nurbsCurveDrawer.h \
|
nurbsCurveDrawer.I nurbsCurveDrawer.h \
|
||||||
|
nurbsCurveEvaluator.h \
|
||||||
nurbsCurveInterface.I nurbsCurveInterface.h \
|
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||||
|
nurbsCurveResult.I nurbsCurveResult.h \
|
||||||
|
nurbsMatrixVector.I nurbsMatrixVector.h \
|
||||||
|
nurbsVertex.h nurbsVertex.I \
|
||||||
nurbsPPCurve.h \
|
nurbsPPCurve.h \
|
||||||
parametricCurve.h \
|
parametricCurve.h \
|
||||||
parametricCurveCollection.I parametricCurveCollection.h \
|
parametricCurveCollection.I parametricCurveCollection.h \
|
||||||
|
291
panda/src/parametrics/nurbsCurveEvaluator.cxx
Normal file
291
panda/src/parametrics/nurbsCurveEvaluator.cxx
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
// Filename: nurbsCurveEvaluator.cxx
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "nurbsCurveEvaluator.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsCurveEvaluator::
|
||||||
|
NurbsCurveEvaluator() {
|
||||||
|
_order = 4;
|
||||||
|
_knots_dirty = true;
|
||||||
|
_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsCurveEvaluator::
|
||||||
|
~NurbsCurveEvaluator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::set_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the order of the curve. This resets the knot
|
||||||
|
// vector to the default knot vector for the number of
|
||||||
|
// vertices.
|
||||||
|
//
|
||||||
|
// The order must be 1, 2, 3, or 4, and the value is one
|
||||||
|
// more than the degree of the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
set_order(int order) {
|
||||||
|
_order = order;
|
||||||
|
_knots_dirty = true;
|
||||||
|
_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the order of the curve as set by a previous
|
||||||
|
// call to set_order().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NurbsCurveEvaluator::
|
||||||
|
get_order() const {
|
||||||
|
return _order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::reset
|
||||||
|
// Access: Published
|
||||||
|
// Description: Resets all the vertices and knots to their default
|
||||||
|
// values, and sets the curve up with the indicated
|
||||||
|
// number of vertices. You must then call set_vertex()
|
||||||
|
// repeatedly to fill in all of the vertex values
|
||||||
|
// appropriately.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
reset(int num_vertices) {
|
||||||
|
_vertices.clear();
|
||||||
|
_vertices.reserve(num_vertices);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_vertices; i++) {
|
||||||
|
_vertices.push_back(NurbsVertex());
|
||||||
|
}
|
||||||
|
_knots_dirty = true;
|
||||||
|
_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_num_vertices
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of control vertices in the curve.
|
||||||
|
// This is the number passed to the last call to
|
||||||
|
// reset().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NurbsCurveEvaluator::
|
||||||
|
get_num_vertices() const {
|
||||||
|
return (int)_vertices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::set_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the nth control vertex of the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
set_vertex(int i, const LVecBase4f &vertex) {
|
||||||
|
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||||
|
_vertices[i].set_vertex(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the nth control vertex of the curve, relative
|
||||||
|
// to its indicated coordinate space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const LVecBase4f &NurbsCurveEvaluator::
|
||||||
|
get_vertex(int i) const {
|
||||||
|
nassertr(i >= 0 && i < (int)_vertices.size(), LVecBase4f::zero());
|
||||||
|
return _vertices[i].get_vertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::set_vertex_space
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the coordinate space of the nth control vertex.
|
||||||
|
// If this is not specified, or is set to an empty
|
||||||
|
// NodePath, the nth control vertex is deemed to be in
|
||||||
|
// the coordinate space passed to evaluate().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
set_vertex_space(int i, const NodePath &space) {
|
||||||
|
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||||
|
_vertices[i].set_space(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_vertex_space
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the coordinate space of the nth control
|
||||||
|
// vertex of the curve, expressed as a NodePath.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const NodePath &NurbsCurveEvaluator::
|
||||||
|
get_vertex_space(int i) const {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static NodePath empty_node_path;
|
||||||
|
nassertr(i >= 0 && i < (int)_vertices.size(), empty_node_path);
|
||||||
|
#endif
|
||||||
|
return _vertices[i].get_space();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_num_knots
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of knot values in the curve. This
|
||||||
|
// is based on the number of vertices and the order.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NurbsCurveEvaluator::
|
||||||
|
get_num_knots() const {
|
||||||
|
return (int)_vertices.size() + _order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::set_knot
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the value of the nth knot. Each knot value
|
||||||
|
// should be greater than or equal to the preceding
|
||||||
|
// value. If no knot values are set, a default knot
|
||||||
|
// vector is supplied.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
set_knot(int i, float knot) {
|
||||||
|
if (_knots_dirty) {
|
||||||
|
recompute_knots();
|
||||||
|
}
|
||||||
|
nassertv(i >= 0 && i < (int)_knots.size());
|
||||||
|
_knots[i] = knot;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::get_knot
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the value of the nth knot.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float NurbsCurveEvaluator::
|
||||||
|
get_knot(int i) const {
|
||||||
|
if (_knots_dirty) {
|
||||||
|
((NurbsCurveEvaluator *)this)->recompute_knots();
|
||||||
|
}
|
||||||
|
nassertr(i >= 0 && i < (int)_knots.size(), 0.0f);
|
||||||
|
return _knots[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::evaluate
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a NurbsCurveResult object that represents the
|
||||||
|
// result of applying the knots to all of the current
|
||||||
|
// values of the vertices, transformed into the
|
||||||
|
// indicated coordinate space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(NurbsCurveResult) NurbsCurveEvaluator::
|
||||||
|
evaluate(const NodePath &rel_to) {
|
||||||
|
if (_basis_dirty) {
|
||||||
|
((NurbsCurveEvaluator *)this)->recompute_basis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, transform the vertices as appropriate.
|
||||||
|
int num_vertices = (int)_vertices.size();
|
||||||
|
pvector<LVecBase4f> verts;
|
||||||
|
verts.reserve(num_vertices);
|
||||||
|
int vi;
|
||||||
|
for (vi = 0; vi < num_vertices; vi++) {
|
||||||
|
const NodePath &space = _vertices[vi].get_space();
|
||||||
|
const LVecBase4f &vertex = _vertices[vi].get_vertex();
|
||||||
|
if (space.is_empty()) {
|
||||||
|
verts.push_back(vertex);
|
||||||
|
} else {
|
||||||
|
const LMatrix4f &mat = space.get_mat(rel_to);
|
||||||
|
verts.push_back(vertex * mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And apply those transformed vertices to the basis matrices to
|
||||||
|
// derive the result.
|
||||||
|
return new NurbsCurveResult(_basis, _order, &verts[0], num_vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::recompute_knots
|
||||||
|
// Access: Private
|
||||||
|
// Description: Creates a default knot vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
recompute_knots() {
|
||||||
|
_knots.clear();
|
||||||
|
int num_knots = get_num_knots();
|
||||||
|
_knots.reserve(num_knots);
|
||||||
|
|
||||||
|
float value = 0.0f;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < _order) {
|
||||||
|
_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (i < num_knots - _order) {
|
||||||
|
value += 1.0f;
|
||||||
|
_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
value += 1.0f;
|
||||||
|
while (i < num_knots) {
|
||||||
|
_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_knots_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveEvaluator::recompute_basis
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recomputes the basis matrices according to the knot
|
||||||
|
// vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsCurveEvaluator::
|
||||||
|
recompute_basis() {
|
||||||
|
if (_knots_dirty) {
|
||||||
|
((NurbsCurveEvaluator *)this)->recompute_knots();
|
||||||
|
}
|
||||||
|
|
||||||
|
_basis.clear();
|
||||||
|
if ((int)_vertices.size() > _order - 1) {
|
||||||
|
int min_knot = _order;
|
||||||
|
int max_knot = (int)_vertices.size() + 1;
|
||||||
|
|
||||||
|
for (int i = min_knot; i <= max_knot; i++) {
|
||||||
|
nassertv(i - 1 >= 0 && i < (int)_knots.size());
|
||||||
|
if (_knots[i - 1] < _knots[i]) {
|
||||||
|
// Here's a non-empty segment.
|
||||||
|
_basis.append_segment(_order, i - _order, &_knots[i - _order]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_basis_dirty = false;
|
||||||
|
}
|
87
panda/src/parametrics/nurbsCurveEvaluator.h
Normal file
87
panda/src/parametrics/nurbsCurveEvaluator.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Filename: nurbsCurveEvaluator.h
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef NURBSCURVEEVALUATOR_H
|
||||||
|
#define NURBSCURVEEVALUATOR_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "nurbsMatrixVector.h"
|
||||||
|
#include "nurbsCurveResult.h"
|
||||||
|
#include "nurbsVertex.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "vector_float.h"
|
||||||
|
#include "pvector.h"
|
||||||
|
#include "nodePath.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsCurveEvaluator
|
||||||
|
// Description : This class is an abstraction for evaluating NURBS
|
||||||
|
// curves. It accepts an array of vertices, each of
|
||||||
|
// which may be in a different coordinate space (as
|
||||||
|
// defined by a NodePath), as well as an optional knot
|
||||||
|
// vector.
|
||||||
|
//
|
||||||
|
// This is not related to NurbsCurve, ClassicNurbsCurve,
|
||||||
|
// CubicCurveseg or any of the ParametricCurve-derived
|
||||||
|
// objects in this module. It is a completely parallel
|
||||||
|
// implementation of NURBS curves, and will probably
|
||||||
|
// eventually replace the whole ParametricCurve class
|
||||||
|
// hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsCurveEvaluator {
|
||||||
|
PUBLISHED:
|
||||||
|
NurbsCurveEvaluator();
|
||||||
|
~NurbsCurveEvaluator();
|
||||||
|
|
||||||
|
void set_order(int order);
|
||||||
|
int get_order() const;
|
||||||
|
|
||||||
|
void reset(int num_vertices);
|
||||||
|
|
||||||
|
int get_num_vertices() const;
|
||||||
|
void set_vertex(int i, const LVecBase4f &vertex);
|
||||||
|
const LVecBase4f &get_vertex(int i) const;
|
||||||
|
|
||||||
|
void set_vertex_space(int i, const NodePath &space);
|
||||||
|
const NodePath &get_vertex_space(int i) const;
|
||||||
|
|
||||||
|
int get_num_knots() const;
|
||||||
|
void set_knot(int i, float knot);
|
||||||
|
float get_knot(int i) const;
|
||||||
|
|
||||||
|
PT(NurbsCurveResult) evaluate(const NodePath &rel_to = NodePath());
|
||||||
|
|
||||||
|
private:
|
||||||
|
void recompute_knots();
|
||||||
|
void recompute_basis();
|
||||||
|
|
||||||
|
int _order;
|
||||||
|
|
||||||
|
typedef pvector<NurbsVertex> Vertices;
|
||||||
|
Vertices _vertices;
|
||||||
|
|
||||||
|
bool _knots_dirty;
|
||||||
|
typedef vector_float Knots;
|
||||||
|
Knots _knots;
|
||||||
|
|
||||||
|
bool _basis_dirty;
|
||||||
|
NurbsMatrixVector _basis;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
39
panda/src/parametrics/nurbsCurveResult.I
Normal file
39
panda/src/parametrics/nurbsCurveResult.I
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Filename: nurbsCurveResult.I
|
||||||
|
// Created by: drose (04Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::get_start_t
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the first legal value of t on the curve.
|
||||||
|
// Usually this is 0.0.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsCurveResult::
|
||||||
|
get_start_t() const {
|
||||||
|
return _prod.get_start_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::get_end_t
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the last legal value of t on the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsCurveResult::
|
||||||
|
get_end_t() const {
|
||||||
|
return _prod.get_end_t();
|
||||||
|
}
|
153
panda/src/parametrics/nurbsCurveResult.cxx
Normal file
153
panda/src/parametrics/nurbsCurveResult.cxx
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// Filename: nurbsCurveResult.cxx
|
||||||
|
// Created by: drose (04Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "nurbsCurveResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description: The constructor automatically builds up the result as
|
||||||
|
// the product of the indicated set of basis matrices
|
||||||
|
// and the indicated table of control vertex positions.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsCurveResult::
|
||||||
|
NurbsCurveResult(const NurbsMatrixVector &basis, int order,
|
||||||
|
const LVecBase4f verts[], int num_vertices) {
|
||||||
|
_last_segment = -1;
|
||||||
|
|
||||||
|
int num_segments = basis.get_num_segments();
|
||||||
|
for (int i = 0; i < num_segments; i++) {
|
||||||
|
int vi = basis.get_vertex_index(i);
|
||||||
|
nassertv(vi >= 0 && vi < num_vertices);
|
||||||
|
|
||||||
|
// Create a matrix from our (up to) four involved vertices.
|
||||||
|
LMatrix4f geom;
|
||||||
|
int ci = 0;
|
||||||
|
while (ci < order) {
|
||||||
|
geom.set_row(ci, verts[vi + ci]);
|
||||||
|
ci++;
|
||||||
|
}
|
||||||
|
while (ci < 4) {
|
||||||
|
geom.set_row(ci, LVecBase4f::zero());
|
||||||
|
ci++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And compose this matrix with the segment to produce a new
|
||||||
|
// matrix.
|
||||||
|
_prod.compose_segment(basis, i, geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsCurveResult::
|
||||||
|
~NurbsCurveResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::eval_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Computes the point on the curve corresponding to the
|
||||||
|
// indicated value in parametric time. Returns true if
|
||||||
|
// the t value is value, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool NurbsCurveResult::
|
||||||
|
eval_point(float t, LPoint3f &point) {
|
||||||
|
int segment = find_segment(t);
|
||||||
|
if (segment == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = _prod.scale_t(segment, t);
|
||||||
|
const LMatrix4f &mat = _prod.get_matrix(segment);
|
||||||
|
|
||||||
|
float t2 = t*t;
|
||||||
|
LVecBase4f tvec(t*t2, t2, t, 1.0f);
|
||||||
|
LVecBase4f r = tvec * mat;
|
||||||
|
point.set(r[0] / r[3], r[1] / r[3], r[2] / r[3]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::find_segment
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns the index of the segment that contains the
|
||||||
|
// indicated value of t, or -1 if no segment contains
|
||||||
|
// this value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NurbsCurveResult::
|
||||||
|
find_segment(float t) {
|
||||||
|
// Trivially check the endpoints of the curve.
|
||||||
|
if (t >= get_end_t()) {
|
||||||
|
return _prod.get_num_segments() - 1;
|
||||||
|
} else if (t <= get_start_t()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the last segment we searched for. Often, two consecutive
|
||||||
|
// requests are for the same segment.
|
||||||
|
if (_last_segment != -1 && (t >= _last_from && t < _last_to)) {
|
||||||
|
return _last_segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the segment the hard way.
|
||||||
|
int segment = r_find_segment(t, 0, _prod.get_num_segments() - 1);
|
||||||
|
if (segment != -1) {
|
||||||
|
_last_segment = segment;
|
||||||
|
_last_from = _prod.get_from(segment);
|
||||||
|
_last_to = _prod.get_to(segment);
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsCurveResult::r_find_segment
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recursively searches for the segment that contains
|
||||||
|
// the indicated value of t by performing a binary
|
||||||
|
// search. This assumes the segments are stored in
|
||||||
|
// increasing order of t, and they don't overlap.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NurbsCurveResult::
|
||||||
|
r_find_segment(float t, int top, int bot) const {
|
||||||
|
if (bot < top) {
|
||||||
|
// Not found.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int mid = (top + bot) / 2;
|
||||||
|
nassertr(mid >= 0 && mid < _prod.get_num_segments(), -1);
|
||||||
|
|
||||||
|
float from = _prod.get_from(mid);
|
||||||
|
float to = _prod.get_to(mid);
|
||||||
|
if (from > t) {
|
||||||
|
// Too high, try lower.
|
||||||
|
return r_find_segment(t, top, mid - 1);
|
||||||
|
|
||||||
|
} else if (to <= t) {
|
||||||
|
// Too low, try higher.
|
||||||
|
return r_find_segment(t, mid + 1, bot);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Here we are!
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
69
panda/src/parametrics/nurbsCurveResult.h
Normal file
69
panda/src/parametrics/nurbsCurveResult.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Filename: nurbsCurveResult.h
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef NURBSCURVERESULT_H
|
||||||
|
#define NURBSCURVERESULT_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "referenceCount.h"
|
||||||
|
#include "nurbsMatrixVector.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsCurveResult
|
||||||
|
// Description : The result of a NurbsCurveEvaluator. This object
|
||||||
|
// represents a curve in a particular coordinate space.
|
||||||
|
// It can return the point and/or tangent to the curve
|
||||||
|
// at any point.
|
||||||
|
//
|
||||||
|
// This is not related to NurbsCurve, ClassicNurbsCurve,
|
||||||
|
// CubicCurveseg or any of the ParametricCurve-derived
|
||||||
|
// objects in this module. It is a completely parallel
|
||||||
|
// implementation of NURBS curves, and will probably
|
||||||
|
// eventually replace the whole ParametricCurve class
|
||||||
|
// hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsCurveResult : public ReferenceCount {
|
||||||
|
public:
|
||||||
|
NurbsCurveResult(const NurbsMatrixVector &basis, int order,
|
||||||
|
const LVecBase4f verts[], int num_vertices);
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
~NurbsCurveResult();
|
||||||
|
|
||||||
|
INLINE float get_start_t() const;
|
||||||
|
INLINE float get_end_t() const;
|
||||||
|
|
||||||
|
bool eval_point(float t, LPoint3f &point);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int find_segment(float t);
|
||||||
|
int r_find_segment(float t, int top, int bot) const;
|
||||||
|
|
||||||
|
NurbsMatrixVector _prod;
|
||||||
|
|
||||||
|
int _last_segment;
|
||||||
|
float _last_from;
|
||||||
|
float _last_to;
|
||||||
|
|
||||||
|
friend class NurbsCurveEvaluator;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nurbsCurveResult.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
132
panda/src/parametrics/nurbsMatrixVector.I
Normal file
132
panda/src/parametrics/nurbsMatrixVector.I
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Filename: nurbsMatrixVector.I
|
||||||
|
// Created by: drose (04Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsMatrixVector::
|
||||||
|
NurbsMatrixVector() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsMatrixVector::
|
||||||
|
~NurbsMatrixVector() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_num_segments
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the number of piecewise continuous segments
|
||||||
|
// in the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsMatrixVector::
|
||||||
|
get_num_segments() const {
|
||||||
|
return _segments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_start_t
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the first legal value of t on the curve.
|
||||||
|
// Usually this is 0.0.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsMatrixVector::
|
||||||
|
get_start_t() const {
|
||||||
|
nassertr(!_segments.empty(), 0.0f);
|
||||||
|
return _segments.front()._from;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_end_t
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the last legal value of t on the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsMatrixVector::
|
||||||
|
get_end_t() const {
|
||||||
|
nassertr(!_segments.empty(), 0.0f);
|
||||||
|
return _segments.back()._to;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_vertex_index
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the vertex index of the nth segment. This is
|
||||||
|
// the index number of the first associated control
|
||||||
|
// vertex within the source NurbsCurveEvaluator object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsMatrixVector::
|
||||||
|
get_vertex_index(int segment) const {
|
||||||
|
nassertr(segment >= 0 && segment < (int)_segments.size(), 0);
|
||||||
|
return _segments[segment]._vertex_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_from
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the t value of the beginning of this segment.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsMatrixVector::
|
||||||
|
get_from(int segment) const {
|
||||||
|
nassertr(segment >= 0 && segment < (int)_segments.size(), 0.0f);
|
||||||
|
return _segments[segment]._from;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_to
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the t value of the end of this segment.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsMatrixVector::
|
||||||
|
get_to(int segment) const {
|
||||||
|
nassertr(segment >= 0 && segment < (int)_segments.size(), 0.0f);
|
||||||
|
return _segments[segment]._to;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::get_matrix
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the matrix associated with the nth segment.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const LMatrix4f &NurbsMatrixVector::
|
||||||
|
get_matrix(int segment) const {
|
||||||
|
nassertr(segment >= 0 && segment < (int)_segments.size(), LMatrix4f::ident_mat());
|
||||||
|
return _segments[segment]._matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::scale_t
|
||||||
|
// Access: Public
|
||||||
|
// Description: Scales the value of t into the range [0, 1]
|
||||||
|
// corresponding to [from, to]. Returns the scaled
|
||||||
|
// value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsMatrixVector::
|
||||||
|
scale_t(int segment, float t) const {
|
||||||
|
nassertr(segment >= 0 && segment < (int)_segments.size(), 0.0f);
|
||||||
|
float from = _segments[segment]._from;
|
||||||
|
float to = _segments[segment]._to;
|
||||||
|
t = (t - from) / (to - from);
|
||||||
|
return min(max(t, 0.0f), 1.0f);
|
||||||
|
}
|
150
panda/src/parametrics/nurbsMatrixVector.cxx
Normal file
150
panda/src/parametrics/nurbsMatrixVector.cxx
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// Filename: nurbsMatrixVector.cxx
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "nurbsMatrixVector.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::clear
|
||||||
|
// Access: Public
|
||||||
|
// Description: Removes all the segments from the curve.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsMatrixVector::
|
||||||
|
clear() {
|
||||||
|
_segments.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::append_segment
|
||||||
|
// Access: Public
|
||||||
|
// Description: Computes a NURBS basis for one segment of the curve
|
||||||
|
// and appends it to the set of basis matrices.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsMatrixVector::
|
||||||
|
append_segment(int order, int vertex_index, const float knots[]) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Scale the supplied knots to the range 0..1.
|
||||||
|
float scaled_knots[8];
|
||||||
|
float min_k = knots[order - 1];
|
||||||
|
float max_k = knots[order];
|
||||||
|
|
||||||
|
nassertv(min_k != max_k);
|
||||||
|
for (i = 0; i < order + order; i++) {
|
||||||
|
scaled_knots[i] = (knots[i] - min_k) / (max_k - min_k);
|
||||||
|
}
|
||||||
|
|
||||||
|
Segment segment;
|
||||||
|
segment._vertex_index = vertex_index;
|
||||||
|
segment._from = min_k;
|
||||||
|
segment._to = max_k;
|
||||||
|
|
||||||
|
for (i = 0; i < order; i++) {
|
||||||
|
LVecBase4f b = nurbs_blending_function(order, i, order, scaled_knots);
|
||||||
|
segment._matrix.set_col(i, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = order; i < 4; i++) {
|
||||||
|
segment._matrix.set_col(i, LVecBase4f::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
_segments.push_back(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::compose_segment
|
||||||
|
// Access: Public
|
||||||
|
// Description: Appends a new segment to the vector by composing the
|
||||||
|
// indicated geometry matrix with the indicated basis
|
||||||
|
// matrix from the given vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsMatrixVector::
|
||||||
|
compose_segment(const NurbsMatrixVector &basis, int segment,
|
||||||
|
const LMatrix4f &geom) {
|
||||||
|
nassertv(segment >= 0 && segment < (int)basis._segments.size());
|
||||||
|
const Segment &source = basis._segments[segment];
|
||||||
|
|
||||||
|
Segment dest;
|
||||||
|
dest._vertex_index = source._vertex_index;
|
||||||
|
dest._from = source._from;
|
||||||
|
dest._to = source._to;
|
||||||
|
dest._matrix = source._matrix * geom;
|
||||||
|
|
||||||
|
_segments.push_back(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsMatrixVector::nurbs_blending_function
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Recursively computes the appropriate blending
|
||||||
|
// function for the indicated knot vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LVecBase4f NurbsMatrixVector::
|
||||||
|
nurbs_blending_function(int order, int i, int j, const float knots[]) {
|
||||||
|
// This is doubly recursive. Ick.
|
||||||
|
LVecBase4f r;
|
||||||
|
|
||||||
|
if (j == 1) {
|
||||||
|
if (i == order-1 && knots[i] < knots[i+1]) {
|
||||||
|
r.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
} else {
|
||||||
|
r.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LVecBase4f bi0 = nurbs_blending_function(order, i, j - 1, knots);
|
||||||
|
LVecBase4f bi1 = nurbs_blending_function(order, i + 1, j - 1, knots);
|
||||||
|
|
||||||
|
float d0 = knots[i + j - 1] - knots[i];
|
||||||
|
float d1 = knots[i + j] - knots[i + 1];
|
||||||
|
|
||||||
|
// First term. Division by zero is defined to equal zero.
|
||||||
|
if (d0 != 0.0f) {
|
||||||
|
if (d1 != 0.0f) {
|
||||||
|
r = bi0 / d0 - bi1 / d1;
|
||||||
|
} else {
|
||||||
|
r = bi0 / d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (d1 != 0.0f) {
|
||||||
|
r = - bi1 / d1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
r.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scale by t.
|
||||||
|
r[0] = r[1];
|
||||||
|
r[1] = r[2];
|
||||||
|
r[2] = r[3];
|
||||||
|
r[3] = 0.0f;
|
||||||
|
|
||||||
|
// Second term.
|
||||||
|
if (d0 != 0.0f) {
|
||||||
|
if (d1 != 0.0f) {
|
||||||
|
r += bi0 * (- knots[i] / d0) + bi1 * (knots[i + j] / d1);
|
||||||
|
} else {
|
||||||
|
r += bi0 * (- knots[i] / d0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (d1 != 0.0f) {
|
||||||
|
r += bi1 * (knots[i + j] / d1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
80
panda/src/parametrics/nurbsMatrixVector.h
Normal file
80
panda/src/parametrics/nurbsMatrixVector.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Filename: nurbsMatrixVector.h
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef NURBSMATRIXVECTOR_H
|
||||||
|
#define NURBSMATRIXVECTOR_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "luse.h"
|
||||||
|
#include "pvector.h"
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsMatrixVector
|
||||||
|
// Description : This encapsulates a series of matrices that are used
|
||||||
|
// to represent the sequential segments of a
|
||||||
|
// NurbsCurveEvaluator.
|
||||||
|
//
|
||||||
|
// This is not related to NurbsCurve, ClassicNurbsCurve,
|
||||||
|
// CubicCurveseg or any of the ParametricCurve-derived
|
||||||
|
// objects in this module. It is a completely parallel
|
||||||
|
// implementation of NURBS curves, and will probably
|
||||||
|
// eventually replace the whole ParametricCurve class
|
||||||
|
// hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsMatrixVector {
|
||||||
|
public:
|
||||||
|
INLINE NurbsMatrixVector();
|
||||||
|
INLINE ~NurbsMatrixVector();
|
||||||
|
|
||||||
|
INLINE int get_num_segments() const;
|
||||||
|
INLINE float get_start_t() const;
|
||||||
|
INLINE float get_end_t() const;
|
||||||
|
|
||||||
|
INLINE int get_vertex_index(int segment) const;
|
||||||
|
INLINE float get_from(int segment) const;
|
||||||
|
INLINE float get_to(int segment) const;
|
||||||
|
INLINE const LMatrix4f &get_matrix(int segment) const;
|
||||||
|
INLINE float scale_t(int segment, float t) const;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void append_segment(int order, int vertex_index, const float knots[]);
|
||||||
|
void compose_segment(const NurbsMatrixVector &basis, int segment,
|
||||||
|
const LMatrix4f &geom);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static LVecBase4f nurbs_blending_function(int order, int i, int j,
|
||||||
|
const float knots[]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Segment {
|
||||||
|
public:
|
||||||
|
int _vertex_index;
|
||||||
|
float _from;
|
||||||
|
float _to;
|
||||||
|
LMatrix4f _matrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef pvector<Segment> Segments;
|
||||||
|
Segments _segments;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nurbsMatrixVector.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
99
panda/src/parametrics/nurbsVertex.I
Normal file
99
panda/src/parametrics/nurbsVertex.I
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Filename: nurbsVertex.I
|
||||||
|
// Created by: drose (04Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsVertex::
|
||||||
|
NurbsVertex() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::Copy Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsVertex::
|
||||||
|
NurbsVertex(const NurbsVertex ©) :
|
||||||
|
_vertex(copy._vertex),
|
||||||
|
_space(copy._space)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::Copy Assignment Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsVertex::
|
||||||
|
operator = (const NurbsVertex ©) {
|
||||||
|
_vertex = copy._vertex;
|
||||||
|
_space = copy._space;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsVertex::
|
||||||
|
~NurbsVertex() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::set_vertex
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsVertex::
|
||||||
|
set_vertex(const LVecBase4f &vertex) {
|
||||||
|
_vertex = vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::get_vertex
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const LVecBase4f &NurbsVertex::
|
||||||
|
get_vertex() const {
|
||||||
|
return _vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::set_space
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsVertex::
|
||||||
|
set_space(const NodePath &space) {
|
||||||
|
_space = space;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsVertex::get_space
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const NodePath &NurbsVertex::
|
||||||
|
get_space() const {
|
||||||
|
return _space;
|
||||||
|
}
|
20
panda/src/parametrics/nurbsVertex.cxx
Normal file
20
panda/src/parametrics/nurbsVertex.cxx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Filename: nurbsVertex.cxx
|
||||||
|
// Created by: drose (04Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "nurbsVertex.h"
|
||||||
|
|
61
panda/src/parametrics/nurbsVertex.h
Normal file
61
panda/src/parametrics/nurbsVertex.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Filename: nurbsVertex.h
|
||||||
|
// Created by: drose (03Dec02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef NURBSVERTEX_H
|
||||||
|
#define NURBSVERTEX_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "luse.h"
|
||||||
|
#include "nodePath.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsVertex
|
||||||
|
// Description : This represents a single control vertex in a
|
||||||
|
// NurbsEvaluator. It may be relative to a particular
|
||||||
|
// coordinate space; or its coordinate space may be
|
||||||
|
// unspecified.
|
||||||
|
//
|
||||||
|
// This is not related to NurbsCurve, ClassicNurbsCurve,
|
||||||
|
// CubicCurveseg or any of the ParametricCurve-derived
|
||||||
|
// objects in this module. It is a completely parallel
|
||||||
|
// implementation of NURBS curves, and will probably
|
||||||
|
// eventually replace the whole ParametricCurve class
|
||||||
|
// hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsVertex {
|
||||||
|
public:
|
||||||
|
INLINE NurbsVertex();
|
||||||
|
INLINE NurbsVertex(const NurbsVertex ©);
|
||||||
|
INLINE void operator = (const NurbsVertex ©);
|
||||||
|
INLINE ~NurbsVertex();
|
||||||
|
|
||||||
|
INLINE void set_vertex(const LVecBase4f &vertex);
|
||||||
|
INLINE const LVecBase4f &get_vertex() const;
|
||||||
|
|
||||||
|
INLINE void set_space(const NodePath &space);
|
||||||
|
INLINE const NodePath &get_space() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LVecBase4f _vertex;
|
||||||
|
NodePath _space;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nurbsVertex.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
#include "classicNurbsCurve.cxx"
|
#include "classicNurbsCurve.cxx"
|
||||||
#include "cubicCurveseg.cxx"
|
#include "cubicCurveseg.cxx"
|
||||||
#include "curveFitter.cxx"
|
#include "curveFitter.cxx"
|
||||||
#include "hermiteCurve.cxx"
|
#include "hermiteCurve.cxx"
|
||||||
#include "nurbsCurveDrawer.cxx"
|
#include "nurbsCurveDrawer.cxx"
|
||||||
#include "nurbsCurveInterface.cxx"
|
#include "nurbsCurveInterface.cxx"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
#include "config_parametrics.cxx"
|
#include "config_parametrics.cxx"
|
||||||
#include "piecewiseCurve.cxx"
|
#include "piecewiseCurve.cxx"
|
||||||
#include "parametricCurve.cxx"
|
#include "parametricCurve.cxx"
|
||||||
#include "parametricCurveCollection.cxx"
|
#include "parametricCurveCollection.cxx"
|
||||||
#include "parametricCurveDrawer.cxx"
|
#include "parametricCurveDrawer.cxx"
|
||||||
|
#include "nurbsCurveEvaluator.cxx"
|
||||||
|
#include "nurbsCurveResult.cxx"
|
||||||
|
#include "nurbsMatrixVector.cxx"
|
||||||
|
#include "nurbsVertex.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user