Panda3D
geomLinestrips.cxx
1 // Filename: geomLinestrips.cxx
2 // Created by: drose (22Mar05)
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 "geomLinestrips.h"
16 #include "geomLines.h"
17 #include "geomVertexRewriter.h"
18 #include "pStatTimer.h"
19 #include "bamReader.h"
20 #include "bamWriter.h"
21 #include "graphicsStateGuardianBase.h"
22 
23 TypeHandle GeomLinestrips::_type_handle;
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: GeomLinestrips::Constructor
27 // Access: Published
28 // Description:
29 ////////////////////////////////////////////////////////////////////
30 GeomLinestrips::
31 GeomLinestrips(GeomLinestrips::UsageHint usage_hint) :
32  GeomPrimitive(usage_hint)
33 {
34 }
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: GeomLinestrips::Copy Constructor
38 // Access: Published
39 // Description:
40 ////////////////////////////////////////////////////////////////////
41 GeomLinestrips::
42 GeomLinestrips(const GeomLinestrips &copy) :
43  GeomPrimitive(copy)
44 {
45 }
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: GeomLinestrips::Destructor
49 // Access: Published, Virtual
50 // Description:
51 ////////////////////////////////////////////////////////////////////
52 GeomLinestrips::
53 ~GeomLinestrips() {
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: GeomLinestrips::make_copy
58 // Access: Public, Virtual
59 // Description:
60 ////////////////////////////////////////////////////////////////////
61 PT(GeomPrimitive) GeomLinestrips::
62 make_copy() const {
63  return new GeomLinestrips(*this);
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: GeomLinestrips::get_primitive_type
68 // Access: Public, Virtual
69 // Description: Returns the fundamental rendering type of this
70 // primitive: whether it is points, lines, or polygons.
71 //
72 // This is used to set up the appropriate antialiasing
73 // settings when AntialiasAttrib::M_auto is in effect;
74 // it also implies the type of primitive that will be
75 // produced when decompose() is called.
76 ////////////////////////////////////////////////////////////////////
77 GeomPrimitive::PrimitiveType GeomLinestrips::
78 get_primitive_type() const {
79  return PT_lines;
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function: GeomLinestrips::get_geom_rendering
84 // Access: Published, Virtual
85 // Description: Returns the set of GeomRendering bits that represent
86 // the rendering properties required to properly render
87 // this primitive.
88 ////////////////////////////////////////////////////////////////////
90 get_geom_rendering() const {
91  if (is_indexed()) {
92  if (get_num_primitives() > 1) {
93  return GR_line_strip | GR_indexed_other | GR_strip_cut_index;
94  } else {
95  return GR_line_strip | GR_indexed_other;
96  }
97  } else {
98  return GR_line_strip;
99  }
100 }
101 
102 ////////////////////////////////////////////////////////////////////
103 // Function: GeomLinestrips::get_min_num_vertices_per_primitive
104 // Access: Public, Virtual
105 // Description: Returns the minimum number of vertices that must be
106 // added before close_primitive() may legally be called.
107 ////////////////////////////////////////////////////////////////////
110  return 2;
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function: GeomLinestrips::get_num_unused_vertices_per_primitive
115 // Access: Public, Virtual
116 // Description: Returns the number of vertices that are added between
117 // primitives that aren't, strictly speaking, part of
118 // the primitives themselves. This is used, for
119 // instance, to define degenerate triangles to connect
120 // otherwise disconnected triangle strips.
121 ////////////////////////////////////////////////////////////////////
124  return 1;
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function: GeomLinestrips::draw
129 // Access: Public, Virtual
130 // Description: Calls the appropriate method on the GSG to draw the
131 // primitive.
132 ////////////////////////////////////////////////////////////////////
133 bool GeomLinestrips::
135  bool force) const {
136  return gsg->draw_linestrips(reader, force);
137 }
138 
139 ////////////////////////////////////////////////////////////////////
140 // Function: GeomLinestrips::decompose_impl
141 // Access: Protected, Virtual
142 // Description: Decomposes a complex primitive type into a simpler
143 // primitive type, for instance line strips to
144 // lines, and returns a pointer to the new primitive
145 // definition. If the decomposition cannot be
146 // performed, this might return the original object.
147 //
148 // This method is useful for application code that wants
149 // to iterate through the set of lines on the
150 // primitive without having to write handlers for each
151 // possible kind of primitive type.
152 ////////////////////////////////////////////////////////////////////
153 CPT(GeomPrimitive) GeomLinestrips::
154 decompose_impl() const {
155  PT(GeomLines) lines = new GeomLines(get_usage_hint());
156  lines->set_shade_model(get_shade_model());
157  CPTA_int ends = get_ends();
158 
159  int num_unused = get_num_unused_vertices_per_primitive();
160 
161  int vi = -num_unused;
162  int li = 0;
163  while (li < (int)ends.size()) {
164  // Skip unused vertices between tristrips.
165  vi += num_unused;
166  int end = ends[li];
167  nassertr(vi + 1 <= end, lines.p());
168  int v0 = get_vertex(vi);
169  ++vi;
170  while (vi < end) {
171  int v1 = get_vertex(vi);
172  ++vi;
173  lines->add_vertex(v0);
174  lines->add_vertex(v1);
175  v0 = v1;
176  lines->close_primitive();
177  }
178  ++li;
179  }
180  nassertr(vi == get_num_vertices(), NULL);
181 
182  return lines.p();
183 }
184 
185 ////////////////////////////////////////////////////////////////////
186 // Function: GeomLinestrips::rotate_impl
187 // Access: Protected, Virtual
188 // Description: The virtual implementation of do_rotate().
189 ////////////////////////////////////////////////////////////////////
190 CPT(GeomVertexArrayData) GeomLinestrips::
191 rotate_impl() const {
192  // To rotate a line strip, we just reverse the vertices.
193  CPTA_int ends = get_ends();
194  PT(GeomVertexArrayData) new_vertices = make_index_data();
195  new_vertices->set_num_rows(get_num_vertices());
196 
197  if (is_indexed()) {
198  CPT(GeomVertexArrayData) vertices = get_vertices();
199  GeomVertexReader from(vertices, 0);
200  GeomVertexWriter to(new_vertices, 0);
201 
202  int begin = 0;
203  CPTA_int::const_iterator ei;
204  for (ei = ends.begin(); ei != ends.end(); ++ei) {
205  int end = (*ei);
206  for (int vi = end - 1; vi >= begin; --vi) {
207  from.set_row_unsafe(vi);
208  to.set_data1i(from.get_data1i());
209  }
210  begin = end;
211  }
212 
213  nassertr(to.is_at_end(), NULL);
214 
215  } else {
216  // Nonindexed case.
217  int first_vertex = get_first_vertex();
218  GeomVertexWriter to(new_vertices, 0);
219 
220  int begin = 0;
221  CPTA_int::const_iterator ei;
222  for (ei = ends.begin(); ei != ends.end(); ++ei) {
223  int end = (*ei);
224  for (int vi = end - 1; vi >= begin; --vi) {
225  to.set_data1i(vi + first_vertex);
226  }
227  begin = end;
228  }
229 
230  nassertr(to.is_at_end(), NULL);
231  }
232  return new_vertices;
233 }
234 
235 ////////////////////////////////////////////////////////////////////
236 // Function: GeomLinestrips::requires_unused_vertices
237 // Access: Protected, Virtual
238 // Description: Should be redefined to return true in any primitive
239 // that implements append_unused_vertices().
240 ////////////////////////////////////////////////////////////////////
241 bool GeomLinestrips::
242 requires_unused_vertices() const {
243  return true;
244 }
245 
246 ////////////////////////////////////////////////////////////////////
247 // Function: GeomLinestrips::append_unused_vertices
248 // Access: Protected, Virtual
249 // Description: Called when a new primitive is begun (other than the
250 // first primitive), this should add some degenerate
251 // vertices between primitives, if the primitive type
252 // requires that. The second parameter is the first
253 // vertex that begins the new primitive.
254 ////////////////////////////////////////////////////////////////////
255 void GeomLinestrips::
256 append_unused_vertices(GeomVertexArrayData *vertices, int vertex) {
257  GeomVertexWriter to(vertices, 0);
258  to.set_row_unsafe(vertices->get_num_rows());
259  to.add_data1i(get_strip_cut_index());
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: GeomLinestrips::register_with_read_factory
264 // Access: Public, Static
265 // Description: Tells the BamReader how to create objects of type
266 // Geom.
267 ////////////////////////////////////////////////////////////////////
268 void GeomLinestrips::
270  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
271 }
272 
273 ////////////////////////////////////////////////////////////////////
274 // Function: GeomLinestrips::make_from_bam
275 // Access: Protected, Static
276 // Description: This function is called by the BamReader's factory
277 // when a new object of type Geom is encountered
278 // in the Bam file. It should create the Geom
279 // and extract its information from the file.
280 ////////////////////////////////////////////////////////////////////
281 TypedWritable *GeomLinestrips::
282 make_from_bam(const FactoryParams &params) {
283  GeomLinestrips *object = new GeomLinestrips(UH_unspecified);
284  DatagramIterator scan;
285  BamReader *manager;
286 
287  parse_params(params, scan, manager);
288  object->fillin(scan, manager);
289 
290  return object;
291 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
virtual int get_min_num_vertices_per_primitive() const
Returns the minimum number of vertices that must be added before close_primitive() may legally be cal...
ShadeModel get_shade_model() const
Returns the ShadeModel hint for this primitive.
Definition: geomPrimitive.I:24
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:63
int get_num_vertices() const
Returns the number of indices used by all the primitives in this object.
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
virtual int get_num_unused_vertices_per_primitive() const
Returns the number of vertices that are added between primitives that aren&#39;t, strictly speaking...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual int get_geom_rendering() const
Returns the set of GeomRendering bits that represent the rendering properties required to properly re...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
Defines a series of disconnected line segments.
Definition: geomLines.h:25
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
int get_num_rows() const
Returns the number of rows stored in the array, based on the number of bytes and the stride...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
int get_num_primitives() const
Returns the number of individual primitives stored within this object.
int get_vertex(int i) const
Returns the ith vertex index in the table.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
Defines a series of line strips.
UsageHint get_usage_hint() const
Returns the usage hint for this primitive.
Definition: geomPrimitive.I:67
static void register_with_read_factory()
Tells the BamReader how to create objects of type Geom.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
Similar to PointerToArray, except that its contents may not be modified.
This is the data for one array of a GeomVertexData structure.