42   return new CData(*
this);
    49 void RopeNode::CData::
    60 void RopeNode::CData::
    70 RopeNode(
const std::string &name) :
   132     if (curve != 
nullptr) {
   135         result = curve->evaluate(data.get_node_path(), 
get_matrix());
   137         result = curve->evaluate(data.get_node_path());
   140       if (result->get_num_segments() > 0) {
   143           render_thread(trav, data, result);
   147           render_tape(trav, data, result);
   151           render_billboard(trav, data, result);
   155           render_tube(trav, data, result);
   180 output(std::ostream &out)
 const {
   181   PandaNode::output(out);
   183   if (curve != 
nullptr) {
   184     out << 
" " << *curve;
   186     out << 
" (no curve)";
   194 write(std::ostream &out, 
int indent_level)
 const {
   195   PandaNode::write(out, indent_level);
   206   Thread *current_thread = Thread::get_current_thread();
   208   do_recompute_bounds(rel_to, pipeline_stage, current_thread);
   209   mark_internal_bounds_stale(current_thread);
   219                         int &internal_vertices,
   221                         Thread *current_thread)
 const {
   226   internal_bounds = bounds;
   227   internal_vertices = 0;  
   235 get_format(
bool support_normals)
 const {
   237     (InternalName::get_vertex(), 3, Geom::NT_stdfloat,
   240   if (support_normals && get_normal_mode() == NM_vertex) {
   241     array_format->add_column
   242       (InternalName::get_normal(), 3, Geom::NT_stdfloat,
   245   if (get_use_vertex_color()) {
   246     array_format->add_column
   247       (InternalName::get_color(), 1, Geom::NT_packed_dabc,
   250   if (get_uv_mode() != UV_none) {
   251     array_format->add_column
   252       (InternalName::get_texcoord(), 2, Geom::NT_stdfloat,
   256   return GeomVertexFormat::register_format(array_format);
   263 do_recompute_bounds(
const NodePath &rel_to, 
int pipeline_stage,
   264                     Thread *current_thread)
 const {
   273   if (curve != 
nullptr) {
   275     get_curve()->get_vertices(verts, rel_to);
   280       NurbsCurveEvaluator::Vert3Array::iterator vi;
   281       for (vi = verts.begin(); vi != verts.end(); ++vi) {
   282         (*vi) = LPoint3(*vi) * mat;
   287     DCAST_INTO_R(gbv, bound, bound);
   288     gbv->
around(&verts[0], &verts[0] + verts.size());
   306   CurveSegments curve_segments;
   307   int num_curve_verts = get_connected_segments(curve_segments, result);
   312     (
"rope", get_format(
false), Geom::UH_stream);
   313   compute_thread_vertices(vdata, curve_segments, num_curve_verts);
   318   lines->reserve_num_vertices((num_curve_verts - 1) * 2);
   320   for (
int vi = 0; vi < num_curve_verts - 1; ++vi) {
   321     lines->add_vertex(vi);
   322     lines->add_vertex(vi + 1);
   323     lines->close_primitive();
   327   geom->add_primitive(lines);
   330   CPT(
RenderState) state = data._state->add_attrib(thick);
   332     state = state->add_attrib(ColorAttrib::make_vertex());
   337                        data.get_internal_transform(trav));
   351   CurveSegments curve_segments;
   352   int num_curve_verts = get_connected_segments(curve_segments, result);
   357     (
"rope", get_format(
false), Geom::UH_stream);
   360                              curve_segments, num_curve_verts, result);
   365   CurveSegments::const_iterator si;
   366   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   367     const CurveSegment &segment = (*si);
   369     strip->add_next_vertices(segment.size() * 2);
   370     strip->close_primitive();
   374   geom->add_primitive(strip);
   378     state = state->add_attrib(ColorAttrib::make_vertex());
   383                        data.get_internal_transform(trav));
   397   const TransformState *net_transform = data.get_net_transform(trav);
   401     net_transform->invert_compose(camera_transform);
   402   LVector3 camera_vec = LVector3::forward() * rel_transform->
get_mat();
   404   CurveSegments curve_segments;
   405   int num_curve_verts = get_connected_segments(curve_segments, result);
   410     (
"rope", get_format(
false), Geom::UH_stream);
   412   compute_billboard_vertices(vdata, camera_vec,
   413                              curve_segments, num_curve_verts, result);
   418   CurveSegments::const_iterator si;
   419   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   420     const CurveSegment &segment = (*si);
   422     strip->add_next_vertices(segment.size() * 2);
   423     strip->close_primitive();
   427   geom->add_primitive(strip);
   431     state = state->add_attrib(ColorAttrib::make_vertex());
   436                        data.get_internal_transform(trav));
   450   CurveSegments curve_segments;
   451   int num_curve_verts = get_connected_segments(curve_segments, result);
   457   int num_verts_per_slice;
   460     (
"rope", get_format(
true), Geom::UH_stream);
   462   compute_tube_vertices(vdata, num_verts_per_slice,
   463                         curve_segments, num_curve_verts, result);
   470   CurveSegments::const_iterator si;
   471   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   472     const CurveSegment &segment = (*si);
   474     for (
int s = 0; s < num_slices; ++s) {
   475       int s1 = (s + 1) % num_verts_per_slice;
   477       for (
size_t j = 0; j < segment.size(); ++j) {
   478         strip->add_vertex((vi + j) * num_verts_per_slice + s);
   479         strip->add_vertex((vi + j) * num_verts_per_slice + s1);
   482       strip->close_primitive();
   484     vi += (int)segment.size();
   488   geom->add_primitive(strip);
   492     state = state->add_attrib(ColorAttrib::make_vertex());
   497                        data.get_internal_transform(trav));
   515   int num_curve_verts = 0;
   522   CurveSegment *curve_segment = 
nullptr;
   525   for (
int segment = 0; segment < num_segments; ++segment) {
   529     if (curve_segment == 
nullptr ||
   530         !point.almost_equal(last_point)) {
   534       curve_segments.push_back(CurveSegment());
   535       curve_segment = &curve_segments.back();
   540       if (use_vertex_color) {
   545       if (use_vertex_thickness) {
   551       curve_segment->push_back(vtx);
   556     for (
int i = 1; i < num_verts; ++i) {
   557       PN_stdfloat t = (PN_stdfloat)i / (PN_stdfloat)(num_verts - 1);
   562       if (use_vertex_color) {
   567       if (use_vertex_thickness) {
   573       curve_segment->push_back(vtx);
   580   return num_curve_verts;
   590                         int num_curve_verts)
 const {
   602   PN_stdfloat dist = 0.0f;
   603   CurveSegments::const_iterator si;
   604   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   605     const CurveSegment &segment = (*si);
   606     for (
size_t j = 0; j < segment.size(); ++j) {
   607       vertex.add_data3(segment[j]._p);
   609       if (use_vertex_color) {
   610         color.add_data4(segment[j]._c);
   613       PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
   615       if (uv_mode != UV_none) {
   617           texcoord.add_data2(uv_t, 0.0f);
   619           texcoord.add_data2(0.0f, uv_t);
   634                            const LVector3 &camera_vec,
   638   int expected_num_verts = num_curve_verts * 2;
   646   PN_stdfloat overall_radius = thickness * 0.5f;
   647   PN_stdfloat radius = overall_radius;
   654   PN_stdfloat dist = 0.0f;
   655   CurveSegments::const_iterator si;
   656   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   657     const CurveSegment &segment = (*si);
   658     for (
size_t j = 0; j < segment.size(); ++j) {
   660       compute_tangent(tangent, segment, j, result);
   662       LVector3 norm = cross(tangent, camera_vec);
   665       if (use_vertex_thickness) {
   666         radius = overall_radius * segment[j]._thickness;
   669       vertex.add_data3(segment[j]._p + norm * radius);
   670       vertex.add_data3(segment[j]._p - norm * radius);
   672       if (use_vertex_color) {
   673         color.add_data4(segment[j]._c);
   674         color.add_data4(segment[j]._c);
   677       PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
   679       if (uv_mode != UV_none) {
   681           texcoord.add_data2(uv_t, 1.0f);
   682           texcoord.add_data2(uv_t, 0.0f);
   684           texcoord.add_data2(1.0f, uv_t);
   685           texcoord.add_data2(0.0f, uv_t);
   700                       int &num_verts_per_slice,
   705   num_verts_per_slice = num_slices;
   708   PN_stdfloat overall_radius = thickness * 0.5f;
   709   PN_stdfloat radius = overall_radius;
   720   if (uv_mode != UV_none) {
   721     ++num_verts_per_slice;
   724   int expected_num_verts = num_curve_verts * num_verts_per_slice;
   734   PN_stdfloat dist = 0.0f;
   735   CurveSegments::const_iterator si;
   736   for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
   737     const CurveSegment &segment = (*si);
   738     for (
size_t j = 0; j < segment.size(); ++j) {
   740       compute_tangent(tangent, segment, j, result);
   742       LVector3 norm = cross(tangent, up);
   746       if (IS_NEARLY_ZERO(norm.length_squared())) {
   748         if (IS_NEARLY_ZERO(tangent.get_y()) && IS_NEARLY_ZERO(tangent.get_z())) {
   750           norm = cross(tangent, LVector3(0, 1, 0));
   752           norm = cross(tangent, LVector3(1, 0, 0));
   757       up = cross(norm, tangent);
   759       LMatrix3 rotate = LMatrix3::rotate_mat(360.0f / (PN_stdfloat)num_slices,
   762       PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
   764       for (
int s = 0; s < num_verts_per_slice; ++s) {
   765         if (use_vertex_thickness) {
   766           radius = overall_radius * segment[j]._thickness;
   769         vertex.add_data3(segment[j]._p + norm * radius);
   771         if (normal_mode == NM_vertex) {
   772           normal.add_data3(norm);
   775         if (use_vertex_color) {
   776           color.add_data4(segment[j]._c);
   779         norm = norm * rotate;
   781         if (uv_mode != UV_none) {
   782           PN_stdfloat uv_s = (PN_stdfloat)s / (PN_stdfloat)num_slices;
   784             texcoord.add_data2(uv_t, uv_s);
   786             texcoord.add_data2(uv_s, uv_t);
   819     tangent = segment[j + 1]._p - segment[j]._p;
   820   } 
else if (j == segment.size() - 1) {
   821     tangent = segment[j]._p - segment[j - 1]._p;
   823     tangent = segment[j + 1]._p - segment[j - 1]._p;
   828   if (IS_NEARLY_ZERO(tangent.length_squared())) {
   829     tangent.set(0, 0, 1);
   838 PN_stdfloat RopeNode::
   839 compute_uv_t(PN_stdfloat &dist, 
const RopeNode::UVMode &uv_mode,
   847     return segment[j]._t * uv_scale;
   851       LVector3 vec = segment[j]._p - segment[j - 1]._p;
   852       dist += vec.length();
   854     return dist * uv_scale;
   858       LVector3 vec = segment[j]._p - segment[j - 1]._p;
   859       dist += vec.length_squared();
   861     return dist * uv_scale;
   897   node->fillin(scan, manager);
   908   PandaNode::fillin(scan, manager);
 PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A basic node of the scene graph or data graph.
 
void eval_segment_extended_points(int segment, PN_stdfloat t, int d, PN_stdfloat result[], int num_values) const
Simultaneously performs eval_extended_point on a contiguous sequence of dimensions.
 
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
 
CullHandler * get_cull_handler() const
Returns the object that will receive the culled Geoms.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
const TransformState * get_camera_transform() const
Returns the position of the camera relative to the starting node.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is the base class for a number of render attributes (other than transform) that may be set on sc...
 
PN_stdfloat eval_segment_extended_point(int segment, PN_stdfloat t, int d) const
Evaluates the curve in n-dimensional space according to the extended vertices associated with the cur...
 
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
 
CPT(GeomVertexFormat) RopeNode
Returns the appropriate GeomVertexFormat for rendering, according to the user-specified requirements.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
 
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
 
get_thickness
Returns the thickness of the rope.
 
get_render_mode
Returns the method used to render the rope.
 
This defines a bounding sphere, consisting of a center and a radius.
 
A single page of data maintained by a PipelineCycler.
 
This class is an abstraction for evaluating NURBS curves.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Base class for objects that can be written to and read from Bam files.
 
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
 
void skip_pointer(DatagramIterator &scan)
Reads and discards a pointer value from the Bam file.
 
This collects together the pieces of data that are accumulated for each node while walking the scene ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This class draws a visible representation of the NURBS curve stored in its NurbsCurveEvaluator.
 
Defines a series of triangle strips.
 
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
 
get_vertex_color_dimension
Returns the numeric extended dimension in which the color components should be found.
 
get_pipeline_stage
Returns the Pipeline stage number associated with this thread.
 
get_num_subdiv
Returns the number of subdivisions per cubic segment to draw.
 
void eval_segment_point(int segment, PN_stdfloat t, LVecBase3 &point) const
Evaluates the point on the curve corresponding to the indicated value in parametric time within the i...
 
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of Node by calling the xform()...
 
get_uv_mode
Returns the algorithm to use to generate UV's for the rope.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PN_stdfloat get_segment_t(int segment, PN_stdfloat t) const
Accepts a t value in the range [0, 1], and assumed to be relative to the indicated segment (as in eva...
 
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A lightweight class that represents a single element that may be timed and/or counted via stats.
 
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
 
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
 
get_matrix
Returns the optional matrix which is used to transform each control vertex after it has been transfor...
 
get_normal_mode
Returns the kind of normals to generate for the rope.
 
has_matrix
Returns true if the node has a matrix set, false otherwise.
 
get_vertex_thickness_dimension
Returns the numeric extended dimension in which the thickness component should be found.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
The smallest atom of cull.
 
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
 
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
 
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
 
A container for geometry primitives.
 
An instance of this class is passed to the Factory when requesting it to do its business and construc...
 
get_use_vertex_thickness
Returns the "use vertex thickness" flag.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
 
bool set_num_rows(int n)
Sets the length of the array to n rows in all of the various arrays (presumably by adding rows).
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
int get_num_rows() const
Returns the number of rows stored within all the arrays.
 
get_curve
Returns the curve represented by the RopeNode.
 
int get_num_segments() const
Returns the number of piecewise continuous segments within the curve.
 
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
 
get_num_slices
Returns the number of radial subdivisions to make if RenderMode is RM_tube.
 
Defines a series of disconnected line segments.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
static void register_with_read_factory()
Tells the BamReader how to create objects of type RopeNode.
 
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_uv_direction
Returns true if the rope runs down the U coordinate of the texture, or false if it runs down the V co...
 
void reset_bound(const NodePath &rel_to)
Recomputes the bounding volume.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A thread; that is, a lightweight process.
 
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
 
A class to retrieve the individual data elements previously stored in a Datagram.
 
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
 
TypeHandle is the identifier used to differentiate C++ class types.
 
get_tube_up
Returns the normal vector used to control the "top" of the curve, when RenderMode is RM_tube.
 
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
 
bool around(const GeometricBoundingVolume **first, const GeometricBoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
 
The result of a NurbsCurveEvaluator.
 
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
 
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_use_vertex_color
Returns the "use vertex color" flag.
 
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
 
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
 
get_uv_scale
Returns the scaling factor to apply to generated UV's for the rope.