mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
add NurbsSurfaceEvaluator
This commit is contained in:
parent
41232c24d9
commit
a356726b35
@ -20,6 +20,8 @@
|
|||||||
nurbsCurveInterface.I nurbsCurveInterface.h \
|
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||||
nurbsCurveResult.I nurbsCurveResult.h \
|
nurbsCurveResult.I nurbsCurveResult.h \
|
||||||
nurbsBasisVector.I nurbsBasisVector.h \
|
nurbsBasisVector.I nurbsBasisVector.h \
|
||||||
|
nurbsSurfaceEvaluator.I nurbsSurfaceEvaluator.h \
|
||||||
|
nurbsSurfaceResult.I nurbsSurfaceResult.h \
|
||||||
nurbsVertex.h nurbsVertex.I \
|
nurbsVertex.h nurbsVertex.I \
|
||||||
parametricCurve.h \
|
parametricCurve.h \
|
||||||
parametricCurveCollection.I parametricCurveCollection.h \
|
parametricCurveCollection.I parametricCurveCollection.h \
|
||||||
@ -33,9 +35,11 @@
|
|||||||
parametricCurveDrawer.cxx curveFitter.cxx hermiteCurve.cxx \
|
parametricCurveDrawer.cxx curveFitter.cxx hermiteCurve.cxx \
|
||||||
nurbsCurveDrawer.cxx \
|
nurbsCurveDrawer.cxx \
|
||||||
nurbsCurveEvaluator.cxx \
|
nurbsCurveEvaluator.cxx \
|
||||||
nurbsCurveResult.cxx \
|
|
||||||
nurbsCurveInterface.cxx \
|
nurbsCurveInterface.cxx \
|
||||||
|
nurbsCurveResult.cxx \
|
||||||
nurbsBasisVector.cxx \
|
nurbsBasisVector.cxx \
|
||||||
|
nurbsSurfaceEvaluator.cxx \
|
||||||
|
nurbsSurfaceResult.cxx \
|
||||||
nurbsVertex.cxx \
|
nurbsVertex.cxx \
|
||||||
parametricCurve.cxx parametricCurveCollection.cxx \
|
parametricCurve.cxx parametricCurveCollection.cxx \
|
||||||
piecewiseCurve.cxx \
|
piecewiseCurve.cxx \
|
||||||
@ -54,6 +58,8 @@
|
|||||||
nurbsCurveInterface.I nurbsCurveInterface.h \
|
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||||
nurbsCurveResult.I nurbsCurveResult.h \
|
nurbsCurveResult.I nurbsCurveResult.h \
|
||||||
nurbsBasisVector.I nurbsBasisVector.h \
|
nurbsBasisVector.I nurbsBasisVector.h \
|
||||||
|
nurbsSurfaceEvaluator.I nurbsSurfaceEvaluator.h \
|
||||||
|
nurbsSurfaceResult.I nurbsSurfaceResult.h \
|
||||||
nurbsVertex.h nurbsVertex.I \
|
nurbsVertex.h nurbsVertex.I \
|
||||||
nurbsPPCurve.h \
|
nurbsPPCurve.h \
|
||||||
parametricCurve.h \
|
parametricCurve.h \
|
||||||
|
@ -40,7 +40,7 @@ NurbsCurveResult(const NurbsBasisVector &basis,
|
|||||||
_composed.reserve(num_segments);
|
_composed.reserve(num_segments);
|
||||||
for (int i = 0; i < num_segments; i++) {
|
for (int i = 0; i < num_segments; i++) {
|
||||||
int vi = _basis.get_vertex_index(i);
|
int vi = _basis.get_vertex_index(i);
|
||||||
nassertv(vi >= 0 && vi < num_vertices);
|
nassertv(vi >= 0 && vi + order - 1 < num_vertices);
|
||||||
|
|
||||||
// Create a geometry matrix from our (up to) four involved vertices.
|
// Create a geometry matrix from our (up to) four involved vertices.
|
||||||
LMatrix4f geom;
|
LMatrix4f geom;
|
||||||
@ -86,6 +86,7 @@ eval_segment_point(int segment, float t, LVecBase3f &point) const {
|
|||||||
LVecBase4f tvec(t*t2, t2, t, 1.0f);
|
LVecBase4f tvec(t*t2, t2, t, 1.0f);
|
||||||
|
|
||||||
float weight = tvec.dot(_composed[segment].get_col(3));
|
float weight = tvec.dot(_composed[segment].get_col(3));
|
||||||
|
|
||||||
point.set(tvec.dot(_composed[segment].get_col(0)) / weight,
|
point.set(tvec.dot(_composed[segment].get_col(0)) / weight,
|
||||||
tvec.dot(_composed[segment].get_col(1)) / weight,
|
tvec.dot(_composed[segment].get_col(1)) / weight,
|
||||||
tvec.dot(_composed[segment].get_col(2)) / weight);
|
tvec.dot(_composed[segment].get_col(2)) / weight);
|
||||||
|
@ -70,7 +70,7 @@ private:
|
|||||||
|
|
||||||
// We pre-compose the basis matrix and the geometry vectors, so we
|
// We pre-compose the basis matrix and the geometry vectors, so we
|
||||||
// have these handy for evaluation. There is one entry in the
|
// have these handy for evaluation. There is one entry in the
|
||||||
// _composed_vector for each entry in basis._segments.
|
// _composed for each entry in basis._segments.
|
||||||
typedef pvector<LMatrix4f> ComposedGeom;
|
typedef pvector<LMatrix4f> ComposedGeom;
|
||||||
ComposedGeom _composed;
|
ComposedGeom _composed;
|
||||||
|
|
||||||
|
271
panda/src/parametrics/nurbsSurfaceEvaluator.I
Normal file
271
panda/src/parametrics/nurbsSurfaceEvaluator.I
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
// Filename: nurbsSurfaceEvaluator.I
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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: NurbsSurfaceEvaluator::set_u_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the order of the surface in the U direction.
|
||||||
|
// 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 surface.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_u_order(int u_order) {
|
||||||
|
_u_order = u_order;
|
||||||
|
_u_knots_dirty = true;
|
||||||
|
_u_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_u_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the order of the surface in the U direction
|
||||||
|
// as set by a previous call to set_u_order().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_u_order() const {
|
||||||
|
return _u_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_v_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the order of the surface in the V direction.
|
||||||
|
// 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 surface.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_v_order(int v_order) {
|
||||||
|
_v_order = v_order;
|
||||||
|
_v_knots_dirty = true;
|
||||||
|
_v_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_v_order
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the order of the surface in the V direction
|
||||||
|
// as set by a previous call to set_v_order().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_v_order() const {
|
||||||
|
return _v_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_num_u_vertices
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of control vertices in the U
|
||||||
|
// direction on the surface. This is the number passed
|
||||||
|
// to the last call to reset().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_num_u_vertices() const {
|
||||||
|
return _num_u_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_num_v_vertices
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of control vertices in the V
|
||||||
|
// direction on the surface. This is the number passed
|
||||||
|
// to the last call to reset().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_num_v_vertices() const {
|
||||||
|
return _num_v_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the nth control vertex of the surface, as a vertex
|
||||||
|
// in 4-d homogeneous space. In this form, the first
|
||||||
|
// three components of the vertex should already have
|
||||||
|
// been scaled by the fourth component, which is the
|
||||||
|
// homogeneous weight.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_vertex(int ui, int vi, const LVecBase4f &vertex) {
|
||||||
|
nassertv(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices);
|
||||||
|
vert(ui, vi).set_vertex(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the nth control vertex of the surface. This
|
||||||
|
// flavor sets the vertex as a 3-d coordinate and a
|
||||||
|
// weight; the 3-d coordinate values are implicitly
|
||||||
|
// scaled up by the weight factor.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_vertex(int ui, int vi, const LVecBase3f &vertex, float weight) {
|
||||||
|
nassertv(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices);
|
||||||
|
vert(ui, vi).set_vertex(LVecBase4f(vertex[0] * weight, vertex[1] * weight, vertex[2] * weight, weight));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the nth control vertex of the surface, relative
|
||||||
|
// to its indicated coordinate space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const LVecBase4f &NurbsSurfaceEvaluator::
|
||||||
|
get_vertex(int ui, int vi) const {
|
||||||
|
nassertr(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices, LVecBase4f::zero());
|
||||||
|
return vert(ui, vi).get_vertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::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().
|
||||||
|
//
|
||||||
|
// This specifies the space as a fixed NodePath, which
|
||||||
|
// is always the same NodePath. Also see setting the
|
||||||
|
// space as a path string, which can specify a different
|
||||||
|
// NodePath for different instances of the surface.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_vertex_space(int ui, int vi, const NodePath &space) {
|
||||||
|
nassertv(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices);
|
||||||
|
vert(ui, vi).set_space(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::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
|
||||||
|
// string, the nth control vertex is deemed to be in
|
||||||
|
// the coordinate space passed to evaluate().
|
||||||
|
//
|
||||||
|
// This specifies the space as a string, which describes
|
||||||
|
// the path to find the node relative to the rel_to
|
||||||
|
// NodePath when the surface is evaluated.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NurbsSurfaceEvaluator::
|
||||||
|
set_vertex_space(int ui, int vi, const string &space) {
|
||||||
|
nassertv(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices);
|
||||||
|
vert(ui, vi).set_space(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_extended_vertex
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets an n-dimensional vertex value. This allows
|
||||||
|
// definition of a NURBS surface or surface in a sparse
|
||||||
|
// n-dimensional space, typically used for associating
|
||||||
|
// additional properties (like color or joint
|
||||||
|
// membership) with each vertex of a surface.
|
||||||
|
//
|
||||||
|
// The value d is an arbitrary integer value and
|
||||||
|
// specifies the dimension of question for this
|
||||||
|
// particular vertex. Any number of dimensions may be
|
||||||
|
// specified, and they need not be consecutive. If a
|
||||||
|
// value for a given dimension is not specified, is it
|
||||||
|
// implicitly 0.0.
|
||||||
|
//
|
||||||
|
// The value is implicitly scaled by the homogenous
|
||||||
|
// weight value--that is, the fourth component of the
|
||||||
|
// value passed to set_vertex(). This means the
|
||||||
|
// ordinary vertex must be set first, before the
|
||||||
|
// extended vertices can be set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
set_extended_vertex(int ui, int vi, int d, float value) {
|
||||||
|
nassertv(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices);
|
||||||
|
vert(ui, vi).set_extended_vertex(d, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::float_extended_vertex
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns an n-dimensional vertex value. See
|
||||||
|
// set_extended_vertex(). This returns the value set
|
||||||
|
// for the indicated dimension, or 0.0 if nothing has
|
||||||
|
// been set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float NurbsSurfaceEvaluator::
|
||||||
|
get_extended_vertex(int ui, int vi, int d) const {
|
||||||
|
nassertr(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices, 0.0f);
|
||||||
|
return vert(ui, vi).get_extended_vertex(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_num_u_knots
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of knot values in the surface in
|
||||||
|
// the U direction. This is based on the number of
|
||||||
|
// vertices and the order.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_num_u_knots() const {
|
||||||
|
return _num_u_vertices + _u_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_num_v_knots
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of knot values in the surface in
|
||||||
|
// the V direction. This is based on the number of
|
||||||
|
// vertices and the order.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceEvaluator::
|
||||||
|
get_num_v_knots() const {
|
||||||
|
return _num_v_vertices + _v_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::vert
|
||||||
|
// Access: Private
|
||||||
|
// Description: Internal accessor to dereference the 2-d vertex
|
||||||
|
// coordinate pair into a linear list of vertices.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsVertex &NurbsSurfaceEvaluator::
|
||||||
|
vert(int ui, int vi) {
|
||||||
|
return _vertices[ui * _num_v_vertices + vi];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::vert
|
||||||
|
// Access: Private
|
||||||
|
// Description: Internal accessor to dereference the 2-d vertex
|
||||||
|
// coordinate pair into a linear list of vertices.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const NurbsVertex &NurbsSurfaceEvaluator::
|
||||||
|
vert(int ui, int vi) const {
|
||||||
|
return _vertices[ui * _num_v_vertices + vi];
|
||||||
|
}
|
353
panda/src/parametrics/nurbsSurfaceEvaluator.cxx
Normal file
353
panda/src/parametrics/nurbsSurfaceEvaluator.cxx
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
// Filename: nurbsSurfaceEvaluator.cxx
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 "nurbsSurfaceEvaluator.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsSurfaceEvaluator::
|
||||||
|
NurbsSurfaceEvaluator() {
|
||||||
|
_u_order = 4;
|
||||||
|
_v_order = 4;
|
||||||
|
_u_knots_dirty = true;
|
||||||
|
_v_knots_dirty = true;
|
||||||
|
_u_basis_dirty = true;
|
||||||
|
_v_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsSurfaceEvaluator::
|
||||||
|
~NurbsSurfaceEvaluator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::reset
|
||||||
|
// Access: Published
|
||||||
|
// Description: Resets all the vertices and knots to their default
|
||||||
|
// values, and sets the surface up with the indicated
|
||||||
|
// number of vertices. You must then call set_vertex()
|
||||||
|
// repeatedly to fill in all of the vertex values
|
||||||
|
// appropriately.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
reset(int num_u_vertices, int num_v_vertices) {
|
||||||
|
int num_vertices = num_u_vertices * num_v_vertices;
|
||||||
|
_vertices.clear();
|
||||||
|
_vertices.reserve(num_vertices);
|
||||||
|
_num_u_vertices = num_u_vertices;
|
||||||
|
_num_v_vertices = num_v_vertices;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_vertices; i++) {
|
||||||
|
_vertices.push_back(NurbsVertex());
|
||||||
|
}
|
||||||
|
_u_knots_dirty = true;
|
||||||
|
_v_knots_dirty = true;
|
||||||
|
_u_basis_dirty = true;
|
||||||
|
_v_basis_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_vertex_space
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the coordinate space of the nth control
|
||||||
|
// vertex of the surface, expressed as a NodePath.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NodePath NurbsSurfaceEvaluator::
|
||||||
|
get_vertex_space(int ui, int vi, const NodePath &rel_to) const {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static NodePath empty_node_path;
|
||||||
|
nassertr(ui >= 0 && ui < _num_u_vertices &&
|
||||||
|
vi >= 0 && vi < _num_v_vertices, empty_node_path);
|
||||||
|
#endif
|
||||||
|
return vert(ui, vi).get_space(rel_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_u_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 NurbsSurfaceEvaluator::
|
||||||
|
set_u_knot(int i, float knot) {
|
||||||
|
if (_u_knots_dirty) {
|
||||||
|
recompute_u_knots();
|
||||||
|
}
|
||||||
|
nassertv(i >= 0 && i < (int)_u_knots.size());
|
||||||
|
_u_knots[i] = knot;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_u_knot
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the value of the nth knot.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float NurbsSurfaceEvaluator::
|
||||||
|
get_u_knot(int i) const {
|
||||||
|
if (_u_knots_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_u_knots();
|
||||||
|
}
|
||||||
|
nassertr(i >= 0 && i < (int)_u_knots.size(), 0.0f);
|
||||||
|
return _u_knots[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::set_v_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 NurbsSurfaceEvaluator::
|
||||||
|
set_v_knot(int i, float knot) {
|
||||||
|
if (_v_knots_dirty) {
|
||||||
|
recompute_v_knots();
|
||||||
|
}
|
||||||
|
nassertv(i >= 0 && i < (int)_v_knots.size());
|
||||||
|
_v_knots[i] = knot;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_v_knot
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the value of the nth knot.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float NurbsSurfaceEvaluator::
|
||||||
|
get_v_knot(int i) const {
|
||||||
|
if (_v_knots_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_v_knots();
|
||||||
|
}
|
||||||
|
nassertr(i >= 0 && i < (int)_v_knots.size(), 0.0f);
|
||||||
|
return _v_knots[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::evaluate
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a NurbsSurfaceResult 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(NurbsSurfaceResult) NurbsSurfaceEvaluator::
|
||||||
|
evaluate(const NodePath &rel_to) const {
|
||||||
|
if (_u_basis_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_u_basis();
|
||||||
|
}
|
||||||
|
if (_v_basis_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_v_basis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, transform the vertices as appropriate.
|
||||||
|
pvector<LVecBase4f> vecs;
|
||||||
|
get_vertices(vecs, rel_to);
|
||||||
|
|
||||||
|
// And apply those transformed vertices to the basis matrices to
|
||||||
|
// derive the result.
|
||||||
|
return new NurbsSurfaceResult(_u_basis, _v_basis,
|
||||||
|
&vecs[0], &_vertices[0],
|
||||||
|
_num_u_vertices, _num_v_vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_vertices
|
||||||
|
// Access: Public
|
||||||
|
// Description: Fills the indicated vector with the set of vertices
|
||||||
|
// in the surface, transformed to the given space. This
|
||||||
|
// flavor returns the vertices in 4-dimensional
|
||||||
|
// homogenous space.
|
||||||
|
//
|
||||||
|
// Vertices are arranged in linear sequence, with the v
|
||||||
|
// coordinate changing more rapidly.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
get_vertices(pvector<LVecBase4f> &verts, const NodePath &rel_to) const {
|
||||||
|
int num_vertices = (int)_vertices.size();
|
||||||
|
verts.reserve(verts.size() + num_vertices);
|
||||||
|
int vi;
|
||||||
|
for (vi = 0; vi < num_vertices; vi++) {
|
||||||
|
NodePath space = _vertices[vi].get_space(rel_to);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::get_vertices
|
||||||
|
// Access: Public
|
||||||
|
// Description: Fills the indicated vector with the set of vertices
|
||||||
|
// in the surface, transformed to the given space. This
|
||||||
|
// flavor returns the vertices in 4-dimensional
|
||||||
|
// homogenous space.
|
||||||
|
//
|
||||||
|
// Vertices are arranged in linear sequence, with the v
|
||||||
|
// coordinate changing more rapidly.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
get_vertices(pvector<LPoint3f> &verts, const NodePath &rel_to) const {
|
||||||
|
int num_vertices = (int)_vertices.size();
|
||||||
|
verts.reserve(verts.size() + num_vertices);
|
||||||
|
int vi;
|
||||||
|
for (vi = 0; vi < num_vertices; vi++) {
|
||||||
|
const NodePath &space = _vertices[vi].get_space(rel_to);
|
||||||
|
LVecBase4f vertex = _vertices[vi].get_vertex();
|
||||||
|
if (!space.is_empty()) {
|
||||||
|
const LMatrix4f &mat = space.get_mat(rel_to);
|
||||||
|
vertex = vertex * mat;
|
||||||
|
}
|
||||||
|
LPoint3f v3(vertex[0] / vertex[3], vertex[1] / vertex[3], vertex[2] / vertex[3]);
|
||||||
|
verts.push_back(v3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::recompute_u_knots
|
||||||
|
// Access: Private
|
||||||
|
// Description: Creates a default knot vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
recompute_u_knots() {
|
||||||
|
_u_knots.clear();
|
||||||
|
int num_knots = get_num_u_knots();
|
||||||
|
_u_knots.reserve(num_knots);
|
||||||
|
|
||||||
|
float value = 0.0f;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < _u_order) {
|
||||||
|
_u_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (i < num_knots - _u_order) {
|
||||||
|
value += 1.0f;
|
||||||
|
_u_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
value += 1.0f;
|
||||||
|
while (i < num_knots) {
|
||||||
|
_u_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_u_knots_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::recompute_v_knots
|
||||||
|
// Access: Private
|
||||||
|
// Description: Creates a default knot vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
recompute_v_knots() {
|
||||||
|
_v_knots.clear();
|
||||||
|
int num_knots = get_num_v_knots();
|
||||||
|
_v_knots.reserve(num_knots);
|
||||||
|
|
||||||
|
float value = 0.0f;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < _v_order) {
|
||||||
|
_v_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (i < num_knots - _v_order) {
|
||||||
|
value += 1.0f;
|
||||||
|
_v_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
value += 1.0f;
|
||||||
|
while (i < num_knots) {
|
||||||
|
_v_knots.push_back(value);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_v_knots_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::recompute_u_basis
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recomputes the basis matrices according to the knot
|
||||||
|
// vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
recompute_u_basis() {
|
||||||
|
if (_u_knots_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_u_knots();
|
||||||
|
}
|
||||||
|
|
||||||
|
_u_basis.clear(_u_order);
|
||||||
|
if (_num_u_vertices > _u_order - 1) {
|
||||||
|
int min_knot = _u_order;
|
||||||
|
int max_knot = _num_u_vertices + 1;
|
||||||
|
|
||||||
|
for (int i = min_knot; i <= max_knot; i++) {
|
||||||
|
nassertv(i - 1 >= 0 && i < (int)_u_knots.size());
|
||||||
|
if (_u_knots[i - 1] < _u_knots[i]) {
|
||||||
|
// Here's a non-empty segment.
|
||||||
|
_u_basis.append_segment(i - _u_order, &_u_knots[i - _u_order]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_u_basis_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceEvaluator::recompute_v_basis
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recomputes the basis matrices according to the knot
|
||||||
|
// vector.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceEvaluator::
|
||||||
|
recompute_v_basis() {
|
||||||
|
if (_v_knots_dirty) {
|
||||||
|
((NurbsSurfaceEvaluator *)this)->recompute_v_knots();
|
||||||
|
}
|
||||||
|
|
||||||
|
_v_basis.clear(_v_order);
|
||||||
|
if (_num_v_vertices > _v_order - 1) {
|
||||||
|
int min_knot = _v_order;
|
||||||
|
int max_knot = _num_v_vertices + 1;
|
||||||
|
|
||||||
|
for (int i = min_knot; i <= max_knot; i++) {
|
||||||
|
nassertv(i - 1 >= 0 && i < (int)_v_knots.size());
|
||||||
|
if (_v_knots[i - 1] < _v_knots[i]) {
|
||||||
|
// Here's a non-empty segment.
|
||||||
|
_v_basis.append_segment(i - _v_order, &_v_knots[i - _v_order]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_v_basis_dirty = false;
|
||||||
|
}
|
113
panda/src/parametrics/nurbsSurfaceEvaluator.h
Normal file
113
panda/src/parametrics/nurbsSurfaceEvaluator.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Filename: nurbsSurfaceEvaluator.h
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 NURBSSURFACEEVALUATOR_H
|
||||||
|
#define NURBSSURFACEEVALUATOR_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "nurbsBasisVector.h"
|
||||||
|
#include "nurbsSurfaceResult.h"
|
||||||
|
#include "nurbsVertex.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "vector_float.h"
|
||||||
|
#include "pvector.h"
|
||||||
|
#include "nodePath.h"
|
||||||
|
#include "referenceCount.h"
|
||||||
|
#include "luse.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsSurfaceEvaluator
|
||||||
|
// Description : This class is an abstraction for evaluating NURBS
|
||||||
|
// surfaces. 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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsSurfaceEvaluator : public ReferenceCount {
|
||||||
|
PUBLISHED:
|
||||||
|
NurbsSurfaceEvaluator();
|
||||||
|
~NurbsSurfaceEvaluator();
|
||||||
|
|
||||||
|
INLINE void set_u_order(int u_order);
|
||||||
|
INLINE int get_u_order() const;
|
||||||
|
|
||||||
|
INLINE void set_v_order(int v_order);
|
||||||
|
INLINE int get_v_order() const;
|
||||||
|
|
||||||
|
void reset(int num_u_vertices, int num_v_vertices);
|
||||||
|
|
||||||
|
INLINE int get_num_u_vertices() const;
|
||||||
|
INLINE int get_num_v_vertices() const;
|
||||||
|
INLINE void set_vertex(int ui, int vi, const LVecBase4f &vertex);
|
||||||
|
INLINE void set_vertex(int ui, int vi, const LVecBase3f &vertex, float weight = 1.0);
|
||||||
|
INLINE const LVecBase4f &get_vertex(int ui, int vi) const;
|
||||||
|
|
||||||
|
INLINE void set_vertex_space(int ui, int vi, const NodePath &space);
|
||||||
|
INLINE void set_vertex_space(int ui, int vi, const string &space);
|
||||||
|
NodePath get_vertex_space(int ui, int vi, const NodePath &rel_to) const;
|
||||||
|
|
||||||
|
INLINE void set_extended_vertex(int ui, int vi, int d, float value);
|
||||||
|
INLINE float get_extended_vertex(int ui, int vi, int d) const;
|
||||||
|
|
||||||
|
INLINE int get_num_u_knots() const;
|
||||||
|
void set_u_knot(int i, float knot);
|
||||||
|
float get_u_knot(int i) const;
|
||||||
|
|
||||||
|
INLINE int get_num_v_knots() const;
|
||||||
|
void set_v_knot(int i, float knot);
|
||||||
|
float get_v_knot(int i) const;
|
||||||
|
|
||||||
|
PT(NurbsSurfaceResult) evaluate(const NodePath &rel_to = NodePath()) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void get_vertices(pvector<LVecBase4f> &verts, const NodePath &rel_to) const;
|
||||||
|
void get_vertices(pvector<LPoint3f> &verts, const NodePath &rel_to) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
INLINE NurbsVertex &vert(int ui, int vi);
|
||||||
|
INLINE const NurbsVertex &vert(int ui, int vi) const;
|
||||||
|
|
||||||
|
void recompute_u_knots();
|
||||||
|
void recompute_v_knots();
|
||||||
|
void recompute_u_basis();
|
||||||
|
void recompute_v_basis();
|
||||||
|
|
||||||
|
int _u_order;
|
||||||
|
int _v_order;
|
||||||
|
|
||||||
|
typedef pvector<NurbsVertex> Vertices;
|
||||||
|
Vertices _vertices;
|
||||||
|
int _num_u_vertices;
|
||||||
|
int _num_v_vertices;
|
||||||
|
|
||||||
|
bool _u_knots_dirty;
|
||||||
|
bool _v_knots_dirty;
|
||||||
|
typedef vector_float Knots;
|
||||||
|
Knots _u_knots;
|
||||||
|
Knots _v_knots;
|
||||||
|
|
||||||
|
bool _u_basis_dirty;
|
||||||
|
bool _v_basis_dirty;
|
||||||
|
NurbsBasisVector _u_basis;
|
||||||
|
NurbsBasisVector _v_basis;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nurbsSurfaceEvaluator.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
207
panda/src/parametrics/nurbsSurfaceResult.I
Normal file
207
panda/src/parametrics/nurbsSurfaceResult.I
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
// Filename: nurbsSurfaceResult.I
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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: NurbsSurfaceResult::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE NurbsSurfaceResult::
|
||||||
|
~NurbsSurfaceResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_start_u
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the first legal value of u on the surface.
|
||||||
|
// Usually this is 0.0.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_start_u() const {
|
||||||
|
return _u_basis.get_start_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_end_u
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the last legal value of u on the surface.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_end_u() const {
|
||||||
|
return _u_basis.get_end_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_start_v
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the first legal value of v on the surface.
|
||||||
|
// Usually this is 0.0.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_start_v() const {
|
||||||
|
return _v_basis.get_start_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_end_v
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the last legal value of v on the surface.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_end_v() const {
|
||||||
|
return _v_basis.get_end_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Computes the point on the surface corresponding to the
|
||||||
|
// indicated value in parametric time. Returns true if
|
||||||
|
// the t value is value, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool NurbsSurfaceResult::
|
||||||
|
eval_point(float u, float v, LVecBase3f &point) {
|
||||||
|
int ui = find_u_segment(u);
|
||||||
|
int vi = find_v_segment(v);
|
||||||
|
if (ui == -1 || vi == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_segment_point(ui, vi, _u_basis.scale_t(ui, u), _v_basis.scale_t(vi, v),
|
||||||
|
point);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_normal
|
||||||
|
// Access: Published
|
||||||
|
// Description: Computes the normal to the surface at the indicated
|
||||||
|
// point in parametric time. This normal vector will
|
||||||
|
// not necessarily be normalized, and could be zero.
|
||||||
|
// See also eval_point().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool NurbsSurfaceResult::
|
||||||
|
eval_normal(float u, float v, LVecBase3f &normal) {
|
||||||
|
int ui = find_u_segment(u);
|
||||||
|
int vi = find_v_segment(v);
|
||||||
|
if (ui == -1 || vi == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_segment_normal(ui, vi, _u_basis.scale_t(ui, u), _v_basis.scale_t(vi, v),
|
||||||
|
normal);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_extended_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Evaluates the surface in n-dimensional space according
|
||||||
|
// to the extended vertices associated with the surface in
|
||||||
|
// the indicated dimension.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
eval_extended_point(float u, float v, int d) {
|
||||||
|
int ui = find_u_segment(u);
|
||||||
|
int vi = find_v_segment(v);
|
||||||
|
if (ui == -1 || vi == -1) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eval_segment_extended_point(ui, vi, _u_basis.scale_t(ui, u),
|
||||||
|
_v_basis.scale_t(vi, v), d);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_num_u_segments
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the number of piecewise continuous segments
|
||||||
|
// within the surface in the U direction. This number
|
||||||
|
// is usually not important unless you plan to call
|
||||||
|
// eval_segment_point().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceResult::
|
||||||
|
get_num_u_segments() const {
|
||||||
|
return _u_basis.get_num_segments();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_num_v_segments
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the number of piecewise continuous segments
|
||||||
|
// within the surface in the V direction. This number
|
||||||
|
// is usually not important unless you plan to call
|
||||||
|
// eval_segment_point().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceResult::
|
||||||
|
get_num_v_segments() const {
|
||||||
|
return _v_basis.get_num_segments();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_segment_u
|
||||||
|
// Access: Public
|
||||||
|
// Description: Accepts a u value in the range [0, 1], and assumed to
|
||||||
|
// be relative to the indicated segment (as in
|
||||||
|
// eval_segment_point()), and returns the corresponding
|
||||||
|
// u value in the entire surface (as in eval_point()).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_segment_u(int ui, float u) const {
|
||||||
|
return u * (_u_basis.get_to(ui) - _u_basis.get_from(ui)) + _u_basis.get_from(ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::get_segment_v
|
||||||
|
// Access: Public
|
||||||
|
// Description: Accepts a v value in the range [0, 1], and assumed to
|
||||||
|
// be relative to the indicated segment (as in
|
||||||
|
// eval_segment_point()), and returns the corresponding
|
||||||
|
// v value in the entire surface (as in eval_point()).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float NurbsSurfaceResult::
|
||||||
|
get_segment_v(int vi, float v) const {
|
||||||
|
return v * (_v_basis.get_to(vi) - _v_basis.get_from(vi)) + _v_basis.get_from(vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::verti
|
||||||
|
// Access: Private
|
||||||
|
// Description: An internal function to dereference a 2-d vertex
|
||||||
|
// coordinate pair into a linear list of vertices. This
|
||||||
|
// returns the linear index corresponding to the 2-d
|
||||||
|
// pair.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceResult::
|
||||||
|
verti(int ui, int vi) const {
|
||||||
|
return ui * _num_v_vertices + vi;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::segi
|
||||||
|
// Access: Private
|
||||||
|
// Description: An internal function to dereference a 2-d segment
|
||||||
|
// coordinate pair into a linear list of segments. This
|
||||||
|
// returns the linear index corresponding to the 2-d
|
||||||
|
// pair.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int NurbsSurfaceResult::
|
||||||
|
segi(int ui, int vi) const {
|
||||||
|
return ui * _v_basis.get_num_segments() + vi;
|
||||||
|
}
|
337
panda/src/parametrics/nurbsSurfaceResult.cxx
Normal file
337
panda/src/parametrics/nurbsSurfaceResult.cxx
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
// Filename: nurbsSurfaceResult.cxx
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 "nurbsSurfaceResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NurbsSurfaceResult::
|
||||||
|
NurbsSurfaceResult(const NurbsBasisVector &u_basis,
|
||||||
|
const NurbsBasisVector &v_basis,
|
||||||
|
const LVecBase4f vecs[], const NurbsVertex *verts,
|
||||||
|
int num_u_vertices, int num_v_vertices) :
|
||||||
|
_u_basis(u_basis),
|
||||||
|
_v_basis(v_basis),
|
||||||
|
_verts(verts),
|
||||||
|
_num_u_vertices(num_u_vertices),
|
||||||
|
_num_v_vertices(num_v_vertices)
|
||||||
|
{
|
||||||
|
_last_u_segment = -1;
|
||||||
|
_last_v_segment = -1;
|
||||||
|
int u_order = _u_basis.get_order();
|
||||||
|
int v_order = _v_basis.get_order();
|
||||||
|
int num_u_segments = _u_basis.get_num_segments();
|
||||||
|
int num_v_segments = _v_basis.get_num_segments();
|
||||||
|
int num_segments = num_u_segments * num_v_segments;
|
||||||
|
|
||||||
|
_composed.reserve(num_segments);
|
||||||
|
for (int ui = 0; ui < num_u_segments; ui++) {
|
||||||
|
const LMatrix4f &u_basis_mat = _u_basis.get_basis(ui);
|
||||||
|
|
||||||
|
int un = _u_basis.get_vertex_index(ui);
|
||||||
|
nassertv(un >= 0 && un + u_order - 1 < _num_u_vertices);
|
||||||
|
|
||||||
|
for (int vi = 0; vi < num_v_segments; vi++) {
|
||||||
|
LMatrix4f v_basis_transpose = transpose(_v_basis.get_basis(vi));
|
||||||
|
|
||||||
|
int vn = _v_basis.get_vertex_index(vi);
|
||||||
|
nassertv(vn >= 0 && vn + v_order - 1 < _num_v_vertices);
|
||||||
|
|
||||||
|
// Create four geometry matrices from our (up to) sixteen
|
||||||
|
// involved vertices.
|
||||||
|
LVecBase4f c[4][4];
|
||||||
|
for (int uni = 0; uni < 4; uni++) {
|
||||||
|
for (int vni = 0; vni < 4; vni++) {
|
||||||
|
c[uni][vni] = (uni < u_order && vni < v_order) ?
|
||||||
|
vecs[verti(un + uni, vn + vni)] :
|
||||||
|
LVecBase4f::zero();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LMatrix4f geom_x(c[0][0][0], c[0][1][0], c[0][2][0], c[0][3][0],
|
||||||
|
c[1][0][0], c[1][1][0], c[1][2][0], c[1][3][0],
|
||||||
|
c[2][0][0], c[2][1][0], c[2][2][0], c[2][3][0],
|
||||||
|
c[3][0][0], c[3][1][0], c[3][2][0], c[3][3][0]);
|
||||||
|
|
||||||
|
LMatrix4f geom_y(c[0][0][1], c[0][1][1], c[0][2][1], c[0][3][1],
|
||||||
|
c[1][0][1], c[1][1][1], c[1][2][1], c[1][3][1],
|
||||||
|
c[2][0][1], c[2][1][1], c[2][2][1], c[2][3][1],
|
||||||
|
c[3][0][1], c[3][1][1], c[3][2][1], c[3][3][1]);
|
||||||
|
|
||||||
|
LMatrix4f geom_z(c[0][0][2], c[0][1][2], c[0][2][2], c[0][3][2],
|
||||||
|
c[1][0][2], c[1][1][2], c[1][2][2], c[1][3][2],
|
||||||
|
c[2][0][2], c[2][1][2], c[2][2][2], c[2][3][2],
|
||||||
|
c[3][0][2], c[3][1][2], c[3][2][2], c[3][3][2]);
|
||||||
|
|
||||||
|
LMatrix4f geom_w(c[0][0][3], c[0][1][3], c[0][2][3], c[0][3][3],
|
||||||
|
c[1][0][3], c[1][1][3], c[1][2][3], c[1][3][3],
|
||||||
|
c[2][0][3], c[2][1][3], c[2][2][3], c[2][3][3],
|
||||||
|
c[3][0][3], c[3][1][3], c[3][2][3], c[3][3][3]);
|
||||||
|
|
||||||
|
// And compose these geometry matrices with the basis matrices
|
||||||
|
// to produce a new set of matrices, which will be used to
|
||||||
|
// evaluate the surface.
|
||||||
|
ComposedMats result;
|
||||||
|
result._x = u_basis_mat * geom_x * v_basis_transpose;
|
||||||
|
result._y = u_basis_mat * geom_y * v_basis_transpose;
|
||||||
|
result._z = u_basis_mat * geom_z * v_basis_transpose;
|
||||||
|
result._w = u_basis_mat * geom_w * v_basis_transpose;
|
||||||
|
|
||||||
|
_composed.push_back(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertv((int)_composed.size() == num_segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_segment_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Evaluates the point on the surface corresponding to the
|
||||||
|
// indicated value in parametric time within the
|
||||||
|
// indicated surface segment. u and v should be in the
|
||||||
|
// range [0, 1].
|
||||||
|
//
|
||||||
|
// The surface is internally represented as a number of
|
||||||
|
// connected (or possibly unconnected) piecewise
|
||||||
|
// continuous segments. The exact number of segments
|
||||||
|
// for a particular surface depends on the knot vector,
|
||||||
|
// and is returned by get_num_segments(). Normally,
|
||||||
|
// eval_point() is used to evaluate a point along the
|
||||||
|
// continuous surface, but when you care more about local
|
||||||
|
// continuity, you can use eval_segment_point() to
|
||||||
|
// evaluate the points along each segment.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceResult::
|
||||||
|
eval_segment_point(int ui, int vi, float u, float v, LVecBase3f &point) const {
|
||||||
|
float u2 = u*u;
|
||||||
|
LVecBase4f uvec(u*u2, u2, u, 1.0f);
|
||||||
|
float v2 = v*v;
|
||||||
|
LVecBase4f vvec(v*v2, v2, v, 1.0f);
|
||||||
|
int i = segi(ui, vi);
|
||||||
|
nassertv(i >= 0 && i < (int)_composed.size());
|
||||||
|
|
||||||
|
float weight = vvec.dot(uvec * _composed[i]._w);
|
||||||
|
|
||||||
|
point.set(vvec.dot(uvec * _composed[i]._x) / weight,
|
||||||
|
vvec.dot(uvec * _composed[i]._y) / weight,
|
||||||
|
vvec.dot(uvec * _composed[i]._z) / weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_segment_normal
|
||||||
|
// Access: Published
|
||||||
|
// Description: As eval_segment_point, but computes the normal to
|
||||||
|
// the surface at the indicated point. The normal vector
|
||||||
|
// will not necessarily be normalized, and could be
|
||||||
|
// zero.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NurbsSurfaceResult::
|
||||||
|
eval_segment_normal(int ui, int vi, float u, float v, LVecBase3f &normal) const {
|
||||||
|
/*
|
||||||
|
float t2 = t*t;
|
||||||
|
LVecBase4f tvec(t2, t, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
normal.set(tvec.dot(_composed[segment].get_col(0)),
|
||||||
|
tvec.dot(_composed[segment].get_col(1)),
|
||||||
|
tvec.dot(_composed[segment].get_col(2)));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::eval_segment_extended_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Evaluates the surface in n-dimensional space according
|
||||||
|
// to the extended vertices associated with the surface in
|
||||||
|
// the indicated dimension.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float NurbsSurfaceResult::
|
||||||
|
eval_segment_extended_point(int ui, int vi, float u, float v, int d) const {
|
||||||
|
/*
|
||||||
|
nassertr(segment >= 0 && segment < _basis.get_num_segments(), 0.0f);
|
||||||
|
|
||||||
|
int order = _basis.get_order();
|
||||||
|
int vi = _basis.get_vertex_index(segment);
|
||||||
|
|
||||||
|
LVecBase4f geom;
|
||||||
|
int ci = 0;
|
||||||
|
while (ci < order) {
|
||||||
|
geom[ci] = _verts[vi + ci].get_extended_vertex(d);
|
||||||
|
ci++;
|
||||||
|
}
|
||||||
|
while (ci < 4) {
|
||||||
|
geom[ci] = 0.0f;
|
||||||
|
ci++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LMatrix4f &basis = _basis.get_basis(segment);
|
||||||
|
|
||||||
|
// Compute matrix * column vector.
|
||||||
|
LVecBase4f composed_geom(basis.get_row(0).dot(geom),
|
||||||
|
basis.get_row(1).dot(geom),
|
||||||
|
basis.get_row(2).dot(geom),
|
||||||
|
basis.get_row(3).dot(geom));
|
||||||
|
|
||||||
|
float t2 = t*t;
|
||||||
|
LVecBase4f tvec(t*t2, t2, t, 1.0f);
|
||||||
|
|
||||||
|
float weight = tvec.dot(_composed[segment].get_col(3));
|
||||||
|
|
||||||
|
float result = tvec.dot(composed_geom) / weight;
|
||||||
|
return result;
|
||||||
|
*/
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::find_u_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 NurbsSurfaceResult::
|
||||||
|
find_u_segment(float u) {
|
||||||
|
// Trivially check the endpoints of the surface.
|
||||||
|
if (u >= get_end_u()) {
|
||||||
|
return _u_basis.get_num_segments() - 1;
|
||||||
|
} else if (u <= get_start_u()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the last segment we searched for. Often, two consecutive
|
||||||
|
// requests are for the same segment.
|
||||||
|
if (_last_u_segment != -1 && (u >= _last_u_from && u < _last_u_to)) {
|
||||||
|
return _last_u_segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the segment the hard way.
|
||||||
|
int segment = r_find_u_segment(u, 0, _u_basis.get_num_segments() - 1);
|
||||||
|
if (segment != -1) {
|
||||||
|
_last_u_segment = segment;
|
||||||
|
_last_u_from = _u_basis.get_from(segment);
|
||||||
|
_last_u_to = _u_basis.get_to(segment);
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::r_find_u_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 NurbsSurfaceResult::
|
||||||
|
r_find_u_segment(float u, int top, int bot) const {
|
||||||
|
if (bot < top) {
|
||||||
|
// Not found.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int mid = (top + bot) / 2;
|
||||||
|
nassertr(mid >= 0 && mid < _u_basis.get_num_segments(), -1);
|
||||||
|
|
||||||
|
float from = _u_basis.get_from(mid);
|
||||||
|
float to = _u_basis.get_to(mid);
|
||||||
|
if (from > u) {
|
||||||
|
// Too high, try lower.
|
||||||
|
return r_find_u_segment(u, top, mid - 1);
|
||||||
|
|
||||||
|
} else if (to <= u) {
|
||||||
|
// Too low, try higher.
|
||||||
|
return r_find_u_segment(u, mid + 1, bot);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Here we are!
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::find_v_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 NurbsSurfaceResult::
|
||||||
|
find_v_segment(float v) {
|
||||||
|
// Trivially check the endpoints of the surface.
|
||||||
|
if (v >= get_end_v()) {
|
||||||
|
return _v_basis.get_num_segments() - 1;
|
||||||
|
} else if (v <= get_start_v()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the last segment we searched for. Often, two consecutive
|
||||||
|
// requests are for the same segment.
|
||||||
|
if (_last_v_segment != -1 && (v >= _last_v_from && v < _last_v_to)) {
|
||||||
|
return _last_v_segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the segment the hard way.
|
||||||
|
int segment = r_find_v_segment(v, 0, _v_basis.get_num_segments() - 1);
|
||||||
|
if (segment != -1) {
|
||||||
|
_last_v_segment = segment;
|
||||||
|
_last_v_from = _v_basis.get_from(segment);
|
||||||
|
_last_v_to = _v_basis.get_to(segment);
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NurbsSurfaceResult::r_find_v_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 NurbsSurfaceResult::
|
||||||
|
r_find_v_segment(float v, int top, int bot) const {
|
||||||
|
if (bot < top) {
|
||||||
|
// Not found.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int mid = (top + bot) / 2;
|
||||||
|
nassertr(mid >= 0 && mid < _v_basis.get_num_segments(), -1);
|
||||||
|
|
||||||
|
float from = _v_basis.get_from(mid);
|
||||||
|
float to = _v_basis.get_to(mid);
|
||||||
|
if (from > v) {
|
||||||
|
// Too high, try lower.
|
||||||
|
return r_find_v_segment(v, top, mid - 1);
|
||||||
|
|
||||||
|
} else if (to <= v) {
|
||||||
|
// Too low, try higher.
|
||||||
|
return r_find_v_segment(v, mid + 1, bot);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Here we are!
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
101
panda/src/parametrics/nurbsSurfaceResult.h
Normal file
101
panda/src/parametrics/nurbsSurfaceResult.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Filename: nurbsSurfaceResult.h
|
||||||
|
// Created by: drose (10Oct03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 NURBSSURFACERESULT_H
|
||||||
|
#define NURBSSURFACERESULT_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "referenceCount.h"
|
||||||
|
#include "nurbsBasisVector.h"
|
||||||
|
|
||||||
|
class NurbsVertex;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NurbsSurfaceResult
|
||||||
|
// Description : The result of a NurbsSurfaceEvaluator. This object
|
||||||
|
// represents a surface in a particular coordinate space.
|
||||||
|
// It can return the point and/or normal to the surface
|
||||||
|
// at any point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA NurbsSurfaceResult : public ReferenceCount {
|
||||||
|
public:
|
||||||
|
NurbsSurfaceResult(const NurbsBasisVector &u_basis,
|
||||||
|
const NurbsBasisVector &v_basis,
|
||||||
|
const LVecBase4f vecs[], const NurbsVertex *verts,
|
||||||
|
int num_u_vertices, int num_v_vertices);
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
INLINE ~NurbsSurfaceResult();
|
||||||
|
|
||||||
|
INLINE float get_start_u() const;
|
||||||
|
INLINE float get_end_u() const;
|
||||||
|
|
||||||
|
INLINE float get_start_v() const;
|
||||||
|
INLINE float get_end_v() const;
|
||||||
|
|
||||||
|
INLINE bool eval_point(float u, float v, LVecBase3f &point);
|
||||||
|
INLINE bool eval_normal(float u, float v, LVecBase3f &normal);
|
||||||
|
INLINE float eval_extended_point(float u, float v, int d);
|
||||||
|
|
||||||
|
INLINE int get_num_u_segments() const;
|
||||||
|
INLINE int get_num_v_segments() const;
|
||||||
|
void eval_segment_point(int ui, int vi, float u, float v, LVecBase3f &point) const;
|
||||||
|
void eval_segment_normal(int ui, int vi, float u, float v, LVecBase3f &normal) const;
|
||||||
|
float eval_segment_extended_point(int ui, int vi, float u, float v, int d) const;
|
||||||
|
INLINE float get_segment_u(int ui, float u) const;
|
||||||
|
INLINE float get_segment_v(int vi, float v) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
INLINE int verti(int ui, int vi) const;
|
||||||
|
INLINE int segi(int ui, int vi) const;
|
||||||
|
|
||||||
|
int find_u_segment(float u);
|
||||||
|
int r_find_u_segment(float u, int top, int bot) const;
|
||||||
|
int find_v_segment(float v);
|
||||||
|
int r_find_v_segment(float v, int top, int bot) const;
|
||||||
|
|
||||||
|
NurbsBasisVector _u_basis;
|
||||||
|
NurbsBasisVector _v_basis;
|
||||||
|
const NurbsVertex *_verts;
|
||||||
|
int _num_u_vertices;
|
||||||
|
int _num_v_vertices;
|
||||||
|
|
||||||
|
// We pre-compose the basis matrix and the geometry vectors, so we
|
||||||
|
// have these handy for evaluation. There is one entry in the
|
||||||
|
// _composed for each entry in u_basis._segments *
|
||||||
|
// v_basis._segments.
|
||||||
|
class ComposedMats {
|
||||||
|
public:
|
||||||
|
LMatrix4f _x, _y, _z, _w;
|
||||||
|
};
|
||||||
|
typedef pvector<ComposedMats> ComposedGeom;
|
||||||
|
ComposedGeom _composed;
|
||||||
|
|
||||||
|
|
||||||
|
int _last_u_segment;
|
||||||
|
float _last_u_from;
|
||||||
|
float _last_u_to;
|
||||||
|
int _last_v_segment;
|
||||||
|
float _last_v_from;
|
||||||
|
float _last_v_to;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nurbsSurfaceResult.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -5,6 +5,8 @@
|
|||||||
#include "parametricCurveDrawer.cxx"
|
#include "parametricCurveDrawer.cxx"
|
||||||
#include "nurbsCurveEvaluator.cxx"
|
#include "nurbsCurveEvaluator.cxx"
|
||||||
#include "nurbsCurveResult.cxx"
|
#include "nurbsCurveResult.cxx"
|
||||||
|
#include "nurbsSurfaceEvaluator.cxx"
|
||||||
|
#include "nurbsSurfaceResult.cxx"
|
||||||
#include "nurbsBasisVector.cxx"
|
#include "nurbsBasisVector.cxx"
|
||||||
#include "nurbsVertex.cxx"
|
#include "nurbsVertex.cxx"
|
||||||
#include "ropeNode.cxx"
|
#include "ropeNode.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user