From fd864e2f6d647e40b09f7afef5146a0f8ae7e864 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 23 Jan 2007 18:42:38 +0000 Subject: [PATCH] add per-vertex thickness --- panda/src/parametrics/ropeNode.I | 70 +++++++++++++++++++++++++++++- panda/src/parametrics/ropeNode.cxx | 38 +++++++++++++--- panda/src/parametrics/ropeNode.h | 7 +++ 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/panda/src/parametrics/ropeNode.I b/panda/src/parametrics/ropeNode.I index 737b92be6c..e675c631ec 100644 --- a/panda/src/parametrics/ropeNode.I +++ b/panda/src/parametrics/ropeNode.I @@ -36,6 +36,7 @@ CData() { _use_vertex_color = false; _num_subdiv = 10; _num_slices = 5; + _use_vertex_thickness = false; _thickness = 1.0f; } @@ -58,6 +59,7 @@ CData(const RopeNode::CData ©) : _use_vertex_color(copy._use_vertex_color), _num_subdiv(copy._num_subdiv), _num_slices(copy._num_slices), + _use_vertex_thickness(copy._use_vertex_thickness), _thickness(copy._thickness) { } @@ -248,8 +250,10 @@ get_tube_up() const { // Access: Published // Description: Sets the "use vertex color" flag. When this is true, // the R, G, B, A vertex color is assumed to be stored -// as the dimensions 0, 1, 2, 3, respectively, of the -// extended vertex values. Use +// as the dimensions n + 0, n + 1, n + 2, n + 3, +// respectively, of the extended vertex values, where n +// is the value returned by +// get_vertex_color_dimension(). Use // NurbsCurveEvaluator::set_extended_vertex() to set // these values. //////////////////////////////////////////////////////////////////// @@ -271,6 +275,21 @@ get_use_vertex_color() const { return cdata->_use_vertex_color; } +//////////////////////////////////////////////////////////////////// +// Function: get_vertex_color_dimension +// Access: Published, Static +// Description: Returns the numeric extended dimension in which the +// color components should be found. See +// NurbsCurveEvaluator::set_extended_vertex(). +// +// The color components will be expected at (n, n + 1, n +// + 2, n + 3). +//////////////////////////////////////////////////////////////////// +INLINE int RopeNode:: +get_vertex_color_dimension() { + return 0; +} + //////////////////////////////////////////////////////////////////// // Function: set_num_subdiv // Access: Published @@ -330,12 +349,59 @@ get_num_slices() const { return cdata->_num_slices; } +//////////////////////////////////////////////////////////////////// +// Function: set_use_vertex_thickness +// Access: Published +// Description: Sets the "use vertex thickness" flag. When this is true, +// the vertex thickness is assumed to be stored as the +// dimension get_vertex_thickness_dimension(), of the +// extended vertex values. Use +// NurbsCurveEvaluator::set_extended_vertex() to set +// these values. +// +// In this mode, the overall thickness is also applied +// as a scale to the vertex thickness. Not all render +// modes support vertex thickness. +//////////////////////////////////////////////////////////////////// +INLINE void RopeNode:: +set_use_vertex_thickness(bool flag) { + CDWriter cdata(_cycler); + cdata->_use_vertex_thickness = flag; +} + +//////////////////////////////////////////////////////////////////// +// Function: get_use_vertex_thickness +// Access: Published +// Description: Returns the "use vertex thickness" flag. See +// set_use_vertex_thickness(). +//////////////////////////////////////////////////////////////////// +INLINE bool RopeNode:: +get_use_vertex_thickness() const { + CDReader cdata(_cycler); + return cdata->_use_vertex_thickness; +} + +//////////////////////////////////////////////////////////////////// +// Function: get_vertex_thickness_dimension +// Access: Published, Static +// Description: Returns the numeric extended dimension in which the +// thickness component should be found. See +// NurbsCurveEvaluator::set_extended_vertex(). +//////////////////////////////////////////////////////////////////// +INLINE int RopeNode:: +get_vertex_thickness_dimension() { + return 4; +} + //////////////////////////////////////////////////////////////////// // Function: set_thickness // Access: Published // Description: Specifies the thickness of the rope, in pixels or in // spatial units, depending on the render mode. See // set_render_mode(). +// +// The thickness may also be specified on a per-vertex +// basis. See set_use_vertex_thickness(). //////////////////////////////////////////////////////////////////// INLINE void RopeNode:: set_thickness(float thickness) { diff --git a/panda/src/parametrics/ropeNode.cxx b/panda/src/parametrics/ropeNode.cxx index 28bd316659..82c13b4c5f 100644 --- a/panda/src/parametrics/ropeNode.cxx +++ b/panda/src/parametrics/ropeNode.cxx @@ -326,7 +326,8 @@ do_recompute_bounds(const NodePath &rel_to, int pipeline_stage, // 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. +// support line thickness. This mode does not support +// per-vertex thickness. //////////////////////////////////////////////////////////////////// void RopeNode:: render_thread(CullTraverser *trav, CullTraverserData &data, @@ -540,6 +541,7 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments, int num_verts = get_num_subdiv() + 1; int num_segments = result->get_num_segments(); bool use_vertex_color = get_use_vertex_color(); + bool use_vertex_thickness = get_use_vertex_thickness(); CurveSegment *curve_segment = NULL; LPoint3f last_point; @@ -560,7 +562,14 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments, vtx._p = point; vtx._t = result->get_segment_t(segment, 0.0f); if (use_vertex_color) { - result->eval_segment_extended_points(segment, 0.0f, 0, &vtx._c[0], 4); + result->eval_segment_extended_points(segment, 0.0f, + get_vertex_color_dimension(), + &vtx._c[0], 4); + } + if (use_vertex_thickness) { + vtx._thickness = + result->eval_segment_extended_point(segment, 0.0f, + get_vertex_thickness_dimension()); } curve_segment->push_back(vtx); @@ -574,7 +583,14 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments, result->eval_segment_point(segment, t, vtx._p); vtx._t = result->get_segment_t(segment, t); if (use_vertex_color) { - result->eval_segment_extended_points(segment, t, 0, &vtx._c[0], 4); + result->eval_segment_extended_points(segment, t, + get_vertex_color_dimension(), + &vtx._c[0], 4); + } + if (use_vertex_thickness) { + vtx._thickness = + result->eval_segment_extended_point(segment, t, + get_vertex_thickness_dimension()); } curve_segment->push_back(vtx); @@ -644,11 +660,13 @@ compute_billboard_vertices(GeomVertexData *vdata, GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); float thickness = get_thickness(); - float radius = thickness * 0.5f; + float overall_radius = thickness * 0.5f; + float radius = overall_radius; UVMode uv_mode = get_uv_mode(); float uv_scale = get_uv_scale(); bool u_dominant = get_uv_direction(); bool use_vertex_color = get_use_vertex_color(); + bool use_vertex_thickness = get_use_vertex_thickness(); float dist = 0.0f; CurveSegments::const_iterator si; @@ -661,6 +679,10 @@ compute_billboard_vertices(GeomVertexData *vdata, LVector3f norm = cross(tangent, camera_vec); norm.normalize(); + if (use_vertex_thickness) { + radius = overall_radius * segment[j]._thickness; + } + vertex.add_data3f(segment[j]._p + norm * radius); vertex.add_data3f(segment[j]._p - norm * radius); @@ -705,12 +727,14 @@ compute_tube_vertices(GeomVertexData *vdata, num_verts_per_slice = num_slices; float thickness = get_thickness(); - float radius = thickness * 0.5f; + float overall_radius = thickness * 0.5f; + float radius = overall_radius; UVMode uv_mode = get_uv_mode(); float uv_scale = get_uv_scale(); bool u_dominant = get_uv_direction(); NormalMode normal_mode = get_normal_mode(); bool use_vertex_color = get_use_vertex_color(); + bool use_vertex_thickness = get_use_vertex_thickness(); // If we are generating UV's, we will need to duplicate the vertices // along the seam so that the UV's go through the whole range of @@ -739,6 +763,10 @@ compute_tube_vertices(GeomVertexData *vdata, float uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j); for (int s = 0; s < num_verts_per_slice; ++s) { + if (use_vertex_thickness) { + radius = overall_radius * segment[j]._thickness; + } + vertex.add_data3f(segment[j]._p + norm * radius); if (normal_mode == NM_vertex) { diff --git a/panda/src/parametrics/ropeNode.h b/panda/src/parametrics/ropeNode.h index 8d1bca5a0d..33fa4c1a8f 100644 --- a/panda/src/parametrics/ropeNode.h +++ b/panda/src/parametrics/ropeNode.h @@ -123,6 +123,7 @@ PUBLISHED: INLINE void set_use_vertex_color(bool flag); INLINE bool get_use_vertex_color() const; + INLINE static int get_vertex_color_dimension(); INLINE void set_num_subdiv(int num_subdiv); INLINE int get_num_subdiv() const; @@ -130,6 +131,10 @@ PUBLISHED: INLINE void set_num_slices(int num_slices); INLINE int get_num_slices() const; + INLINE void set_use_vertex_thickness(bool flag); + INLINE bool get_use_vertex_thickness() const; + INLINE static int get_vertex_thickness_dimension(); + INLINE void set_thickness(float thickness); INLINE float get_thickness() const; @@ -162,6 +167,7 @@ private: public: LPoint3f _p; Colorf _c; + float _thickness; float _t; }; typedef pvector CurveSegment; @@ -213,6 +219,7 @@ private: bool _use_vertex_color; int _num_subdiv; int _num_slices; + bool _use_vertex_thickness; float _thickness; };