Panda3D
lineSegs.cxx
1 // Filename: lineSegs.cxx
2 // Created by: drose (16Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "lineSegs.h"
16 #include "renderState.h"
17 #include "renderModeAttrib.h"
18 #include "geom.h"
19 #include "geomLinestrips.h"
20 #include "geomPoints.h"
21 #include "geomVertexReader.h"
22 #include "geomVertexWriter.h"
23 #include "colorAttrib.h"
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: LineSegs::Constructor
27 // Access: Public
28 // Description: Constructs a LineSegs object, which can be used to
29 // create any number of disconnected lines or points of
30 // various thicknesses and colors through the visible
31 // scene. After creating the object, call move_to() and
32 // draw_to() repeatedly to describe the path, then call
33 // create() to create a GeomNode which will render the
34 // described path.
35 ////////////////////////////////////////////////////////////////////
37 LineSegs(const string &name) : Namable(name) {
38  _color.set(1.0f, 1.0f, 1.0f, 1.0f);
39  _thick = 1.0f;
40 }
41 
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: LineSegs::Destructor
45 // Access: Public
46 ////////////////////////////////////////////////////////////////////
47 LineSegs::
48 ~LineSegs() {
49 }
50 
51 
52 ////////////////////////////////////////////////////////////////////
53 // Function: LineSegs::reset
54 // Access: Public
55 // Description: Removes any lines in progress and resets to the
56 // initial empty state.
57 ////////////////////////////////////////////////////////////////////
58 void LineSegs::
59 reset() {
60  _list.clear();
61 }
62 
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: LineSegs::move_to
66 // Access: Public
67 // Description: Moves the pen to the given point without drawing a
68 // line. When followed by draw_to(), this marks the
69 // first point of a line segment; when followed by
70 // move_to() or create(), this creates a single point.
71 ////////////////////////////////////////////////////////////////////
72 void LineSegs::
73 move_to(const LVecBase3 &v) {
74  // We create a new SegmentList with the initial point in it.
75  SegmentList segs;
76  segs.push_back(Point(v, _color));
77 
78  // And add this list to the list of segments.
79  _list.push_back(segs);
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function: LineSegs::draw_to
84 // Access: Public
85 // Description: Draws a line segment from the pen's last position
86 // (the last call to move_to or draw_to) to the
87 // indicated point. move_to() and draw_to() only update
88 // tables; the actual drawing is performed when create()
89 // is called.
90 ////////////////////////////////////////////////////////////////////
91 void LineSegs::
92 draw_to(const LVecBase3 &v) {
93  if (_list.empty()) {
94  // Let our first call to draw_to() be an implicit move_to().
95  move_to(v);
96 
97  } else {
98  // Get the current SegmentList, which was the last one we added to
99  // the LineList.
100  SegmentList &segs = _list.back();
101 
102  // Add the new point.
103  segs.push_back(Point(v, _color));
104  }
105 }
106 
107 ////////////////////////////////////////////////////////////////////
108 // Function: LineSegs::empty
109 // Access: Public
110 // Description: Returns true if move_to() or draw_to() have not been
111 // called since the last reset() or create(), false
112 // otherwise.
113 ////////////////////////////////////////////////////////////////////
114 bool LineSegs::
116  return _list.empty();
117 }
118 
119 ////////////////////////////////////////////////////////////////////
120 // Function: LineSegs::get_vertex
121 // Access: Public
122 // Description: Returns the nth point or vertex of the line segment
123 // sequence generated by the last call to create(). The
124 // first move_to() generates vertex 0; subsequent
125 // move_to() and draw_to() calls generate consecutively
126 // higher vertex numbers.
127 ////////////////////////////////////////////////////////////////////
128 LVertex LineSegs::
129 get_vertex(int n) const {
130  nassertr(_created_data != (GeomVertexData *)NULL, LVertex::zero());
131  GeomVertexReader vertex(_created_data, InternalName::get_vertex());
132  vertex.set_row_unsafe(n);
133  return vertex.get_data3();
134 }
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: LineSegs::set_vertex
138 // Access: Public
139 // Description: Moves the nth point or vertex of the line segment
140 // sequence generated by the last call to create(). The
141 // first move_to() generates vertex 0; subsequent
142 // move_to() and draw_to() calls generate consecutively
143 // higher vertex numbers.
144 ////////////////////////////////////////////////////////////////////
145 void LineSegs::
146 set_vertex(int n, const LVertex &vert) {
147  nassertv(_created_data != (GeomVertexData *)NULL);
148  GeomVertexWriter vertex(_created_data, InternalName::get_vertex());
149  vertex.set_row_unsafe(n);
150  vertex.set_data3(vert);
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: LineSegs::get_vertex_color
155 // Access: Public
156 // Description: Returns the color of the nth point or vertex.
157 ////////////////////////////////////////////////////////////////////
159 get_vertex_color(int n) const {
160  nassertr(_created_data != (GeomVertexData *)NULL, LColor::zero());
161  GeomVertexReader color(_created_data, InternalName::get_color());
162  color.set_row_unsafe(n);
163  return color.get_data4();
164 }
165 
166 ////////////////////////////////////////////////////////////////////
167 // Function: LineSegs::set_vertex_color
168 // Access: Public
169 // Description: Changes the vertex color of the nth point or vertex.
170 // See set_vertex().
171 ////////////////////////////////////////////////////////////////////
172 void LineSegs::
173 set_vertex_color(int n, const LColor &c) {
174  nassertv(_created_data != (GeomVertexData *)NULL);
175  GeomVertexWriter color(_created_data, InternalName::get_color());
176  color.set_row_unsafe(n);
177  color.set_data4(c);
178 }
179 
180 ////////////////////////////////////////////////////////////////////
181 // Function: LineSegs::get_current_position
182 // Access: Public
183 // Description: Returns the pen's current position. The next call to
184 // draw_to() will draw a line segment from this point.
185 ////////////////////////////////////////////////////////////////////
186 const LVertex &LineSegs::
188  if (_list.empty()) {
189  // Our pen isn't anywhere. We'll put it somewhere.
190  move_to(LVertex(0.0f, 0.0f, 0.0f));
191  }
192 
193  return _list.back().back()._point;
194 }
195 
196 ////////////////////////////////////////////////////////////////////
197 // Function: LineSegs::create
198 // Access: Public
199 // Description: Appends to an existing GeomNode a new Geom that
200 // will render the series of line segments and points
201 // described via calls to move_to() and draw_to(). The
202 // lines and points are created with the color and
203 // thickness established by calls to set_color() and
204 // set_thick().
205 //
206 // If dynamic is true, the line segments will be created
207 // with the dynamic Geom setting, optimizing them for
208 // runtime vertex animation.
209 ////////////////////////////////////////////////////////////////////
211 create(GeomNode *previous, bool dynamic) {
212  if (!_list.empty()) {
213  CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _thick);
214  CPT(RenderAttrib) vtxcolor = ColorAttrib::make_vertex();
215  CPT(RenderState) state = RenderState::make(thick, vtxcolor);
216 
217  _created_data = new GeomVertexData
218  ("lineSegs", GeomVertexFormat::get_v3cp(),
219  dynamic ? Geom::UH_dynamic : Geom::UH_static);
220  GeomVertexWriter vertex(_created_data, InternalName::get_vertex());
221  GeomVertexWriter color(_created_data, InternalName::get_color());
222 
223  PT(GeomLinestrips) lines = new GeomLinestrips(Geom::UH_static);
224  PT(GeomPoints) points = new GeomPoints(Geom::UH_static);
225 
226  int v = 0;
227  LineList::const_iterator ll;
228  SegmentList::const_iterator sl;
229 
230  for (ll = _list.begin(); ll != _list.end(); ll++) {
231  const SegmentList &segs = (*ll);
232 
233  if (segs.size() < 2) {
234  // A segment of length 1 is just a point.
235  for (sl = segs.begin(); sl != segs.end(); sl++) {
236  points->add_vertex(v);
237  vertex.add_data3((*sl)._point);
238  color.add_data4((*sl)._color);
239  v++;
240  }
241  points->close_primitive();
242 
243  } else {
244  // A segment of length 2 or more is a line segment or
245  // segments.
246  for (sl = segs.begin(); sl != segs.end(); sl++) {
247  lines->add_vertex(v);
248  vertex.add_data3((*sl)._point);
249  color.add_data4((*sl)._color);
250  v++;
251  }
252  lines->close_primitive();
253  }
254  }
255 
256  if (lines->get_num_vertices() != 0) {
257  PT(Geom) geom = new Geom(_created_data);
258  geom->add_primitive(lines);
259  previous->add_geom(geom, state);
260  }
261  if (points->get_num_vertices() != 0) {
262  PT(Geom) geom = new Geom(_created_data);
263  geom->add_primitive(points);
264  previous->add_geom(geom, state);
265  }
266 
267  // And reset for next time.
268  reset();
269  }
270 
271  return previous;
272 }
bool is_empty()
Returns true if move_to() or draw_to() have not been called since the last reset() or create()...
Definition: lineSegs.cxx:115
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
LineSegs(const string &name="lines")
Constructs a LineSegs object, which can be used to create any number of disconnected lines or points ...
Definition: lineSegs.cxx:37
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
Defines a series of disconnected points.
Definition: geomPoints.h:25
void set_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. ...
LColor get_vertex_color(int vertex) const
Returns the color of the nth point or vertex.
Definition: lineSegs.cxx:159
const LVertex & get_current_position()
Returns the pen&#39;s current position.
Definition: lineSegs.cxx:187
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
GeomNode * create(bool dynamic=false)
Creates a new GeomNode that will render the series of line segments and points described via calls to...
Definition: lineSegs.I:137
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. ...
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
void move_to(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Moves the pen to the given point without drawing a line.
Definition: lineSegs.I:105
A base class for all things which can have a name.
Definition: namable.h:29
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
const LVecBase3 & get_data3()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
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. ...
void set_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. ...
void reset()
Removes any lines in progress and resets to the initial empty state.
Definition: lineSegs.cxx:59
void draw_to(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Draws a line segment from the pen&#39;s last position (the last call to move_to or draw_to) to the indica...
Definition: lineSegs.I:119
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void set_vertex(int n, const LVertex &vert)
Moves the nth point or vertex of the line segment sequence generated by the last call to create()...
Definition: lineSegs.cxx:146
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
Defines a series of line strips.
LVertex get_vertex(int n) const
Returns the nth point or vertex of the line segment sequence generated by the last call to create()...
Definition: lineSegs.cxx:129
void set_vertex_color(int vertex, const LColor &c)
Changes the vertex color of the nth point or vertex.
Definition: lineSegs.cxx:173
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
Definition: geomNode.cxx:642
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
static const LVecBase4f & zero()
Returns a zero-length vector.
Definition: lvecBase4.h:493