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(PN_stdfloat scale); 00113 INLINE PN_stdfloat 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 LVector3 &tube_up); 00119 INLINE const LVector3 &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(PN_stdfloat thickness); 00136 INLINE PN_stdfloat get_thickness() const; 00137 00138 INLINE void set_matrix(const LMatrix4 &matrix); 00139 INLINE void clear_matrix(); 00140 INLINE bool has_matrix() const; 00141 INLINE const LMatrix4 &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 LPoint3 _p; 00169 UnalignedLVecBase4 _c; 00170 PN_stdfloat _thickness; 00171 PN_stdfloat _t; 00172 }; 00173 typedef pvector<CurveVertex> CurveSegment; 00174 typedef pvector<CurveSegment> CurveSegments; 00175 00176 int get_connected_segments(CurveSegments &curve_segments, 00177 const NurbsCurveResult *result) const; 00178 00179 void compute_thread_vertices(GeomVertexData *vdata, 00180 const CurveSegments &curve_segments, 00181 int num_curve_verts) const; 00182 void compute_billboard_vertices(GeomVertexData *vdata, 00183 const LVector3 &camera_vec, 00184 const CurveSegments &curve_segments, 00185 int num_curve_verts, 00186 NurbsCurveResult *result) const; 00187 void compute_tube_vertices(GeomVertexData *vdata, 00188 int &num_verts_per_slice, 00189 const CurveSegments &curve_segments, 00190 int num_curve_verts, 00191 NurbsCurveResult *result) const; 00192 00193 static void compute_tangent(LVector3 &tangent, const CurveSegment &segment, 00194 size_t j, NurbsCurveResult *result); 00195 static PN_stdfloat compute_uv_t(PN_stdfloat &dist, const UVMode &uv_mode, 00196 PN_stdfloat uv_scale, const CurveSegment &segment, 00197 size_t j); 00198 00199 00200 private: 00201 // This is the data that must be cycled between pipeline stages. 00202 class EXPCL_PANDA_PARAMETRICS CData : public CycleData { 00203 public: 00204 INLINE CData(); 00205 INLINE CData(const CData ©); 00206 virtual CycleData *make_copy() const; 00207 virtual void write_datagram(BamWriter *manager, Datagram &dg) const; 00208 virtual void fillin(DatagramIterator &scan, BamReader *manager); 00209 virtual TypeHandle get_parent_type() const { 00210 return RopeNode::get_class_type(); 00211 } 00212 00213 PT(NurbsCurveEvaluator) _curve; 00214 RenderMode _render_mode; 00215 UVMode _uv_mode; 00216 bool _u_dominant; 00217 PN_stdfloat _uv_scale; 00218 NormalMode _normal_mode; 00219 LVector3 _tube_up; 00220 LMatrix4 _matrix; 00221 bool _has_matrix; 00222 bool _use_vertex_color; 00223 int _num_subdiv; 00224 int _num_slices; 00225 bool _use_vertex_thickness; 00226 PN_stdfloat _thickness; 00227 }; 00228 00229 PipelineCycler<CData> _cycler; 00230 typedef CycleDataReader<CData> CDReader; 00231 typedef CycleDataWriter<CData> CDWriter; 00232 00233 static PStatCollector _rope_node_pcollector; 00234 00235 public: 00236 static void register_with_read_factory(); 00237 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00238 00239 protected: 00240 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00241 void fillin(DatagramIterator &scan, BamReader *manager); 00242 00243 public: 00244 static TypeHandle get_class_type() { 00245 return _type_handle; 00246 } 00247 static void init_type() { 00248 PandaNode::init_type(); 00249 register_type(_type_handle, "RopeNode", 00250 PandaNode::get_class_type()); 00251 } 00252 virtual TypeHandle get_type() const { 00253 return get_class_type(); 00254 } 00255 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00256 00257 private: 00258 static TypeHandle _type_handle; 00259 }; 00260 00261 #include "ropeNode.I" 00262 00263 #endif