Panda3D
|
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 ©); 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 ©); 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 ¶ms); 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