Panda3D
 All Classes Functions Variables Enumerations
geomTriangles.cxx
1 // Filename: geomTriangles.cxx
2 // Created by: drose (06Mar05)
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 "geomTriangles.h"
16 #include "geomVertexRewriter.h"
17 #include "pStatTimer.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "graphicsStateGuardianBase.h"
21 
22 TypeHandle GeomTriangles::_type_handle;
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: GeomTriangles::Constructor
26 // Access: Published
27 // Description:
28 ////////////////////////////////////////////////////////////////////
29 GeomTriangles::
30 GeomTriangles(GeomTriangles::UsageHint usage_hint) :
31  GeomPrimitive(usage_hint)
32 {
33 }
34 
35 ////////////////////////////////////////////////////////////////////
36 // Function: GeomTriangles::Copy Constructor
37 // Access: Published
38 // Description:
39 ////////////////////////////////////////////////////////////////////
40 GeomTriangles::
41 GeomTriangles(const GeomTriangles &copy) :
42  GeomPrimitive(copy)
43 {
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: GeomTriangles::Destructor
48 // Access: Published, Virtual
49 // Description:
50 ////////////////////////////////////////////////////////////////////
51 GeomTriangles::
52 ~GeomTriangles() {
53 }
54 
55 ////////////////////////////////////////////////////////////////////
56 // Function: GeomTriangles::make_copy
57 // Access: Public, Virtual
58 // Description:
59 ////////////////////////////////////////////////////////////////////
61 make_copy() const {
62  return new GeomTriangles(*this);
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: GeomTriangles::get_primitive_type
67 // Access: Public, Virtual
68 // Description: Returns the fundamental rendering type of this
69 // primitive: whether it is points, lines, or polygons.
70 //
71 // This is used to set up the appropriate antialiasing
72 // settings when AntialiasAttrib::M_auto is in effect;
73 // it also implies the type of primitive that will be
74 // produced when decompose() is called.
75 ////////////////////////////////////////////////////////////////////
76 GeomPrimitive::PrimitiveType GeomTriangles::
77 get_primitive_type() const {
78  return PT_polygons;
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: GeomTriangles::get_num_vertices_per_primitive
83 // Access: Public, Virtual
84 // Description: If the primitive type is a simple type in which all
85 // primitives have the same number of vertices, like
86 // triangles, returns the number of vertices per
87 // primitive. If the primitive type is a more complex
88 // type in which different primitives might have
89 // different numbers of vertices, for instance a
90 // triangle strip, returns 0.
91 ////////////////////////////////////////////////////////////////////
94  return 3;
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: GeomTriangles::draw
99 // Access: Public, Virtual
100 // Description: Calls the appropriate method on the GSG to draw the
101 // primitive.
102 ////////////////////////////////////////////////////////////////////
103 bool GeomTriangles::
105  bool force) const {
106  return gsg->draw_triangles(reader, force);
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: GeomTriangles::doubleside_impl
111 // Access: Protected, Virtual
112 // Description: The virtual implementation of doubleside().
113 ////////////////////////////////////////////////////////////////////
115 doubleside_impl() const {
116  Thread *current_thread = Thread::get_current_thread();
117  PT(GeomTriangles) reversed = new GeomTriangles(*this);
118 
119  GeomPrimitivePipelineReader from(this, current_thread);
120 
121  // This is like reverse(), except we don't clear the vertices first.
122  // That way we double the vertices up.
123 
124  // First, rotate the original copy, if necessary, so the
125  // flat-first/flat-last nature of the vertices is consistent
126  // throughout the primitive.
127  bool needs_rotate = false;
128  switch (from.get_shade_model()) {
129  case SM_flat_first_vertex:
130  case SM_flat_last_vertex:
131  reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
132  needs_rotate = true;
133 
134  default:
135  break;
136  }
137 
138  // Now append all the new vertices, in reverse order.
139  for (int i = from.get_num_vertices() - 1; i >= 0; --i) {
140  reversed->add_vertex(from.get_vertex(i));
141  }
142 
143  // Finally, re-rotate the whole thing to get back to the original
144  // shade model.
145  if (needs_rotate) {
146  reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
147  }
148 
149  return reversed.p();
150 }
151 
152 ////////////////////////////////////////////////////////////////////
153 // Function: GeomTriangles::reverse_impl
154 // Access: Protected, Virtual
155 // Description: The virtual implementation of reverse().
156 ////////////////////////////////////////////////////////////////////
158 reverse_impl() const {
159  Thread *current_thread = Thread::get_current_thread();
160  PT(GeomTriangles) reversed = new GeomTriangles(*this);
161 
162  GeomPrimitivePipelineReader from(this, current_thread);
163  reversed->clear_vertices();
164 
165  for (int i = from.get_num_vertices() - 1; i >= 0; --i) {
166  reversed->add_vertex(from.get_vertex(i));
167  }
168 
169  switch (from.get_shade_model()) {
170  case SM_flat_first_vertex:
171  reversed->set_shade_model(SM_flat_last_vertex);
172  reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
173  break;
174 
175  case SM_flat_last_vertex:
176  reversed->set_shade_model(SM_flat_first_vertex);
177  reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
178  break;
179 
180  default:
181  break;
182  }
183 
184  return reversed.p();
185 }
186 
187 ////////////////////////////////////////////////////////////////////
188 // Function: GeomTriangles::rotate_impl
189 // Access: Protected, Virtual
190 // Description: The virtual implementation of rotate().
191 ////////////////////////////////////////////////////////////////////
193 rotate_impl() const {
194  // To rotate triangles, we just move one vertex from the front to
195  // the back, or vice-versa; but we have to know what direction we're
196  // going.
197  ShadeModel shade_model = get_shade_model();
198  int num_vertices = get_num_vertices();
199 
200  PT(GeomVertexArrayData) new_vertices = make_index_data();
201  new_vertices->set_num_rows(num_vertices);
202 
203  if (is_indexed()) {
204  CPT(GeomVertexArrayData) vertices = get_vertices();
205  GeomVertexReader from(vertices, 0);
206  GeomVertexWriter to(new_vertices, 0);
207 
208  switch (shade_model) {
209  case SM_flat_first_vertex:
210  // Move the first vertex to the end.
211  {
212  for (int begin = 0; begin < num_vertices; begin += 3) {
213  from.set_row_unsafe(begin + 1);
214  to.set_data1i(from.get_data1i());
215  to.set_data1i(from.get_data1i());
216  from.set_row_unsafe(begin);
217  to.set_data1i(from.get_data1i());
218  }
219  }
220  break;
221 
222  case SM_flat_last_vertex:
223  // Move the last vertex to the front.
224  {
225  for (int begin = 0; begin < num_vertices; begin += 3) {
226  from.set_row_unsafe(begin + 2);
227  to.set_data1i(from.get_data1i());
228  from.set_row_unsafe(begin);
229  to.set_data1i(from.get_data1i());
230  to.set_data1i(from.get_data1i());
231  }
232  }
233  break;
234 
235  default:
236  // This shouldn't get called with any other shade model.
237  nassertr(false, vertices);
238  }
239 
240  nassertr(to.is_at_end(), NULL);
241 
242  } else {
243  // Nonindexed case.
244  int first_vertex = get_first_vertex();
245  GeomVertexWriter to(new_vertices, 0);
246 
247  switch (shade_model) {
248  case SM_flat_first_vertex:
249  // Move the first vertex to the end.
250  {
251  for (int begin = 0; begin < num_vertices; begin += 3) {
252  to.set_data1i(begin + 1 + first_vertex);
253  to.set_data1i(begin + 2 + first_vertex);
254  to.set_data1i(begin + first_vertex);
255  }
256  }
257  break;
258 
259  case SM_flat_last_vertex:
260  // Move the last vertex to the front.
261  {
262  for (int begin = 0; begin < num_vertices; begin += 3) {
263  to.set_data1i(begin + 2 + first_vertex);
264  to.set_data1i(begin + first_vertex);
265  to.set_data1i(begin + 1 + first_vertex);
266  }
267  }
268  break;
269 
270  default:
271  // This shouldn't get called with any other shade model.
272  nassertr(false, NULL);
273  }
274 
275  nassertr(to.is_at_end(), NULL);
276  }
277 
278  return new_vertices;
279 }
280 
281 ////////////////////////////////////////////////////////////////////
282 // Function: GeomTriangles::register_with_read_factory
283 // Access: Public, Static
284 // Description: Tells the BamReader how to create objects of type
285 // Geom.
286 ////////////////////////////////////////////////////////////////////
287 void GeomTriangles::
289  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
290 }
291 
292 ////////////////////////////////////////////////////////////////////
293 // Function: GeomTriangles::make_from_bam
294 // Access: Protected, Static
295 // Description: This function is called by the BamReader's factory
296 // when a new object of type Geom is encountered
297 // in the Bam file. It should create the Geom
298 // and extract its information from the file.
299 ////////////////////////////////////////////////////////////////////
300 TypedWritable *GeomTriangles::
301 make_from_bam(const FactoryParams &params) {
302  GeomTriangles *object = new GeomTriangles(UH_unspecified);
303  DatagramIterator scan;
304  BamReader *manager;
305 
306  parse_params(params, scan, manager);
307  object->fillin(scan, manager);
308 
309  return object;
310 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
virtual int get_num_vertices_per_primitive() const
If the primitive type is a simple type in which all primitives have the same number of vertices...
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
static void register_with_read_factory()
Tells the BamReader how to create objects of type Geom.
void set_data1i(int data)
Sets the write row to a particular 1-component value, and advances the write row. ...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
A thread; that is, a lightweight process.
Definition: thread.h:51
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
int get_vertex(int i) const
Returns the ith vertex index in the table.
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
A class to retrieve the individual data elements previously stored in a Datagram. ...
virtual bool draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, bool force) const
Calls the appropriate method on the GSG to draw the primitive.
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.
This is the data for one array of a GeomVertexData structure.
bool is_at_end() const
Returns true if the writer is currently at the end of the list of vertices, false otherwise...