Panda3D
Loading...
Searching...
No Matches
geomLinestrips.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file geomLinestrips.cxx
10 * @author drose
11 * @date 2005-03-22
12 */
13
14#include "geomLinestrips.h"
15#include "geomLines.h"
16#include "geomVertexRewriter.h"
17#include "pStatTimer.h"
18#include "bamReader.h"
19#include "bamWriter.h"
22
23using std::map;
24
25TypeHandle GeomLinestrips::_type_handle;
26
27/**
28 *
29 */
30GeomLinestrips::
31GeomLinestrips(GeomLinestrips::UsageHint usage_hint) :
32 GeomPrimitive(usage_hint)
33{
34}
35
36/**
37 *
38 */
39GeomLinestrips::
40GeomLinestrips(const GeomLinestrips &copy) :
41 GeomPrimitive(copy)
42{
43}
44
45/**
46 *
47 */
48GeomLinestrips::
49~GeomLinestrips() {
50}
51
52/**
53 *
54 */
55PT(GeomPrimitive) GeomLinestrips::
56make_copy() const {
57 return new GeomLinestrips(*this);
58}
59
60/**
61 * Returns the fundamental rendering type of this primitive: whether it is
62 * points, lines, or polygons.
63 *
64 * This is used to set up the appropriate antialiasing settings when
65 * AntialiasAttrib::M_auto is in effect; it also implies the type of primitive
66 * that will be produced when decompose() is called.
67 */
68GeomPrimitive::PrimitiveType GeomLinestrips::
69get_primitive_type() const {
70 return PT_lines;
71}
72
73/**
74 * Returns the set of GeomRendering bits that represent the rendering
75 * properties required to properly render this primitive.
76 */
77int GeomLinestrips::
78get_geom_rendering() const {
79 if (is_indexed()) {
80 if (get_num_primitives() > 1) {
81 return GR_line_strip | GR_indexed_other | GR_strip_cut_index;
82 } else {
83 return GR_line_strip | GR_indexed_other;
84 }
85 } else {
86 return GR_line_strip;
87 }
88}
89
90/**
91 * Adds adjacency information to this primitive. May return null if this type
92 * of geometry does not support adjacency information.
93 */
94CPT(GeomPrimitive) GeomLinestrips::
95make_adjacency() const {
96 Thread *current_thread = Thread::get_current_thread();
98
99 GeomPrimitivePipelineReader from(this, current_thread);
100 int num_vertices = from.get_num_vertices();
101 CPTA_int ends = get_ends();
102
103 const int num_unused = 1;
104
105 // First, build a map of each vertex to its next vertex, and another map
106 // doing the exact reverse.
107 map<int, int> forward_map, reverse_map;
108 int vi = -num_unused;
109 int li = 0;
110 while (li < (int)ends.size()) {
111 // Skip unused vertices between linestrips.
112 vi += num_unused;
113 int end = ends[li];
114 nassertr(vi + 1 <= end, nullptr);
115 int v0 = from.get_vertex(vi++);
116 while (vi < end) {
117 int v1 = from.get_vertex(vi++);
118 forward_map[v0] = v1;
119 reverse_map[v1] = v0;
120 v0 = v1;
121 }
122 ++li;
123 }
124 nassertr(vi == num_vertices, nullptr);
125
126 // Now build up the new vertex data. For each linestrip, we prepend and
127 // append the appropriate connecting vertices.
128 vi = -num_unused;
129 li = 0;
130 while (li < (int)ends.size()) {
131 // Skip unused vertices between linestrips.
132 vi += num_unused;
133 int end = ends[li];
134 nassertr(vi + 1 <= end, nullptr);
135
136 // Look for the line segment connected to the beginning of this strip.
137 int v0 = from.get_vertex(vi++);
138 auto it = reverse_map.find(v0);
139 if (it != reverse_map.end()) {
140 adj->add_vertex(it->second);
141 } else {
142 // Um, no adjoining line segment? Just repeat the vertex, I guess.
143 adj->add_vertex(v0);
144 }
145
146 // Add the actual vertices in the strip.
147 adj->add_vertex(v0);
148 int v1 = v0;
149 while (vi < end) {
150 v1 = from.get_vertex(vi++);
151 adj->add_vertex(v1);
152 }
153
154 // Do the same for the last vertex in the strip.
155 it = forward_map.find(v1);
156 if (it != forward_map.end()) {
157 adj->add_vertex(it->second);
158 } else {
159 adj->add_vertex(v1);
160 }
161
162 adj->close_primitive();
163 ++li;
164 }
165 nassertr(vi == num_vertices, nullptr);
166
167 return adj;
168}
169
170/**
171 * Returns the minimum number of vertices that must be added before
172 * close_primitive() may legally be called.
173 */
174int GeomLinestrips::
175get_min_num_vertices_per_primitive() const {
176 return 2;
177}
178
179/**
180 * Returns the number of vertices that are added between primitives that
181 * aren't, strictly speaking, part of the primitives themselves. This is
182 * used, for instance, to define degenerate triangles to connect otherwise
183 * disconnected triangle strips.
184 */
185int GeomLinestrips::
186get_num_unused_vertices_per_primitive() const {
187 return 1;
188}
189
190/**
191 * Calls the appropriate method on the GSG to draw the primitive.
192 */
193bool GeomLinestrips::
195 bool force) const {
196 return gsg->draw_linestrips(reader, force);
197}
198
199/**
200 * Decomposes a complex primitive type into a simpler primitive type, for
201 * instance line strips to lines, and returns a pointer to the new primitive
202 * definition. If the decomposition cannot be performed, this might return
203 * the original object.
204 *
205 * This method is useful for application code that wants to iterate through
206 * the set of lines on the primitive without having to write handlers for each
207 * possible kind of primitive type.
208 */
209CPT(GeomPrimitive) GeomLinestrips::
210decompose_impl() const {
211 PT(GeomLines) lines = new GeomLines(get_usage_hint());
212 lines->set_shade_model(get_shade_model());
213 CPTA_int ends = get_ends();
214
215 int num_unused = get_num_unused_vertices_per_primitive();
216
217 int vi = -num_unused;
218 int li = 0;
219 while (li < (int)ends.size()) {
220 // Skip unused vertices between tristrips.
221 vi += num_unused;
222 int end = ends[li];
223 nassertr(vi + 1 <= end, lines);
224 int v0 = get_vertex(vi);
225 ++vi;
226 while (vi < end) {
227 int v1 = get_vertex(vi);
228 ++vi;
229 lines->add_vertex(v0);
230 lines->add_vertex(v1);
231 v0 = v1;
232 lines->close_primitive();
233 }
234 ++li;
235 }
236 nassertr(vi == get_num_vertices(), nullptr);
237
238 return lines;
239}
240
241/**
242 * The virtual implementation of do_rotate().
243 */
244CPT(GeomVertexArrayData) GeomLinestrips::
245rotate_impl() const {
246 // To rotate a line strip, we just reverse the vertices.
247 CPTA_int ends = get_ends();
248 PT(GeomVertexArrayData) new_vertices = make_index_data();
249 new_vertices->set_num_rows(get_num_vertices());
250
251 if (is_indexed()) {
252 CPT(GeomVertexArrayData) vertices = get_vertices();
253 GeomVertexReader from(vertices, 0);
254 GeomVertexWriter to(new_vertices, 0);
255
256 int begin = 0;
257 CPTA_int::const_iterator ei;
258 for (ei = ends.begin(); ei != ends.end(); ++ei) {
259 int end = (*ei);
260 for (int vi = end - 1; vi >= begin; --vi) {
261 from.set_row_unsafe(vi);
262 to.set_data1i(from.get_data1i());
263 }
264 begin = end;
265 }
266
267 nassertr(to.is_at_end(), nullptr);
268
269 } else {
270 // Nonindexed case.
271 int first_vertex = get_first_vertex();
272 GeomVertexWriter to(new_vertices, 0);
273
274 int begin = 0;
275 CPTA_int::const_iterator ei;
276 for (ei = ends.begin(); ei != ends.end(); ++ei) {
277 int end = (*ei);
278 for (int vi = end - 1; vi >= begin; --vi) {
279 to.set_data1i(vi + first_vertex);
280 }
281 begin = end;
282 }
283
284 nassertr(to.is_at_end(), nullptr);
285 }
286 return new_vertices;
287}
288
289/**
290 * Should be redefined to return true in any primitive that implements
291 * append_unused_vertices().
292 */
293bool GeomLinestrips::
294requires_unused_vertices() const {
295 return true;
296}
297
298/**
299 * Called when a new primitive is begun (other than the first primitive), this
300 * should add some degenerate vertices between primitives, if the primitive
301 * type requires that. The second parameter is the first vertex that begins
302 * the new primitive.
303 */
304void GeomLinestrips::
305append_unused_vertices(GeomVertexArrayData *vertices, int vertex) {
306 GeomVertexWriter to(vertices, 0);
307 to.set_row_unsafe(vertices->get_num_rows());
308 to.add_data1i(get_strip_cut_index());
309}
310
311/**
312 * Tells the BamReader how to create objects of type Geom.
313 */
316 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
317}
318
319/**
320 * This function is called by the BamReader's factory when a new object of
321 * type Geom is encountered in the Bam file. It should create the Geom and
322 * extract its information from the file.
323 */
324TypedWritable *GeomLinestrips::
325make_from_bam(const FactoryParams &params) {
326 GeomLinestrips *object = new GeomLinestrips(UH_unspecified);
327 DatagramIterator scan;
328 BamReader *manager;
329
330 parse_params(params, scan, manager);
331 object->fillin(scan, manager);
332
333 return object;
334}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition bamReader.I:275
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...
Definition bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
Similar to PointerToArray, except that its contents may not be modified.
A class to retrieve the individual data elements previously stored in a Datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition factory.I:73
Defines a series of disconnected line segments.
Definition geomLines.h:23
Defines a series of line strips with adjacency information.
Defines a series of line strips.
static void register_with_read_factory()
Tells the BamReader how to create objects of type Geom.
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
int get_num_primitives() const
Returns the number of individual primitives stored within this object.
CPTA_int get_ends() const
Returns a const pointer to the primitive ends array so application code can read it directly.
get_vertex
Returns the ith vertex index in the table.
get_usage_hint
Returns the usage hint for this primitive.
get_num_vertices
Returns the number of indices used by all the primitives in this object.
get_strip_cut_index
Returns the index of the indicated type that is reserved for use as a strip cut index,...
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
get_shade_model
Returns the ShadeModel hint for this primitive.
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
This is the data for one array of a GeomVertexData structure.
int get_num_rows() const
Returns the number of rows stored in the array, based on the number of bytes and the stride.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.