extend nurbs interface for egg-qtess

This commit is contained in:
David Rose 2003-10-14 19:36:45 +00:00
parent 15f382d754
commit 3791dbaa71
21 changed files with 523 additions and 119 deletions

View File

@ -150,6 +150,20 @@ determine_bin() {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::copy_attributes
// Access: Public
// Description: Copies the rendering attributes from the indicated
// primitive.
////////////////////////////////////////////////////////////////////
void EggPrimitive::
copy_attributes(const EggPrimitive &other) {
EggAttributes::operator = (other);
set_texture(other.get_texture());
set_material(other.get_material());
set_bface_flag(other.get_bface_flag());
}
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::has_vertex_normal
// Access: Public

View File

@ -87,6 +87,8 @@ PUBLISHED:
INLINE void set_bface_flag(bool flag);
INLINE bool get_bface_flag() const;
void copy_attributes(const EggPrimitive &other);
bool has_vertex_normal() const;
bool has_vertex_color() const;

View File

@ -19,6 +19,7 @@
deferredNodeProperty.h \
eggBinner.h \
eggLoader.h \
egg_parametrics.h \
load_egg_file.h \
loaderFileTypeEgg.h
@ -30,6 +31,7 @@
deferredNodeProperty.cxx \
eggBinner.cxx \
eggLoader.cxx \
egg_parametrics.cxx \
load_egg_file.cxx \
loaderFileTypeEgg.cxx
@ -40,7 +42,7 @@
#endif
#define INSTALL_HEADERS \
load_egg_file.h config_egg2pg.h
egg_parametrics.h load_egg_file.h config_egg2pg.h
#define IGATESCAN load_egg_file.h

View File

@ -2,3 +2,4 @@
#include "characterMaker.cxx"
#include "computedVerticesMaker.cxx"
#include "config_egg2pg.cxx"
#include "egg_parametrics.cxx"

View File

@ -19,6 +19,7 @@
#include "pandabase.h"
#include "eggLoader.h"
#include "egg_parametrics.h"
#include "config_egg2pg.h"
#include "nodePath.h"
#include "renderState.h"
@ -463,46 +464,12 @@ make_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
assert(parent != NULL);
assert(!parent->is_geom_node());
PT(NurbsCurveEvaluator) nurbs = new NurbsCurveEvaluator;
if (egg_curve->get_order() < 1 || egg_curve->get_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSCurve order for " << egg_curve->get_name() << ": "
<< egg_curve->get_order() << "\n";
PT(NurbsCurveEvaluator) nurbs = ::make_nurbs_curve(egg_curve, mat);
if (nurbs == (NurbsCurveEvaluator *)NULL) {
_error = true;
return;
}
nurbs->set_order(egg_curve->get_order());
nurbs->reset(egg_curve->size());
EggPrimitive::const_iterator pi;
int vi = 0;
for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
EggVertex *egg_vertex = (*pi);
nurbs->set_vertex(vi, LCAST(float, egg_vertex->get_pos4() * mat));
Colorf color = egg_vertex->get_color();
nurbs->set_extended_vertex(vi, 0, color[0]);
nurbs->set_extended_vertex(vi, 1, color[1]);
nurbs->set_extended_vertex(vi, 2, color[2]);
nurbs->set_extended_vertex(vi, 3, color[3]);
vi++;
}
int num_knots = egg_curve->get_num_knots();
if (num_knots != nurbs->get_num_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSCurve number of knots for "
<< egg_curve->get_name() << ": got " << num_knots
<< " knots, expected " << nurbs->get_num_knots() << "\n";
_error = true;
return;
}
for (int i = 0; i < num_knots; i++) {
nurbs->set_knot(i, egg_curve->get_knot(i));
}
/*
switch (egg_curve->get_curve_type()) {
case EggCurve::CT_xyz:
@ -662,72 +629,12 @@ make_nurbs_surface(EggNurbsSurface *egg_surface, PandaNode *parent,
assert(parent != NULL);
assert(!parent->is_geom_node());
PT(NurbsSurfaceEvaluator) nurbs = new NurbsSurfaceEvaluator;
if (egg_surface->get_u_order() < 1 || egg_surface->get_u_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSSurface U order for " << egg_surface->get_name() << ": "
<< egg_surface->get_u_order() << "\n";
PT(NurbsSurfaceEvaluator) nurbs = ::make_nurbs_surface(egg_surface, mat);
if (nurbs == (NurbsSurfaceEvaluator *)NULL) {
_error = true;
return;
}
if (egg_surface->get_v_order() < 1 || egg_surface->get_v_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSSurface V order for " << egg_surface->get_name() << ": "
<< egg_surface->get_v_order() << "\n";
_error = true;
return;
}
nurbs->set_u_order(egg_surface->get_u_order());
nurbs->set_v_order(egg_surface->get_v_order());
int num_u_vertices = egg_surface->get_num_u_cvs();
int num_v_vertices = egg_surface->get_num_v_cvs();
nurbs->reset(num_u_vertices, num_v_vertices);
for (int ui = 0; ui < num_u_vertices; ui++) {
for (int vi = 0; vi < num_v_vertices; vi++) {
int i = egg_surface->get_vertex_index(ui, vi);
EggVertex *egg_vertex = egg_surface->get_vertex(i);
nurbs->set_vertex(ui, vi, LCAST(float, egg_vertex->get_pos4() * mat));
Colorf color = egg_vertex->get_color();
nurbs->set_extended_vertex(ui, vi, 0, color[0]);
nurbs->set_extended_vertex(ui, vi, 1, color[1]);
nurbs->set_extended_vertex(ui, vi, 2, color[2]);
nurbs->set_extended_vertex(ui, vi, 3, color[3]);
}
}
int num_u_knots = egg_surface->get_num_u_knots();
if (num_u_knots != nurbs->get_num_u_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSSurface number of U knots for "
<< egg_surface->get_name() << ": got " << num_u_knots
<< " knots, expected " << nurbs->get_num_u_knots() << "\n";
_error = true;
return;
}
int num_v_knots = egg_surface->get_num_v_knots();
if (num_v_knots != nurbs->get_num_v_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSSurface number of U knots for "
<< egg_surface->get_name() << ": got " << num_v_knots
<< " knots, expected " << nurbs->get_num_v_knots() << "\n";
_error = true;
return;
}
int i;
for (i = 0; i < num_u_knots; i++) {
nurbs->set_u_knot(i, egg_surface->get_u_knot(i));
}
for (i = 0; i < num_v_knots; i++) {
nurbs->set_v_knot(i, egg_surface->get_v_knot(i));
}
PT(SheetNode) sheet = new SheetNode(egg_surface->get_name());
sheet->set_surface(nurbs);

View File

@ -0,0 +1,141 @@
// Filename: egg_parametrics.cxx
// Created by: drose (13Oct03)
//
////////////////////////////////////////////////////////////////////
//
// 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 "egg_parametrics.h"
#include "config_egg2pg.h"
////////////////////////////////////////////////////////////////////
// Function: make_nurbs_surface
// Description: Returns a new NurbsSurfaceEvaluator that's filled in
// with the values from the given EggSurface (and
// transformed by the indicated matrix), or NULL if the
// object is invalid. If there is vertex color, it will
// be applied to values 0 - 3 of the extended vertex
// values.
////////////////////////////////////////////////////////////////////
PT(NurbsSurfaceEvaluator)
make_nurbs_surface(EggNurbsSurface *egg_surface, const LMatrix4d &mat) {
if (egg_surface->get_u_order() < 1 || egg_surface->get_u_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSSurface U order for " << egg_surface->get_name() << ": "
<< egg_surface->get_u_order() << "\n";
return NULL;
}
if (egg_surface->get_v_order() < 1 || egg_surface->get_v_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSSurface V order for " << egg_surface->get_name() << ": "
<< egg_surface->get_v_order() << "\n";
return NULL;
}
PT(NurbsSurfaceEvaluator) nurbs = new NurbsSurfaceEvaluator;
nurbs->set_u_order(egg_surface->get_u_order());
nurbs->set_v_order(egg_surface->get_v_order());
int num_u_vertices = egg_surface->get_num_u_cvs();
int num_v_vertices = egg_surface->get_num_v_cvs();
nurbs->reset(num_u_vertices, num_v_vertices);
for (int ui = 0; ui < num_u_vertices; ui++) {
for (int vi = 0; vi < num_v_vertices; vi++) {
int i = egg_surface->get_vertex_index(ui, vi);
EggVertex *egg_vertex = egg_surface->get_vertex(i);
nurbs->set_vertex(ui, vi, LCAST(float, egg_vertex->get_pos4() * mat));
Colorf color = egg_vertex->get_color();
nurbs->set_extended_vertices(ui, vi, 0, color.get_data(), 4);
}
}
int num_u_knots = egg_surface->get_num_u_knots();
if (num_u_knots != nurbs->get_num_u_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSSurface number of U knots for "
<< egg_surface->get_name() << ": got " << num_u_knots
<< " knots, expected " << nurbs->get_num_u_knots() << "\n";
return NULL;
}
int num_v_knots = egg_surface->get_num_v_knots();
if (num_v_knots != nurbs->get_num_v_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSSurface number of U knots for "
<< egg_surface->get_name() << ": got " << num_v_knots
<< " knots, expected " << nurbs->get_num_v_knots() << "\n";
return NULL;
}
int i;
for (i = 0; i < num_u_knots; i++) {
nurbs->set_u_knot(i, egg_surface->get_u_knot(i));
}
for (i = 0; i < num_v_knots; i++) {
nurbs->set_v_knot(i, egg_surface->get_v_knot(i));
}
return nurbs;
}
////////////////////////////////////////////////////////////////////
// Function: make_nurbs_curve
// Description: Returns a new NurbsCurveEvaluator that's filled in
// with the values from the given EggCurve (and
// transformed by the indicated matrix), or NULL if the
// object is invalid. If there is vertex color, it will
// be applied to values 0 - 3 of the extended vertex
// values.
////////////////////////////////////////////////////////////////////
PT(NurbsCurveEvaluator)
make_nurbs_curve(EggNurbsCurve *egg_curve, const LMatrix4d &mat) {
if (egg_curve->get_order() < 1 || egg_curve->get_order() > 4) {
egg2pg_cat.error()
<< "Invalid NURBSCurve order for " << egg_curve->get_name() << ": "
<< egg_curve->get_order() << "\n";
return NULL;
}
PT(NurbsCurveEvaluator) nurbs = new NurbsCurveEvaluator;
nurbs->set_order(egg_curve->get_order());
nurbs->reset(egg_curve->size());
EggPrimitive::const_iterator pi;
int vi = 0;
for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
EggVertex *egg_vertex = (*pi);
nurbs->set_vertex(vi, LCAST(float, egg_vertex->get_pos4() * mat));
Colorf color = egg_vertex->get_color();
nurbs->set_extended_vertices(vi, 0, color.get_data(), 4);
vi++;
}
int num_knots = egg_curve->get_num_knots();
if (num_knots != nurbs->get_num_knots()) {
egg2pg_cat.error()
<< "Invalid NURBSCurve number of knots for "
<< egg_curve->get_name() << ": got " << num_knots
<< " knots, expected " << nurbs->get_num_knots() << "\n";
return NULL;
}
for (int i = 0; i < num_knots; i++) {
nurbs->set_knot(i, egg_curve->get_knot(i));
}
return nurbs;
}

View File

@ -0,0 +1,57 @@
// Filename: egg_parametrics.h
// Created by: drose (13Oct03)
//
////////////////////////////////////////////////////////////////////
//
// 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 EGG_PARAMETRICS_H
#define EGG_PARAMETRICS_H
#include "pandabase.h"
#include "eggNurbsSurface.h"
#include "eggNurbsCurve.h"
#include "nurbsSurfaceEvaluator.h"
#include "nurbsCurveEvaluator.h"
BEGIN_PUBLISH
////////////////////////////////////////////////////////////////////
// Function: make_nurbs_surface
// Description: Returns a new NurbsSurfaceEvaluator that's filled in
// with the values from the given EggSurface (and
// transformed by the indicated matrix), or NULL if the
// object is invalid. If there is vertex color, it will
// be applied to values 0 - 3 of the extended vertex
// values.
////////////////////////////////////////////////////////////////////
EXPCL_PANDAEGG PT(NurbsSurfaceEvaluator)
make_nurbs_surface(EggNurbsSurface *egg_surface, const LMatrix4d &mat);
////////////////////////////////////////////////////////////////////
// Function: make_nurbs_curve
// Description: Returns a new NurbsCurveEvaluator that's filled in
// with the values from the given EggCurve (and
// transformed by the indicated matrix), or NULL if the
// object is invalid. If there is vertex color, it will
// be applied to values 0 - 3 of the extended vertex
// values.
////////////////////////////////////////////////////////////////////
EXPCL_PANDAEGG PT(NurbsCurveEvaluator)
make_nurbs_curve(EggNurbsCurve *egg_curve, const LMatrix4d &mat);
END_PUBLISH
#endif

View File

@ -66,6 +66,19 @@ append_segment(int vertex_index, const float knots[]) {
_segments.push_back(segment);
}
////////////////////////////////////////////////////////////////////
// Function: NurbsBasisVector::transpose
// Access: Public
// Description: Transposes the basis matrices stored in the vector.
////////////////////////////////////////////////////////////////////
void NurbsBasisVector::
transpose() {
Segments::iterator si;
for (si = _segments.begin(); si != _segments.end(); ++si) {
(*si)._basis.transpose_in_place();
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsBasisVector::nurbs_blending_function
// Access: Private, Static

View File

@ -59,6 +59,8 @@ public:
void clear(int order);
void append_segment(int vertex_index, const float knots[]);
void transpose();
private:
static LVecBase4f nurbs_blending_function(int order, int i, int j,
const float knots[]);

View File

@ -75,6 +75,25 @@ get_vertex_space(int i, const NodePath &rel_to) const {
return _vertices[i].get_space(rel_to);
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveEvaluator::set_extended_vertices
// Access: Public
// Description: Simultaneously sets several extended values in the
// slots d through (d + num_values - 1) from the
// num_values elements of the indicated array. This is
// equivalent to calling set_extended_vertex()
// num_values times. See set_extended_vertex().
////////////////////////////////////////////////////////////////////
void NurbsCurveEvaluator::
set_extended_vertices(int i, int d, const float values[], int num_values) {
nassertv(i >= 0 && i < (int)_vertices.size());
NurbsVertex &vertex = _vertices[i];
for (int n = 0; n < num_values; n++) {
vertex.set_extended_vertex(d + n, values[n]);
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveEvaluator::set_knot
// Access: Published
@ -106,6 +125,30 @@ get_knot(int i) const {
return _knots[i];
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveEvaluator::normalize_knots
// Access: Published
// Description: Normalizes the knot sequence so that the parametric
// range of the curve is 0 .. 1.
////////////////////////////////////////////////////////////////////
void NurbsCurveEvaluator::
normalize_knots() {
if (_knots_dirty) {
recompute_knots();
}
if (get_num_vertices() > _order - 1) {
double min_value = _knots[_order - 1];
double max_value = _knots[get_num_vertices()];
double range = (max_value - min_value);
for (Knots::iterator ki = _knots.begin(); ki != _knots.end(); ++ki) {
(*ki) = ((*ki) - min_value) / range;
}
_basis_dirty = true;
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveEvaluator::evaluate
// Access: Published

View File

@ -67,10 +67,13 @@ PUBLISHED:
INLINE void set_extended_vertex(int i, int d, float value);
INLINE float get_extended_vertex(int i, int d) const;
void set_extended_vertices(int i, int d,
const float values[], int num_values);
INLINE int get_num_knots() const;
void set_knot(int i, float knot);
float get_knot(int i) const;
void normalize_knots();
INLINE int get_num_segments() const;

View File

@ -52,7 +52,7 @@ get_end_t() const {
// 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.
// the t value is valid, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool NurbsCurveResult::
eval_point(float t, LVecBase3f &point) {
@ -101,6 +101,27 @@ eval_extended_point(float t, int d) {
return eval_segment_extended_point(segment, _basis.scale_t(segment, t), d);
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveResult::eval_extended_points
// Access: Published
// Description: Simultaneously performs eval_extended_point on a
// contiguous sequence of dimensions. The dimensions
// evaluated are d through (d + num_values - 1); the
// results are filled into the num_values elements in
// the indicated result array.
////////////////////////////////////////////////////////////////////
INLINE bool NurbsCurveResult::
eval_extended_points(float t, int d, float result[], int num_values) {
int segment = find_segment(t);
if (segment == -1) {
return false;
}
eval_segment_extended_points(segment, _basis.scale_t(segment, t), d,
result, num_values);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveResult::get_num_segments
// Access: Public

View File

@ -121,6 +121,13 @@ float NurbsCurveResult::
eval_segment_extended_point(int segment, float t, int d) const {
nassertr(segment >= 0 && segment < _basis.get_num_segments(), 0.0f);
float t2 = t*t;
LVecBase4f tvec(t*t2, t2, t, 1.0f);
float weight = tvec.dot(_composed[segment].get_col(3));
// Calculate the composition of the basis matrix and the geometry
// matrix on-the-fly.
int order = _basis.get_order();
int vi = _basis.get_vertex_index(segment);
@ -142,14 +149,53 @@ eval_segment_extended_point(int segment, float t, int d) const {
basis.get_row(1).dot(geom),
basis.get_row(2).dot(geom),
basis.get_row(3).dot(geom));
return tvec.dot(composed_geom) / weight;
}
////////////////////////////////////////////////////////////////////
// Function: NurbsCurveResult::eval_segment_extended_points
// Access: Published
// Description: Simultaneously performs eval_extended_point on a
// contiguous sequence of dimensions. The dimensions
// evaluated are d through (d + num_values - 1); the
// results are filled into the num_values elements in
// the indicated result array.
////////////////////////////////////////////////////////////////////
void NurbsCurveResult::
eval_segment_extended_points(int segment, float t, int d,
float result[], int num_values) const {
nassertv(segment >= 0 && segment < _basis.get_num_segments());
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;
// Calculate the composition of the basis matrix and the geometry
// matrix on-the-fly.
const LMatrix4f &basis = _basis.get_basis(segment);
int order = _basis.get_order();
int vi = _basis.get_vertex_index(segment);
for (int n = 0; n < num_values; n++) {
LVecBase4f geom;
int ci = 0;
while (ci < order) {
geom[ci] = _verts[vi + ci].get_extended_vertex(d + n);
ci++;
}
while (ci < 4) {
geom[ci] = 0.0f;
ci++;
}
// 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));
result[n] = tvec.dot(composed_geom) / weight;
}
}
////////////////////////////////////////////////////////////////////

View File

@ -54,11 +54,15 @@ PUBLISHED:
INLINE bool eval_point(float t, LVecBase3f &point);
INLINE bool eval_tangent(float t, LVecBase3f &tangent);
INLINE float eval_extended_point(float t, int d);
INLINE bool eval_extended_points(float t, int d,
float result[], int num_values);
INLINE int get_num_segments() const;
void eval_segment_point(int segment, float t, LVecBase3f &point) const;
void eval_segment_tangent(int segment, float t, LVecBase3f &tangent) const;
float eval_segment_extended_point(int segment, float t, int d) const;
void eval_segment_extended_points(int segment, float t, int d,
float result[], int num_values) const;
INLINE float get_segment_t(int segment, float t) const;
private:

View File

@ -84,6 +84,27 @@ get_vertex_space(int ui, int vi, const NodePath &rel_to) const {
return vert(ui, vi).get_space(rel_to);
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::set_extended_vertices
// Access: Public
// Description: Simultaneously sets several extended values in the
// slots d through (d + num_values - 1) from the
// num_values elements of the indicated array. This is
// equivalent to calling set_extended_vertex()
// num_values times. See set_extended_vertex().
////////////////////////////////////////////////////////////////////
void NurbsSurfaceEvaluator::
set_extended_vertices(int ui, int vi, int d,
const float values[], int num_values) {
nassertv(ui >= 0 && ui < _num_u_vertices &&
vi >= 0 && vi < _num_v_vertices);
NurbsVertex &vertex = vert(ui, vi);
for (int n = 0; n < num_values; n++) {
vertex.set_extended_vertex(d + n, values[n]);
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::set_u_knot
// Access: Published
@ -115,6 +136,30 @@ get_u_knot(int i) const {
return _u_knots[i];
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::normalize_u_knots
// Access: Published
// Description: Normalizes the knot sequence so that the parametric
// range of the surface in the U direction is 0 .. 1.
////////////////////////////////////////////////////////////////////
void NurbsSurfaceEvaluator::
normalize_u_knots() {
if (_u_knots_dirty) {
recompute_u_knots();
}
if (_num_u_vertices > _u_order - 1) {
double min_value = _u_knots[_u_order - 1];
double max_value = _u_knots[_num_u_vertices];
double range = (max_value - min_value);
for (Knots::iterator ki = _u_knots.begin(); ki != _u_knots.end(); ++ki) {
(*ki) = ((*ki) - min_value) / range;
}
_u_basis_dirty = true;
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::set_v_knot
// Access: Published
@ -146,6 +191,30 @@ get_v_knot(int i) const {
return _v_knots[i];
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::normalize_v_knots
// Access: Published
// Description: Normalizes the knot sequence so that the parametric
// range of the surface in the U direction is 0 .. 1.
////////////////////////////////////////////////////////////////////
void NurbsSurfaceEvaluator::
normalize_v_knots() {
if (_v_knots_dirty) {
recompute_v_knots();
}
if (_num_v_vertices > _v_order - 1) {
double min_value = _v_knots[_v_order - 1];
double max_value = _v_knots[_num_v_vertices];
double range = (max_value - min_value);
for (Knots::iterator ki = _v_knots.begin(); ki != _v_knots.end(); ++ki) {
(*ki) = ((*ki) - min_value) / range;
}
_v_basis_dirty = true;
}
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceEvaluator::evaluate
// Access: Published

View File

@ -64,14 +64,18 @@ PUBLISHED:
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;
void set_extended_vertices(int ui, int vi, int d,
const float values[], int num_values);
INLINE int get_num_u_knots() const;
void set_u_knot(int i, float knot);
float get_u_knot(int i) const;
void normalize_u_knots();
INLINE int get_num_v_knots() const;
void set_v_knot(int i, float knot);
float get_v_knot(int i) const;
void normalize_v_knots();
INLINE int get_num_u_segments() const;
INLINE int get_num_v_segments() const;

View File

@ -73,7 +73,7 @@ get_end_v() const {
// 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.
// the u, v values are valid, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool NurbsSurfaceResult::
eval_point(float u, float v, LVecBase3f &point) {
@ -128,6 +128,30 @@ eval_extended_point(float u, float v, int d) {
_v_basis.scale_t(vi, v), d);
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceResult::eval_extended_points
// Access: Published
// Description: Simultaneously performs eval_extended_point on a
// contiguous sequence of dimensions. The dimensions
// evaluated are d through (d + num_values - 1); the
// results are filled into the num_values elements in
// the indicated result array.
////////////////////////////////////////////////////////////////////
INLINE bool NurbsSurfaceResult::
eval_extended_points(float u, float v, int d, float result[],
int num_values) {
int ui = find_u_segment(u);
int vi = find_v_segment(v);
if (ui == -1 || vi == -1) {
return false;
}
eval_segment_extended_points(ui, vi, _u_basis.scale_t(ui, u),
_v_basis.scale_t(vi, v), d, result,
num_values);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceResult::get_num_u_segments
// Access: Public

View File

@ -37,6 +37,9 @@ NurbsSurfaceResult(const NurbsBasisVector &u_basis,
_num_u_vertices(num_u_vertices),
_num_v_vertices(num_v_vertices)
{
// The V basis matrices will always be transposed.
_v_basis.transpose();
_last_u_segment = -1;
_last_v_segment = -1;
int u_order = _u_basis.get_order();
@ -51,7 +54,7 @@ NurbsSurfaceResult(const NurbsBasisVector &u_basis,
}
for (int vi = 0; vi < num_v_segments; vi++) {
LMatrix4f v_basis_transpose = transpose(_v_basis.get_basis(vi));
const LMatrix4f &v_basis_transpose = _v_basis.get_basis(vi);
int vn = _v_basis.get_vertex_index(vi);
nassertv(vn >= 0 && vn + v_order - 1 < _num_v_vertices);
@ -171,9 +174,19 @@ eval_segment_normal(int ui, int vi, float u, float v, LVecBase3f &normal) const
////////////////////////////////////////////////////////////////////
float NurbsSurfaceResult::
eval_segment_extended_point(int ui, int vi, float u, float v, int d) const {
int i = segi(ui, vi);
nassertr(i >= 0 && i < (int)_composed.size(), 0.0f);
float u2 = u*u;
LVecBase4f uvec(u*u2, u2, u, 1.0f);
float v2 = v*v;
LVecBase4f vvec(v*v2, v2, v, 1.0f);
float weight = vvec.dot(uvec * _composed[i]._w);
// Calculate the composition of the basis matrices and the geometry
// matrix on-the-fly.
LMatrix4f v_basis_transpose = transpose(_v_basis.get_basis(vi));
const LMatrix4f &v_basis_transpose = _v_basis.get_basis(vi);
const LMatrix4f &u_basis_mat = _u_basis.get_basis(ui);
int u_order = _u_basis.get_order();
int v_order = _v_basis.get_order();
@ -193,9 +206,23 @@ eval_segment_extended_point(int ui, int vi, float u, float v, int d) const {
}
LMatrix4f composed = u_basis_mat * geom * v_basis_transpose;
return vvec.dot(uvec * composed) / weight;
}
////////////////////////////////////////////////////////////////////
// Function: NurbsSurfaceResult::eval_segment_extended_points
// Access: Published
// Description: Simultaneously performs eval_extended_point on a
// contiguous sequence of dimensions. The dimensions
// evaluated are d through (d + num_values - 1); the
// results are filled into the num_values elements in
// the indicated result array.
////////////////////////////////////////////////////////////////////
void NurbsSurfaceResult::
eval_segment_extended_points(int ui, int vi, float u, float v, int d,
float result[], int num_values) const {
int i = segi(ui, vi);
nassertr(i >= 0 && i < (int)_composed.size(), 0.0f);
nassertv(i >= 0 && i < (int)_composed.size());
float u2 = u*u;
LVecBase4f uvec(u*u2, u2, u, 1.0f);
@ -203,7 +230,33 @@ eval_segment_extended_point(int ui, int vi, float u, float v, int d) const {
LVecBase4f vvec(v*v2, v2, v, 1.0f);
float weight = vvec.dot(uvec * _composed[i]._w);
return vvec.dot(uvec * composed) / weight;
// Calculate the composition of the basis matrices and the geometry
// matrix on-the-fly.
const LMatrix4f &v_basis_transpose = _v_basis.get_basis(vi);
const LMatrix4f &u_basis_mat = _u_basis.get_basis(ui);
int u_order = _u_basis.get_order();
int v_order = _v_basis.get_order();
int un = _u_basis.get_vertex_index(ui);
int vn = _v_basis.get_vertex_index(vi);
for (int n = 0; n < num_values; n++) {
LMatrix4f geom;
memset(&geom, 0, sizeof(geom));
for (int uni = 0; uni < 4; uni++) {
for (int vni = 0; vni < 4; vni++) {
if (uni < u_order && vni < v_order) {
geom(uni, vni) =
_verts[verti(un + uni, vn + vni)].get_extended_vertex(d + n);
}
}
}
LMatrix4f composed = u_basis_mat * geom * v_basis_transpose;
result[n] = vvec.dot(uvec * composed) / weight;
}
}
////////////////////////////////////////////////////////////////////

View File

@ -51,12 +51,16 @@ PUBLISHED:
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 bool eval_extended_points(float u, float v, int d,
float result[], int num_values);
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;
void eval_segment_extended_points(int ui, int vi, float u, float v, int d,
float result[], int num_values) const;
INLINE float get_segment_u(int ui, float u) const;
INLINE float get_segment_v(int vi, float v) const;

View File

@ -287,10 +287,8 @@ render_thread(CullTraverser *trav, CullTraverserData &data,
verts.push_back(point);
if (use_vertex_color) {
Colorf color(result->eval_segment_extended_point(segment, t, 0),
result->eval_segment_extended_point(segment, t, 1),
result->eval_segment_extended_point(segment, t, 2),
result->eval_segment_extended_point(segment, t, 3));
Colorf color;
result->eval_segment_extended_points(segment, t, 0, &color[0], 4),
colors.push_back(color);
}

View File

@ -293,15 +293,11 @@ render_sheet(CullTraverser *trav, CullTraverserData &data,
uvs.push_back(TexCoordf(u1_tc, v_tc));
if (use_vertex_color) {
Colorf c0(result->eval_segment_extended_point(ui, vi, u0, v, 0),
result->eval_segment_extended_point(ui, vi, u0, v, 1),
result->eval_segment_extended_point(ui, vi, u0, v, 2),
result->eval_segment_extended_point(ui, vi, u0, v, 3));
Colorf c0, c1;
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
colors.push_back(c0);
Colorf c1(result->eval_segment_extended_point(ui, vi, u1, v, 0),
result->eval_segment_extended_point(ui, vi, u1, v, 1),
result->eval_segment_extended_point(ui, vi, u1, v, 2),
result->eval_segment_extended_point(ui, vi, u1, v, 3));
colors.push_back(c1);
}
}