Browse Source

add per-vertex thickness

David Rose 19 years ago
parent
commit
fd864e2f6d

+ 68 - 2
panda/src/parametrics/ropeNode.I

@@ -36,6 +36,7 @@ CData() {
   _use_vertex_color = false;
   _use_vertex_color = false;
   _num_subdiv = 10;
   _num_subdiv = 10;
   _num_slices = 5;
   _num_slices = 5;
+  _use_vertex_thickness = false;
   _thickness = 1.0f;
   _thickness = 1.0f;
 }
 }
 
 
@@ -58,6 +59,7 @@ CData(const RopeNode::CData &copy) :
   _use_vertex_color(copy._use_vertex_color),
   _use_vertex_color(copy._use_vertex_color),
   _num_subdiv(copy._num_subdiv),
   _num_subdiv(copy._num_subdiv),
   _num_slices(copy._num_slices),
   _num_slices(copy._num_slices),
+  _use_vertex_thickness(copy._use_vertex_thickness),
   _thickness(copy._thickness)
   _thickness(copy._thickness)
 {
 {
 }
 }
@@ -248,8 +250,10 @@ get_tube_up() const {
 //       Access: Published
 //       Access: Published
 //  Description: Sets the "use vertex color" flag.  When this is true,
 //  Description: Sets the "use vertex color" flag.  When this is true,
 //               the R, G, B, A vertex color is assumed to be stored
 //               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
 //               NurbsCurveEvaluator::set_extended_vertex() to set
 //               these values.
 //               these values.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -271,6 +275,21 @@ get_use_vertex_color() const {
   return cdata->_use_vertex_color;
   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
 //     Function: set_num_subdiv
 //       Access: Published
 //       Access: Published
@@ -330,12 +349,59 @@ get_num_slices() const {
   return cdata->_num_slices;
   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
 //     Function: set_thickness
 //       Access: Published
 //       Access: Published
 //  Description: Specifies the thickness of the rope, in pixels or in
 //  Description: Specifies the thickness of the rope, in pixels or in
 //               spatial units, depending on the render mode.  See
 //               spatial units, depending on the render mode.  See
 //               set_render_mode().
 //               set_render_mode().
+//
+//               The thickness may also be specified on a per-vertex
+//               basis.  See set_use_vertex_thickness().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void RopeNode::
 INLINE void RopeNode::
 set_thickness(float thickness) {
 set_thickness(float thickness) {

+ 33 - 5
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
 //               In this mode, the thickness parameter represents a
 //               thickness in pixels, and is passed to the linestrip.
 //               thickness in pixels, and is passed to the linestrip.
 //               However, you should be aware the DirectX does not
 //               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::
 void RopeNode::
 render_thread(CullTraverser *trav, CullTraverserData &data, 
 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_verts = get_num_subdiv() + 1;
   int num_segments = result->get_num_segments();
   int num_segments = result->get_num_segments();
   bool use_vertex_color = get_use_vertex_color();
   bool use_vertex_color = get_use_vertex_color();
+  bool use_vertex_thickness = get_use_vertex_thickness();
 
 
   CurveSegment *curve_segment = NULL;
   CurveSegment *curve_segment = NULL;
   LPoint3f last_point;
   LPoint3f last_point;
@@ -560,7 +562,14 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments,
       vtx._p = point;
       vtx._p = point;
       vtx._t = result->get_segment_t(segment, 0.0f);
       vtx._t = result->get_segment_t(segment, 0.0f);
       if (use_vertex_color) {
       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);
       curve_segment->push_back(vtx);
@@ -574,7 +583,14 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments,
       result->eval_segment_point(segment, t, vtx._p);
       result->eval_segment_point(segment, t, vtx._p);
       vtx._t = result->get_segment_t(segment, t);
       vtx._t = result->get_segment_t(segment, t);
       if (use_vertex_color) {
       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);
       curve_segment->push_back(vtx);
@@ -644,11 +660,13 @@ compute_billboard_vertices(GeomVertexData *vdata,
   GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
   GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
 
 
   float thickness = get_thickness();
   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();
   UVMode uv_mode = get_uv_mode();
   float uv_scale = get_uv_scale();
   float uv_scale = get_uv_scale();
   bool u_dominant = get_uv_direction();
   bool u_dominant = get_uv_direction();
   bool use_vertex_color = get_use_vertex_color();
   bool use_vertex_color = get_use_vertex_color();
+  bool use_vertex_thickness = get_use_vertex_thickness();
 
 
   float dist = 0.0f;
   float dist = 0.0f;
   CurveSegments::const_iterator si;
   CurveSegments::const_iterator si;
@@ -661,6 +679,10 @@ compute_billboard_vertices(GeomVertexData *vdata,
       LVector3f norm = cross(tangent, camera_vec);
       LVector3f norm = cross(tangent, camera_vec);
       norm.normalize();
       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);
       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;
   num_verts_per_slice = num_slices;
 
 
   float thickness = get_thickness();
   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();
   UVMode uv_mode = get_uv_mode();
   float uv_scale = get_uv_scale();
   float uv_scale = get_uv_scale();
   bool u_dominant = get_uv_direction();
   bool u_dominant = get_uv_direction();
   NormalMode normal_mode = get_normal_mode();
   NormalMode normal_mode = get_normal_mode();
   bool use_vertex_color = get_use_vertex_color();
   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
   // 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
   // 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);
       float uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
 
 
       for (int s = 0; s < num_verts_per_slice; ++s) {
       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);
         vertex.add_data3f(segment[j]._p + norm * radius);
 
 
         if (normal_mode == NM_vertex) {
         if (normal_mode == NM_vertex) {

+ 7 - 0
panda/src/parametrics/ropeNode.h

@@ -123,6 +123,7 @@ PUBLISHED:
 
 
   INLINE void set_use_vertex_color(bool flag);
   INLINE void set_use_vertex_color(bool flag);
   INLINE bool get_use_vertex_color() const;
   INLINE bool get_use_vertex_color() const;
+  INLINE static int get_vertex_color_dimension();
 
 
   INLINE void set_num_subdiv(int num_subdiv);
   INLINE void set_num_subdiv(int num_subdiv);
   INLINE int get_num_subdiv() const;
   INLINE int get_num_subdiv() const;
@@ -130,6 +131,10 @@ PUBLISHED:
   INLINE void set_num_slices(int num_slices);
   INLINE void set_num_slices(int num_slices);
   INLINE int get_num_slices() const;
   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 void set_thickness(float thickness);
   INLINE float get_thickness() const;
   INLINE float get_thickness() const;
 
 
@@ -162,6 +167,7 @@ private:
   public:
   public:
     LPoint3f _p;
     LPoint3f _p;
     Colorf _c;
     Colorf _c;
+    float _thickness;
     float _t;
     float _t;
   };
   };
   typedef pvector<CurveVertex> CurveSegment;
   typedef pvector<CurveVertex> CurveSegment;
@@ -213,6 +219,7 @@ private:
     bool _use_vertex_color;
     bool _use_vertex_color;
     int _num_subdiv;
     int _num_subdiv;
     int _num_slices;
     int _num_slices;
+    bool _use_vertex_thickness;
     float _thickness;
     float _thickness;
   };
   };