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.