16 #include "cullTraverser.h" 17 #include "cullTraverserData.h" 18 #include "cullableObject.h" 19 #include "cullHandler.h" 20 #include "renderState.h" 21 #include "renderModeAttrib.h" 22 #include "colorAttrib.h" 23 #include "bamWriter.h" 24 #include "bamReader.h" 26 #include "datagramIterator.h" 27 #include "pStatTimer.h" 29 #include "geomLines.h" 30 #include "geomTristrips.h" 31 #include "geomVertexWriter.h" 32 #include "boundingSphere.h" 45 return new CData(*
this);
54 void RopeNode::CData::
68 void RopeNode::CData::
80 RopeNode(
const string &name) :
168 render_thread(trav, data, result);
172 render_tape(trav, data, result);
176 render_billboard(trav, data, result);
180 render_tube(trav, data, result);
211 output(ostream &out)
const {
212 PandaNode::output(out);
215 out <<
" " << *curve;
217 out <<
" (no curve)";
227 write(ostream &out,
int indent_level)
const {
228 PandaNode::write(out, indent_level);
229 indent(out, indent_level) << *
get_curve() <<
"\n";
244 do_recompute_bounds(rel_to, pipeline_stage, current_thread);
245 mark_internal_bounds_stale(current_thread);
258 int &internal_vertices,
260 Thread *current_thread)
const {
265 internal_bounds = bounds;
266 internal_vertices = 0;
276 CPT(GeomVertexFormat) RopeNode::
277 get_format(
bool support_normals)
const {
278 PT(GeomVertexArrayFormat) array_format =
new GeomVertexArrayFormat
279 (InternalName::get_vertex(), 3, Geom::NT_stdfloat,
283 array_format->add_column
284 (InternalName::get_normal(), 3, Geom::NT_stdfloat,
288 array_format->add_column
289 (InternalName::get_color(), 1, Geom::NT_packed_dabc,
293 array_format->add_column
294 (InternalName::get_texcoord(), 2, Geom::NT_stdfloat,
298 return GeomVertexFormat::register_format(array_format);
307 do_recompute_bounds(
const NodePath &rel_to,
int pipeline_stage,
308 Thread *current_thread)
const {
319 get_curve()->get_vertices(verts, rel_to);
324 NurbsCurveEvaluator::Vert3Array::iterator vi;
325 for (vi = verts.begin(); vi != verts.end(); ++vi) {
331 DCAST_INTO_R(gbv, bound, bound);
332 gbv->
around(&verts[0], &verts[0] + verts.size());
355 int num_curve_verts = get_connected_segments(curve_segments, result);
360 (
"rope", get_format(
false), Geom::UH_stream);
361 compute_thread_vertices(vdata, curve_segments, num_curve_verts);
366 lines->reserve_num_vertices((num_curve_verts - 1) * 2);
368 for (
int vi = 0; vi < num_curve_verts - 1; ++vi) {
369 lines->add_vertex(vi);
370 lines->add_vertex(vi + 1);
371 lines->close_primitive();
375 geom->add_primitive(lines);
378 CPT(
RenderState) state = data._state->add_attrib(thick);
380 state = state->add_attrib(ColorAttrib::make_vertex());
385 data.get_internal_transform(trav));
403 int num_curve_verts = get_connected_segments(curve_segments, result);
409 (
"rope", get_format(
false), Geom::UH_stream);
412 curve_segments, num_curve_verts, result);
417 CurveSegments::const_iterator si;
418 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
421 strip->add_next_vertices(segment.size() * 2);
422 strip->close_primitive();
426 geom->add_primitive(strip);
430 state = state->add_attrib(ColorAttrib::make_vertex());
435 data.get_internal_transform(trav));
452 const TransformState *net_transform = data.get_net_transform(trav);
455 CPT(TransformState) rel_transform =
456 net_transform->invert_compose(camera_transform);
460 int num_curve_verts = get_connected_segments(curve_segments, result);
466 (
"rope", get_format(
false), Geom::UH_stream);
468 compute_billboard_vertices(vdata, camera_vec,
469 curve_segments, num_curve_verts, result);
474 CurveSegments::const_iterator si;
475 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
478 strip->add_next_vertices(segment.size() * 2);
479 strip->close_primitive();
483 geom->add_primitive(strip);
487 state = state->add_attrib(ColorAttrib::make_vertex());
492 data.get_internal_transform(trav));
509 int num_curve_verts = get_connected_segments(curve_segments, result);
515 int num_verts_per_slice;
518 (
"rope", get_format(
true), Geom::UH_stream);
520 compute_tube_vertices(vdata, num_verts_per_slice,
521 curve_segments, num_curve_verts, result);
529 CurveSegments::const_iterator si;
530 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
533 for (
int s = 0; s < num_slices; ++s) {
534 int s1 = (s + 1) % num_verts_per_slice;
536 for (
size_t j = 0; j < segment.size(); ++j) {
537 strip->add_vertex((vi + j) * num_verts_per_slice + s);
538 strip->add_vertex((vi + j) * num_verts_per_slice + s1);
541 strip->close_primitive();
543 vi += (int)segment.size();
547 geom->add_primitive(strip);
551 state = state->add_attrib(ColorAttrib::make_vertex());
556 data.get_internal_transform(trav));
579 int num_curve_verts = 0;
589 for (
int segment = 0; segment < num_segments; ++segment) {
599 curve_segment = &curve_segments.back();
604 if (use_vertex_color) {
609 if (use_vertex_thickness) {
615 curve_segment->push_back(vtx);
620 for (
int i = 1; i < num_verts; ++i) {
621 PN_stdfloat t = (PN_stdfloat)i / (PN_stdfloat)(num_verts - 1);
626 if (use_vertex_color) {
631 if (use_vertex_thickness) {
637 curve_segment->push_back(vtx);
644 return num_curve_verts;
657 int num_curve_verts)
const {
669 PN_stdfloat dist = 0.0f;
670 CurveSegments::const_iterator si;
671 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
673 for (
size_t j = 0; j < segment.size(); ++j) {
676 if (use_vertex_color) {
680 PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
682 if (uv_mode != UV_none) {
708 int expected_num_verts = num_curve_verts * 2;
716 PN_stdfloat overall_radius = thickness * 0.5f;
717 PN_stdfloat radius = overall_radius;
724 PN_stdfloat dist = 0.0f;
725 CurveSegments::const_iterator si;
726 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
728 for (
size_t j = 0; j < segment.size(); ++j) {
730 compute_tangent(tangent, segment, j, result);
732 LVector3 norm = cross(tangent, camera_vec);
735 if (use_vertex_thickness) {
736 radius = overall_radius * segment[j]._thickness;
739 vertex.
add_data3(segment[j]._p + norm * radius);
740 vertex.
add_data3(segment[j]._p - norm * radius);
742 if (use_vertex_color) {
747 PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
749 if (uv_mode != UV_none) {
773 int &num_verts_per_slice,
778 num_verts_per_slice = num_slices;
781 PN_stdfloat overall_radius = thickness * 0.5f;
782 PN_stdfloat radius = overall_radius;
793 if (uv_mode != UV_none) {
794 ++num_verts_per_slice;
797 int expected_num_verts = num_curve_verts * num_verts_per_slice;
807 PN_stdfloat dist = 0.0f;
808 CurveSegments::const_iterator si;
809 for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
811 for (
size_t j = 0; j < segment.size(); ++j) {
813 compute_tangent(tangent, segment, j, result);
821 if (IS_NEARLY_ZERO(tangent.get_y()) && IS_NEARLY_ZERO(tangent.get_z())) {
823 norm = cross(tangent,
LVector3(0, 1, 0));
825 norm = cross(tangent,
LVector3(1, 0, 0));
830 up = cross(norm, tangent);
835 PN_stdfloat uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
837 for (
int s = 0; s < num_verts_per_slice; ++s) {
838 if (use_vertex_thickness) {
839 radius = overall_radius * segment[j]._thickness;
842 vertex.
add_data3(segment[j]._p + norm * radius);
844 if (normal_mode == NM_vertex) {
848 if (use_vertex_color) {
852 norm = norm * rotate;
854 if (uv_mode != UV_none) {
855 PN_stdfloat uv_s = (PN_stdfloat)s / (PN_stdfloat)num_slices;
895 tangent = segment[j + 1]._p - segment[j]._p;
896 }
else if (j == segment.size() - 1) {
897 tangent = segment[j]._p - segment[j - 1]._p;
899 tangent = segment[j + 1]._p - segment[j - 1]._p;
905 tangent.set(0, 0, 1);
916 PN_stdfloat RopeNode::
917 compute_uv_t(PN_stdfloat &dist,
const RopeNode::UVMode &uv_mode,
925 return segment[j]._t * uv_scale;
929 LVector3 vec = segment[j]._p - segment[j - 1]._p;
932 return dist * uv_scale;
936 LVector3 vec = segment[j]._p - segment[j - 1]._p;
939 return dist * uv_scale;
982 parse_params(params, scan, manager);
983 node->fillin(scan, manager);
997 PandaNode::fillin(scan, manager);
float length_squared() const
Returns the square of the vector's length, cheap and easy.
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.
const TransformState * get_camera_transform() const
Returns the position of the camera relative to the starting node.
UVMode get_uv_mode() const
Returns the algorithm to use to generate UV's for the rope.
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.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
int get_pipeline_stage() const
Returns the Pipeline stage number associated with this thread.
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
int get_num_slices() const
Returns the number of radial subdivisions to make if RenderMode is RM_tube.
bool get_use_vertex_color() const
Returns the "use vertex color" flag.
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.
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 add_data2(PN_stdfloat x, PN_stdfloat y)
Sets the write row to a particular 2-component value, and advances the write row. ...
void skip_pointer(DatagramIterator &scan)
Reads and discards a pointer value from the Bam file.
bool has_matrix() const
Returns true if the node has a matrix set, false otherwise.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
const LMatrix4 & get_matrix() const
Returns the optional matrix which is used to transform each control vertex after it has been transfor...
This class draws a visible representation of the NURBS curve stored in its NurbsCurveEvaluator.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Defines a series of triangle strips.
int get_num_subdiv() const
Returns the number of subdivisions per cubic segment to draw.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
NormalMode get_normal_mode() const
Returns the kind of normals to generate for the rope.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
bool get_uv_direction() const
Returns true if the rope runs down the U coordinate of the texture, or false if it runs down the V co...
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
bool almost_equal(const LVecBase3f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
PN_stdfloat get_uv_scale() const
Returns the scaling factor to apply to generated UV's for the rope.
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...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of Node by calling the xform()...
static LVector3f forward(CoordinateSystem cs=CS_default)
Returns the forward vector for the given coordinate system.
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...
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 ...
NodePath get_node_path() const
Constructs and returns an actual NodePath that represents the same path we have just traversed...
bool get_use_vertex_thickness() const
Returns the "use vertex thickness" flag.
The smallest atom of cull.
This is a 4-by-4 transform matrix.
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
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...
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
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)...
int get_num_rows() const
Returns the number of rows stored within all the arrays.
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...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
const LVector3 & get_tube_up() const
Returns the normal vector used to control the "top" of the curve, when RenderMode is RM_tube...
Defines a series of disconnected line segments.
RenderMode get_render_mode() const
Returns the method used to render the rope.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
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.
void reset_bound(const NodePath &rel_to)
Recomputes the bounding volume.
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.
static int get_vertex_thickness_dimension()
Returns the numeric extended dimension in which the thickness component should be found...
static LMatrix3f rotate_mat(float angle)
Returns a matrix that rotates by the given angle in degrees counterclockwise.
PN_stdfloat get_thickness() const
Returns the thickness of the rope.
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.
This is a 3-by-3 transform matrix.
bool normalize()
Normalizes the vector in place.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
NurbsCurveEvaluator * get_curve() const
Returns the curve represented by the RopeNode.
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...
static int get_vertex_color_dimension()
Returns the numeric extended dimension in which the color components should be found.
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...