mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
RM_billboard, etc.
This commit is contained in:
parent
0be100989d
commit
a39fe8b02f
@ -16,7 +16,7 @@
|
||||
parametricCurveDrawer.h curveFitter.I curveFitter.h \
|
||||
hermiteCurve.h nurbsCurve.h \
|
||||
nurbsCurveDrawer.I nurbsCurveDrawer.h \
|
||||
nurbsCurveEvaluator.h \
|
||||
nurbsCurveEvaluator.I nurbsCurveEvaluator.h \
|
||||
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||
nurbsCurveResult.I nurbsCurveResult.h \
|
||||
nurbsMatrixVector.I nurbsMatrixVector.h \
|
||||
@ -50,7 +50,7 @@
|
||||
hermiteCurve.h \
|
||||
nurbsCurve.h \
|
||||
nurbsCurveDrawer.I nurbsCurveDrawer.h \
|
||||
nurbsCurveEvaluator.h \
|
||||
nurbsCurveEvaluator.I nurbsCurveEvaluator.h \
|
||||
nurbsCurveInterface.I nurbsCurveInterface.h \
|
||||
nurbsCurveResult.I nurbsCurveResult.h \
|
||||
nurbsMatrixVector.I nurbsMatrixVector.h \
|
||||
|
140
panda/src/parametrics/nurbsCurveEvaluator.I
Normal file
140
panda/src/parametrics/nurbsCurveEvaluator.I
Normal file
@ -0,0 +1,140 @@
|
||||
// Filename: nurbsCurveEvaluator.I
|
||||
// Created by: drose (05Dec02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: NurbsCurveEvaluator::set_order
|
||||
// Access: Published
|
||||
// Description: Sets the order of the curve. This resets the knot
|
||||
// vector to the default knot vector for the number of
|
||||
// vertices.
|
||||
//
|
||||
// The order must be 1, 2, 3, or 4, and the value is one
|
||||
// more than the degree of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsCurveEvaluator::
|
||||
set_order(int order) {
|
||||
_order = order;
|
||||
_knots_dirty = true;
|
||||
_basis_dirty = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_order
|
||||
// Access: Published
|
||||
// Description: Returns the order of the curve as set by a previous
|
||||
// call to set_order().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NurbsCurveEvaluator::
|
||||
get_order() const {
|
||||
return _order;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of control vertices in the curve.
|
||||
// This is the number passed to the last call to
|
||||
// reset().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NurbsCurveEvaluator::
|
||||
get_num_vertices() const {
|
||||
return (int)_vertices.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the nth control vertex of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsCurveEvaluator::
|
||||
set_vertex(int i, const LVecBase4f &vertex) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_vertex(vertex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the nth control vertex of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsCurveEvaluator::
|
||||
set_vertex(int i, const LVecBase3f &vertex, float weight) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_vertex(LVecBase4f(vertex[0] * weight, vertex[1] * weight, vertex[2] * weight, weight));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the nth control vertex of the curve, relative
|
||||
// to its indicated coordinate space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase4f &NurbsCurveEvaluator::
|
||||
get_vertex(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_vertices.size(), LVecBase4f::zero());
|
||||
return _vertices[i].get_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex_space
|
||||
// Access: Published
|
||||
// Description: Sets the coordinate space of the nth control vertex.
|
||||
// If this is not specified, or is set to an empty
|
||||
// NodePath, the nth control vertex is deemed to be in
|
||||
// the coordinate space passed to evaluate().
|
||||
//
|
||||
// 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 curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsCurveEvaluator::
|
||||
set_vertex_space(int i, const NodePath &space) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_space(space);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex_space
|
||||
// Access: Published
|
||||
// Description: Sets the coordinate space of the nth control vertex.
|
||||
// If this is not specified, or is set to an empty
|
||||
// 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 curve is evaluated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsCurveEvaluator::
|
||||
set_vertex_space(int i, const string &space) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_space(space);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_num_knots
|
||||
// Access: Published
|
||||
// Description: Returns the number of knot values in the curve. This
|
||||
// is based on the number of vertices and the order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NurbsCurveEvaluator::
|
||||
get_num_knots() const {
|
||||
return (int)_vertices.size() + _order;
|
||||
}
|
@ -39,34 +39,6 @@ NurbsCurveEvaluator::
|
||||
~NurbsCurveEvaluator() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_order
|
||||
// Access: Published
|
||||
// Description: Sets the order of the curve. This resets the knot
|
||||
// vector to the default knot vector for the number of
|
||||
// vertices.
|
||||
//
|
||||
// The order must be 1, 2, 3, or 4, and the value is one
|
||||
// more than the degree of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NurbsCurveEvaluator::
|
||||
set_order(int order) {
|
||||
_order = order;
|
||||
_knots_dirty = true;
|
||||
_basis_dirty = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_order
|
||||
// Access: Published
|
||||
// Description: Returns the order of the curve as set by a previous
|
||||
// call to set_order().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NurbsCurveEvaluator::
|
||||
get_order() const {
|
||||
return _order;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::reset
|
||||
// Access: Published
|
||||
@ -88,90 +60,19 @@ reset(int num_vertices) {
|
||||
_basis_dirty = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of control vertices in the curve.
|
||||
// This is the number passed to the last call to
|
||||
// reset().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NurbsCurveEvaluator::
|
||||
get_num_vertices() const {
|
||||
return (int)_vertices.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the nth control vertex of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NurbsCurveEvaluator::
|
||||
set_vertex(int i, const LVecBase4f &vertex) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_vertex(vertex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the nth control vertex of the curve.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NurbsCurveEvaluator::
|
||||
set_vertex(int i, const LVecBase3f &vertex, float weight) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_vertex(LVecBase4f(vertex[0] * weight, vertex[1] * weight, vertex[2] * weight, weight));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the nth control vertex of the curve, relative
|
||||
// to its indicated coordinate space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LVecBase4f &NurbsCurveEvaluator::
|
||||
get_vertex(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_vertices.size(), LVecBase4f::zero());
|
||||
return _vertices[i].get_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::set_vertex_space
|
||||
// Access: Published
|
||||
// Description: Sets the coordinate space of the nth control vertex.
|
||||
// If this is not specified, or is set to an empty
|
||||
// NodePath, the nth control vertex is deemed to be in
|
||||
// the coordinate space passed to evaluate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NurbsCurveEvaluator::
|
||||
set_vertex_space(int i, const NodePath &space) {
|
||||
nassertv(i >= 0 && i < (int)_vertices.size());
|
||||
_vertices[i].set_space(space);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_vertex_space
|
||||
// Access: Published
|
||||
// Description: Returns the coordinate space of the nth control
|
||||
// vertex of the curve, expressed as a NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const NodePath &NurbsCurveEvaluator::
|
||||
get_vertex_space(int i) const {
|
||||
NodePath NurbsCurveEvaluator::
|
||||
get_vertex_space(int i, const NodePath &rel_to) const {
|
||||
#ifndef NDEBUG
|
||||
static NodePath empty_node_path;
|
||||
nassertr(i >= 0 && i < (int)_vertices.size(), empty_node_path);
|
||||
#endif
|
||||
return _vertices[i].get_space();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveEvaluator::get_num_knots
|
||||
// Access: Published
|
||||
// Description: Returns the number of knot values in the curve. This
|
||||
// is based on the number of vertices and the order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NurbsCurveEvaluator::
|
||||
get_num_knots() const {
|
||||
return (int)_vertices.size() + _order;
|
||||
return _vertices[i].get_space(rel_to);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -242,7 +143,7 @@ get_vertices(pvector<LVecBase4f> &verts, const NodePath &rel_to) const {
|
||||
verts.reserve(verts.size() + num_vertices);
|
||||
int vi;
|
||||
for (vi = 0; vi < num_vertices; vi++) {
|
||||
const NodePath &space = _vertices[vi].get_space();
|
||||
NodePath space = _vertices[vi].get_space(rel_to);
|
||||
const LVecBase4f &vertex = _vertices[vi].get_vertex();
|
||||
if (space.is_empty()) {
|
||||
verts.push_back(vertex);
|
||||
@ -267,7 +168,7 @@ get_vertices(pvector<LPoint3f> &verts, const NodePath &rel_to) const {
|
||||
verts.reserve(verts.size() + num_vertices);
|
||||
int vi;
|
||||
for (vi = 0; vi < num_vertices; vi++) {
|
||||
const NodePath &space = _vertices[vi].get_space();
|
||||
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);
|
||||
|
@ -50,20 +50,21 @@ PUBLISHED:
|
||||
NurbsCurveEvaluator();
|
||||
~NurbsCurveEvaluator();
|
||||
|
||||
void set_order(int order);
|
||||
int get_order() const;
|
||||
INLINE void set_order(int order);
|
||||
INLINE int get_order() const;
|
||||
|
||||
void reset(int num_vertices);
|
||||
|
||||
int get_num_vertices() const;
|
||||
void set_vertex(int i, const LVecBase4f &vertex);
|
||||
void set_vertex(int i, const LVecBase3f &vertex, float weight = 1.0);
|
||||
const LVecBase4f &get_vertex(int i) const;
|
||||
INLINE int get_num_vertices() const;
|
||||
INLINE void set_vertex(int i, const LVecBase4f &vertex);
|
||||
INLINE void set_vertex(int i, const LVecBase3f &vertex, float weight = 1.0);
|
||||
INLINE const LVecBase4f &get_vertex(int i) const;
|
||||
|
||||
void set_vertex_space(int i, const NodePath &space);
|
||||
const NodePath &get_vertex_space(int i) const;
|
||||
INLINE void set_vertex_space(int i, const NodePath &space);
|
||||
INLINE void set_vertex_space(int i, const string &space);
|
||||
NodePath get_vertex_space(int i, const NodePath &rel_to) const;
|
||||
|
||||
int get_num_knots() const;
|
||||
INLINE int get_num_knots() const;
|
||||
void set_knot(int i, float knot);
|
||||
float get_knot(int i) const;
|
||||
|
||||
@ -90,5 +91,7 @@ private:
|
||||
NurbsMatrixVector _basis;
|
||||
};
|
||||
|
||||
#include "nurbsCurveEvaluator.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -65,6 +65,25 @@ eval_point(float t, LVecBase3f &point) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveResult::eval_tangent
|
||||
// Access: Published
|
||||
// Description: Computes the tangent to the curve at the indicated
|
||||
// point in parametric time. This tangent vector will
|
||||
// not necessarily be normalized, and could be zero.
|
||||
// See also eval_point().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NurbsCurveResult::
|
||||
eval_tangent(float t, LVecBase3f &tangent) {
|
||||
int segment = find_segment(t);
|
||||
if (segment == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eval_segment_tangent(segment, _prod.scale_t(segment, t), tangent);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveResult::get_num_segments
|
||||
// Access: Public
|
||||
@ -77,3 +96,16 @@ INLINE int NurbsCurveResult::
|
||||
get_num_segments() const {
|
||||
return _prod.get_num_segments();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveResult::get_segment_t
|
||||
// Access: Public
|
||||
// Description: Accepts a t value in the range [0, 1], and assumed to
|
||||
// be relative to the indicated segment (as in
|
||||
// eval_segment_point()), and returns the corresponding
|
||||
// t value in the entire curve (as in eval_point()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float NurbsCurveResult::
|
||||
get_segment_t(int segment, float t) const {
|
||||
return t * (_prod.get_to(segment) - _prod.get_from(segment)) + _prod.get_from(segment);
|
||||
}
|
||||
|
@ -82,6 +82,24 @@ eval_segment_point(int segment, float t, LVecBase3f &point) const {
|
||||
point.set(r[0] / r[3], r[1] / r[3], r[2] / r[3]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveResult::eval_segment_tangent
|
||||
// Access: Published
|
||||
// Description: As eval_segment_point, but computes the tangent to
|
||||
// the curve at the indicated point. The tangent vector
|
||||
// will not necessarily be normalized, and could be
|
||||
// zero, particularly at the endpoints.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NurbsCurveResult::
|
||||
eval_segment_tangent(int segment, float t, LVecBase3f &tangent) const {
|
||||
const LMatrix4f &mat = _prod.get_matrix(segment);
|
||||
|
||||
float t2 = t*t;
|
||||
LVecBase4f tvec(t2, t, 1.0f, 0.0f);
|
||||
LVecBase4f r = tvec * mat;
|
||||
tangent.set(r[0], r[1], r[2]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsCurveResult::find_segment
|
||||
// Access: Private
|
||||
|
@ -49,9 +49,12 @@ PUBLISHED:
|
||||
INLINE float get_end_t() const;
|
||||
|
||||
INLINE bool eval_point(float t, LVecBase3f &point);
|
||||
INLINE bool eval_tangent(float t, LVecBase3f &tangent);
|
||||
|
||||
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;
|
||||
INLINE float get_segment_t(int segment, float t) const;
|
||||
|
||||
private:
|
||||
int find_segment(float t);
|
||||
|
@ -34,7 +34,8 @@ NurbsVertex() {
|
||||
INLINE NurbsVertex::
|
||||
NurbsVertex(const NurbsVertex ©) :
|
||||
_vertex(copy._vertex),
|
||||
_space(copy._space)
|
||||
_space(copy._space),
|
||||
_space_path(copy._space_path)
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,6 +48,7 @@ INLINE void NurbsVertex::
|
||||
operator = (const NurbsVertex ©) {
|
||||
_vertex = copy._vertex;
|
||||
_space = copy._space;
|
||||
_space_path = copy._space_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -81,11 +83,24 @@ get_vertex() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsVertex::set_space
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Sets the space of this vertex as a fixed NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsVertex::
|
||||
set_space(const NodePath &space) {
|
||||
_space = space;
|
||||
_space_path = string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NurbsVertex::set_space
|
||||
// Access: Public
|
||||
// Description: Sets the space of this vertex as a relative path from
|
||||
// the rel_to node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NurbsVertex::
|
||||
set_space(const string &space) {
|
||||
_space = NodePath();
|
||||
_space_path = space;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -93,7 +108,11 @@ set_space(const NodePath &space) {
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodePath &NurbsVertex::
|
||||
get_space() const {
|
||||
INLINE NodePath NurbsVertex::
|
||||
get_space(const NodePath &rel_to) const {
|
||||
if (_space_path.empty()) {
|
||||
return _space;
|
||||
} else {
|
||||
return rel_to.find(_space_path);
|
||||
}
|
||||
}
|
||||
|
@ -48,11 +48,13 @@ public:
|
||||
INLINE const LVecBase4f &get_vertex() const;
|
||||
|
||||
INLINE void set_space(const NodePath &space);
|
||||
INLINE const NodePath &get_space() const;
|
||||
INLINE void set_space(const string &space);
|
||||
INLINE NodePath get_space(const NodePath &rel_to) const;
|
||||
|
||||
private:
|
||||
LVecBase4f _vertex;
|
||||
NodePath _space;
|
||||
string _space_path;
|
||||
};
|
||||
|
||||
#include "nurbsVertex.I"
|
||||
|
@ -25,7 +25,11 @@
|
||||
INLINE RopeNode::CData::
|
||||
CData() {
|
||||
_curve = new NurbsCurveEvaluator;
|
||||
_render_mode = RopeNode::RM_thread;
|
||||
_uv_mode = RopeNode::UV_none;
|
||||
_uv_scale.set(1.0f, 1.0f);
|
||||
_num_segs = 10;
|
||||
_thickness = 1.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -35,7 +39,12 @@ CData() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RopeNode::CData::
|
||||
CData(const RopeNode::CData ©) :
|
||||
_curve(copy._curve)
|
||||
_curve(copy._curve),
|
||||
_render_mode(copy._render_mode),
|
||||
_uv_mode(copy._uv_mode),
|
||||
_uv_scale(copy._uv_scale),
|
||||
_num_segs(copy._num_segs),
|
||||
_thickness(copy._thickness)
|
||||
{
|
||||
}
|
||||
|
||||
@ -62,6 +71,79 @@ get_curve() const {
|
||||
return cdata->_curve;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_render_mode
|
||||
// Access: Public
|
||||
// Description: Specifies the method used to render the rope. The
|
||||
// simplest is RM_thread, which just draws a one-pixel
|
||||
// line segment.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RopeNode::
|
||||
set_render_mode(RopeNode::RenderMode render_mode) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_render_mode = render_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_render_mode
|
||||
// Access: Public
|
||||
// Description: Returns the method used to render the rope. See
|
||||
// set_render_mode().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RopeNode::RenderMode RopeNode::
|
||||
get_render_mode() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_render_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_uv_mode
|
||||
// Access: Public
|
||||
// Description: Specifies the algorithm to use to generate UV's for
|
||||
// the rope.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RopeNode::
|
||||
set_uv_mode(RopeNode::UVMode uv_mode) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_uv_mode = uv_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_uv_mode
|
||||
// Access: Public
|
||||
// Description: Returns the algorithm to use to generate UV's for the
|
||||
// rope.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE RopeNode::UVMode RopeNode::
|
||||
get_uv_mode() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_uv_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_uv_scale
|
||||
// Access: Public
|
||||
// Description: Specifies an additional scaling factor to apply to
|
||||
// generated UV's for the rope.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RopeNode::
|
||||
set_uv_scale(const LVecBase2f &uv_scale) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_uv_scale = uv_scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_uv_scale
|
||||
// Access: Public
|
||||
// Description: Returns the scaling factor to apply to generated UV's
|
||||
// for the rope.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase2f &RopeNode::
|
||||
get_uv_scale() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_uv_scale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_num_segs
|
||||
// Access: Public
|
||||
@ -87,3 +169,29 @@ get_num_segs() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_num_segs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_thickness
|
||||
// Access: Public
|
||||
// Description: Specifies the thickness of the rope, in pixels or in
|
||||
// spatial units, depending on the render mode. See
|
||||
// set_render_mode().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void RopeNode::
|
||||
set_thickness(float thickness) {
|
||||
nassertv(thickness >= 0);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_thickness = thickness;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_thickness
|
||||
// Access: Public
|
||||
// Description: Returns the thickness of the rope. See
|
||||
// set_thickness().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float RopeNode::
|
||||
get_thickness() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_thickness;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "cullableObject.h"
|
||||
#include "cullHandler.h"
|
||||
#include "geomLinestrip.h"
|
||||
#include "geomTristrip.h"
|
||||
#include "bamWriter.h"
|
||||
#include "bamReader.h"
|
||||
#include "datagram.h"
|
||||
@ -149,35 +150,21 @@ has_cull_callback() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool RopeNode::
|
||||
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
// Create a new linestrip on-the-fly to render the rope.
|
||||
int num_verts = get_num_segs() + 1;
|
||||
if (num_verts >= 2) {
|
||||
PTA_Vertexf verts;
|
||||
PTA_int lengths;
|
||||
|
||||
// Create some geometry on-the-fly to render the rope.
|
||||
if (get_num_segs() > 0) {
|
||||
NurbsCurveEvaluator *curve = get_curve();
|
||||
PT(NurbsCurveResult) result = curve->evaluate(data._node_path.get_node_path());
|
||||
|
||||
int num_segments = result->get_num_segments();
|
||||
if (num_segments > 0) {
|
||||
for (int segment = 0; segment < num_segments; segment++) {
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
float t = (float)i / (float)(num_verts - 1);
|
||||
LPoint3f point;
|
||||
result->eval_segment_point(segment, t, point);
|
||||
verts.push_back(point);
|
||||
}
|
||||
lengths.push_back(num_verts);
|
||||
}
|
||||
if (result->get_num_segments() > 0) {
|
||||
switch (get_render_mode()) {
|
||||
case RM_thread:
|
||||
render_thread(trav, data, result);
|
||||
break;
|
||||
|
||||
PT(Geom) geom = new GeomLinestrip;
|
||||
geom->set_num_prims(num_segments);
|
||||
geom->set_coords(verts);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object);
|
||||
case RM_billboard:
|
||||
render_billboard(trav, data, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,6 +232,192 @@ recompute_internal_bound() {
|
||||
return reset_bound(NodePath(this));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::render_thread
|
||||
// Access: Private
|
||||
// Description: Draws the rope in RM_thread mode. This uses a
|
||||
// GeomLinestrip to draw the rope in the simplest
|
||||
// possible method, generally resulting in a
|
||||
// one-pixel-wide curve.
|
||||
//
|
||||
// In this mode, the thickness parameter represents a
|
||||
// thickness in pixels, and is passed to the linestrip.
|
||||
// However, you should be aware the DirectX does not
|
||||
// support line thickness.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RopeNode::
|
||||
render_thread(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsCurveResult *result) {
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_int lengths;
|
||||
|
||||
int num_verts = get_num_segs() + 1;
|
||||
int num_segments = result->get_num_segments();
|
||||
for (int segment = 0; segment < num_segments; segment++) {
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
float t = (float)i / (float)(num_verts - 1);
|
||||
LPoint3f point;
|
||||
result->eval_segment_point(segment, t, point);
|
||||
verts.push_back(point);
|
||||
uvs.push_back(TexCoordf(result->get_segment_t(segment, t), 0.0f));
|
||||
}
|
||||
lengths.push_back(num_verts);
|
||||
}
|
||||
|
||||
PT(Geom) geom = new GeomLinestrip;
|
||||
geom->set_num_prims(num_segments);
|
||||
geom->set_coords(verts);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::render_billboard
|
||||
// Access: Private
|
||||
// Description: Draws the rope in RM_billboard mode. This draws a
|
||||
// series of triangle strips oriented to be
|
||||
// perpendicular to the camera plane.
|
||||
//
|
||||
// In this mode, thickness is in spatial units, and
|
||||
// determines the with of the triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RopeNode::
|
||||
render_billboard(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsCurveResult *result) {
|
||||
const TransformState *net_transform = data._net_transform;
|
||||
const TransformState *camera_transform = trav->get_camera_transform();
|
||||
|
||||
CPT(TransformState) rel_transform =
|
||||
net_transform->invert_compose(camera_transform);
|
||||
LVector3f camera_vec = LVector3f::forward() * rel_transform->get_mat();
|
||||
|
||||
float thickness = get_thickness();
|
||||
float radius = thickness * 0.5f;
|
||||
UVMode uv_mode = get_uv_mode();
|
||||
LVecBase2f uv_scale = get_uv_scale();
|
||||
|
||||
// We can't just build one tristrip per segment. Instead, we should
|
||||
// build one continuous tristrip for all connected segments, so we
|
||||
// can stitch them together properly at the seams.
|
||||
|
||||
int num_verts = get_num_segs() + 1;
|
||||
int num_segments = result->get_num_segments();
|
||||
|
||||
vector_Vertexf center_verts;
|
||||
vector_int center_lengths;
|
||||
vector_float center_t;
|
||||
|
||||
LPoint3f point;
|
||||
int cur_length = 0;
|
||||
for (int segment = 0; segment < num_segments; segment++) {
|
||||
LPoint3f first_point;
|
||||
result->eval_segment_point(segment, 0.0f, first_point);
|
||||
if (cur_length == 0 || point != first_point) {
|
||||
// If the first point of this segment is different from the last
|
||||
// point of the previous segment, end the tristrip and store the
|
||||
// point.
|
||||
if (cur_length != 0) {
|
||||
center_lengths.push_back(cur_length);
|
||||
}
|
||||
center_verts.push_back(first_point);
|
||||
center_t.push_back(result->get_segment_t(segment, 0.0f));
|
||||
cur_length = 1;
|
||||
}
|
||||
|
||||
// Store all the remaining points in this segment.
|
||||
for (int i = 1; i < num_verts; i++) {
|
||||
float t = (float)i / (float)(num_verts - 1);
|
||||
result->eval_segment_point(segment, t, point);
|
||||
center_verts.push_back(point);
|
||||
center_t.push_back(result->get_segment_t(segment, t));
|
||||
cur_length++;
|
||||
}
|
||||
}
|
||||
if (cur_length != 0) {
|
||||
center_lengths.push_back(cur_length);
|
||||
}
|
||||
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back and convert them into actual tristrips.
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_int lengths;
|
||||
|
||||
int vi = 0;
|
||||
int num_prims = 0;
|
||||
float dist = 0.0f;
|
||||
for (int i = 0; i < (int)center_lengths.size(); i++) {
|
||||
int length = center_lengths[i];
|
||||
for (int j = 0; j < length; j++) {
|
||||
const Vertexf &point = center_verts[vi + j];
|
||||
float t = center_t[vi + j];
|
||||
LVector3f tangent;
|
||||
// Rather than evaluating the curve for the tangent, we derive
|
||||
// it from the neighboring points. This gives us better
|
||||
// behavior at the endpoints, where the tangent might go to
|
||||
// zero.
|
||||
if (j == 0) {
|
||||
tangent = center_verts[vi + j + 1] - point;
|
||||
} else if (j == length - 1) {
|
||||
tangent = point - center_verts[vi + j - 1];
|
||||
} else {
|
||||
tangent = center_verts[vi + j + 1] - center_verts[vi + j - 1];
|
||||
}
|
||||
LVector3f cross = normalize(tangent.cross(camera_vec));
|
||||
cross *= radius;
|
||||
verts.push_back(point + cross);
|
||||
verts.push_back(point - cross);
|
||||
switch (uv_mode) {
|
||||
case UV_none:
|
||||
break;
|
||||
|
||||
case UV_parametric:
|
||||
uvs.push_back(TexCoordf(t * uv_scale[0], uv_scale[1]));
|
||||
uvs.push_back(TexCoordf(t * uv_scale[0], 0.0f));
|
||||
break;
|
||||
|
||||
case UV_distance:
|
||||
if (j != 0) {
|
||||
LVector3f vec = point - center_verts[vi + j - 1];
|
||||
dist += vec.length();
|
||||
}
|
||||
uvs.push_back(TexCoordf(dist * uv_scale[0], thickness * uv_scale[1]));
|
||||
uvs.push_back(TexCoordf(dist * uv_scale[0], 0.0f));
|
||||
break;
|
||||
|
||||
case UV_distance2:
|
||||
if (j != 0) {
|
||||
LVector3f vec = point - center_verts[vi + j - 1];
|
||||
dist += vec.length_squared();
|
||||
}
|
||||
uvs.push_back(TexCoordf(dist * uv_scale[0], thickness * uv_scale[1]));
|
||||
uvs.push_back(TexCoordf(dist * uv_scale[0], 0.0f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
vi += length;
|
||||
lengths.push_back(length * 2);
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (uv_mode != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
@ -53,17 +53,46 @@ public:
|
||||
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
|
||||
|
||||
PUBLISHED:
|
||||
enum RenderMode {
|
||||
RM_thread,
|
||||
RM_billboard
|
||||
};
|
||||
enum UVMode {
|
||||
UV_none,
|
||||
UV_parametric,
|
||||
UV_distance,
|
||||
UV_distance2,
|
||||
};
|
||||
|
||||
INLINE void set_curve(NurbsCurveEvaluator *curve);
|
||||
INLINE NurbsCurveEvaluator *get_curve() const;
|
||||
|
||||
INLINE void set_render_mode(RenderMode render_mode);
|
||||
INLINE RenderMode get_render_mode() const;
|
||||
|
||||
INLINE void set_uv_mode(UVMode uv_mode);
|
||||
INLINE UVMode get_uv_mode() const;
|
||||
|
||||
INLINE void set_uv_scale(const LVecBase2f &uv_scale);
|
||||
INLINE const LVecBase2f &get_uv_scale() const;
|
||||
|
||||
INLINE void set_num_segs(int num_segs);
|
||||
INLINE int get_num_segs() const;
|
||||
|
||||
INLINE void set_thickness(float thickness);
|
||||
INLINE float get_thickness() const;
|
||||
|
||||
BoundingVolume *reset_bound(const NodePath &rel_to);
|
||||
|
||||
protected:
|
||||
virtual BoundingVolume *recompute_internal_bound();
|
||||
|
||||
private:
|
||||
void render_thread(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsCurveResult *result);
|
||||
void render_billboard(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsCurveResult *result);
|
||||
|
||||
private:
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
@ -75,7 +104,11 @@ private:
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
PT(NurbsCurveEvaluator) _curve;
|
||||
RenderMode _render_mode;
|
||||
UVMode _uv_mode;
|
||||
LVecBase2f _uv_scale;
|
||||
int _num_segs;
|
||||
float _thickness;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
|
Loading…
x
Reference in New Issue
Block a user