Panda3D

ropeNode.h

00001 // Filename: ropeNode.h
00002 // Created by:  drose (04Dec02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef ROPENODE_H
00016 #define ROPENODE_H
00017 
00018 #include "pandabase.h"
00019 #include "nurbsCurveEvaluator.h"
00020 #include "pandaNode.h"
00021 #include "pStatCollector.h"
00022 #include "geomVertexFormat.h"
00023 
00024 class GeomVertexData;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //       Class : RopeNode
00028 // Description : This class draws a visible representation of the
00029 //               NURBS curve stored in its NurbsCurveEvaluator.  It
00030 //               automatically recomputes the curve every frame.
00031 //
00032 //               This is not related to NurbsCurve, CubicCurveseg or
00033 //               any of the ParametricCurve-derived objects in this
00034 //               module.  It is a completely parallel implementation
00035 //               of NURBS curves, and will probably eventually replace
00036 //               the whole ParametricCurve class hierarchy.
00037 ////////////////////////////////////////////////////////////////////
00038 class EXPCL_PANDA_PARAMETRICS RopeNode : public PandaNode {
00039 PUBLISHED:
00040   RopeNode(const string &name);
00041 
00042 protected:
00043   RopeNode(const RopeNode &copy);
00044 public:
00045   virtual void output(ostream &out) const;
00046   virtual void write(ostream &out, int indent_level = 0) const;
00047 
00048   virtual PandaNode *make_copy() const;
00049 
00050   virtual bool safe_to_transform() const;
00051   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
00052   virtual bool is_renderable() const;
00053 
00054 PUBLISHED:
00055   enum RenderMode {
00056     // Render the rope as a one-pixel thread using a linestrip.
00057     RM_thread,
00058 
00059     // Render the rope as a triangle strip oriented to be
00060     // perpendicular to the tube_up vector.
00061     RM_tape,
00062 
00063     // Render the rope as a triangle strip oriented to be
00064     // perpendicular to the view vector.
00065     RM_billboard,
00066 
00067     // Render the rope as a hollow tube extruded along its length.
00068     RM_tube
00069   };
00070 
00071   enum UVMode {
00072     // Don't generate UV's along the curve.
00073     UV_none,
00074 
00075     // Generate UV's based on the parametric coordinates along the
00076     // curve.
00077     UV_parametric,
00078 
00079     // Generate UV's in proportion to spatial distance along the
00080     // curve, by using the distance function to compute the length of
00081     // each segment.
00082     UV_distance,
00083 
00084     // As above, but don't bother to take the square root of each
00085     // segment.  The distance is then in proportion to the
00086     // sum-of-squares of the segments along the rope.  If the segments
00087     // are similar in length, this approximates the proportion of
00088     // UV_distance while avoiding hundreds of square root operations.
00089     UV_distance2,
00090   };
00091 
00092   enum NormalMode {
00093     // Don't generate normals.
00094     NM_none,
00095 
00096     // Generate vertex (smooth-shaded) normals.
00097     NM_vertex
00098   };
00099 
00100   INLINE void set_curve(NurbsCurveEvaluator *curve);
00101   INLINE NurbsCurveEvaluator *get_curve() const;
00102 
00103   INLINE void set_render_mode(RenderMode render_mode);
00104   INLINE RenderMode get_render_mode() const;
00105 
00106   INLINE void set_uv_mode(UVMode uv_mode);
00107   INLINE UVMode get_uv_mode() const;
00108 
00109   INLINE void set_uv_direction(bool u_dominant);
00110   INLINE bool get_uv_direction() const;
00111 
00112   INLINE void set_uv_scale(float scale);
00113   INLINE float get_uv_scale() const;
00114 
00115   INLINE void set_normal_mode(NormalMode normal_mode);
00116   INLINE NormalMode get_normal_mode() const;
00117 
00118   INLINE void set_tube_up(const LVector3f &tube_up);
00119   INLINE const LVector3f &get_tube_up() const;
00120 
00121   INLINE void set_use_vertex_color(bool flag);
00122   INLINE bool get_use_vertex_color() const;
00123   INLINE static int get_vertex_color_dimension();
00124 
00125   INLINE void set_num_subdiv(int num_subdiv);
00126   INLINE int get_num_subdiv() const;
00127 
00128   INLINE void set_num_slices(int num_slices);
00129   INLINE int get_num_slices() const;
00130 
00131   INLINE void set_use_vertex_thickness(bool flag);
00132   INLINE bool get_use_vertex_thickness() const;
00133   INLINE static int get_vertex_thickness_dimension();
00134 
00135   INLINE void set_thickness(float thickness);
00136   INLINE float get_thickness() const;
00137 
00138   INLINE void set_matrix(const LMatrix4f &matrix);
00139   INLINE void clear_matrix();
00140   INLINE bool has_matrix() const;
00141   INLINE const LMatrix4f &get_matrix() const;
00142 
00143   void reset_bound(const NodePath &rel_to);
00144 
00145 protected:
00146   virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
00147                                        int &internal_vertices,
00148                                        int pipeline_stage,
00149                                        Thread *current_thread) const;
00150 
00151 private:
00152   CPT(GeomVertexFormat) get_format(bool support_normals) const;
00153 
00154   PT(BoundingVolume) do_recompute_bounds(const NodePath &rel_to,
00155                                          int pipeline_stage, 
00156                                          Thread *current_thread) const;
00157   void render_thread(CullTraverser *trav, CullTraverserData &data, 
00158                      NurbsCurveResult *result) const;
00159   void render_tape(CullTraverser *trav, CullTraverserData &data, 
00160                    NurbsCurveResult *result) const;
00161   void render_billboard(CullTraverser *trav, CullTraverserData &data, 
00162                         NurbsCurveResult *result) const;
00163   void render_tube(CullTraverser *trav, CullTraverserData &data, 
00164                    NurbsCurveResult *result) const;
00165 
00166   class CurveVertex {
00167   public:
00168     LPoint3f _p;
00169     Colorf _c;
00170     float _thickness;
00171     float _t;
00172   };
00173   typedef pvector<CurveVertex> CurveSegment;
00174   typedef pvector<CurveSegment> CurveSegments;
00175 
00176   void get_connected_segments(CurveSegments &curve_segments,
00177                               const NurbsCurveResult *result) const;
00178 
00179   void compute_thread_vertices(GeomVertexData *vdata,
00180                                const CurveSegments &curve_segments) const;
00181   void compute_billboard_vertices(GeomVertexData *vdata,
00182                                   const LVector3f &camera_vec,
00183                                   const CurveSegments &curve_segments,
00184                                   NurbsCurveResult *result) const;
00185   void compute_tube_vertices(GeomVertexData *vdata,
00186                              int &num_verts_per_slice,
00187                              const CurveSegments &curve_segments,
00188                              NurbsCurveResult *result) const;
00189 
00190   static void compute_tangent(LVector3f &tangent, const CurveSegment &segment,
00191                               size_t j, NurbsCurveResult *result);
00192   static float compute_uv_t(float &dist, const UVMode &uv_mode,
00193                             float uv_scale, const CurveSegment &segment,
00194                             size_t j);
00195 
00196 
00197 private:
00198   // This is the data that must be cycled between pipeline stages.
00199   class EXPCL_PANDA_PARAMETRICS CData : public CycleData {
00200   public:
00201     INLINE CData();
00202     INLINE CData(const CData &copy);
00203     virtual CycleData *make_copy() const;
00204     virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00205     virtual void fillin(DatagramIterator &scan, BamReader *manager);
00206     virtual TypeHandle get_parent_type() const {
00207       return RopeNode::get_class_type();
00208     }
00209 
00210     PT(NurbsCurveEvaluator) _curve;
00211     RenderMode _render_mode;
00212     UVMode _uv_mode;
00213     bool _u_dominant;
00214     float _uv_scale;
00215     NormalMode _normal_mode;
00216     LVector3f _tube_up;
00217     LMatrix4f _matrix;
00218     bool _has_matrix;
00219     bool _use_vertex_color;
00220     int _num_subdiv;
00221     int _num_slices;
00222     bool _use_vertex_thickness;
00223     float _thickness;
00224   };
00225 
00226   PipelineCycler<CData> _cycler;
00227   typedef CycleDataReader<CData> CDReader;
00228   typedef CycleDataWriter<CData> CDWriter;
00229 
00230   static PStatCollector _rope_node_pcollector;
00231 
00232 public:
00233   static void register_with_read_factory();
00234   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00235 
00236 protected:
00237   static TypedWritable *make_from_bam(const FactoryParams &params);
00238   void fillin(DatagramIterator &scan, BamReader *manager);
00239 
00240 public:
00241   static TypeHandle get_class_type() {
00242     return _type_handle;
00243   }
00244   static void init_type() {
00245     PandaNode::init_type();
00246     register_type(_type_handle, "RopeNode",
00247                   PandaNode::get_class_type());
00248   }
00249   virtual TypeHandle get_type() const {
00250     return get_class_type();
00251   }
00252   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00253 
00254 private:
00255   static TypeHandle _type_handle;
00256 };
00257 
00258 #include "ropeNode.I"
00259 
00260 #endif
 All Classes Functions Variables Enumerations