Panda3D
|
00001 // Filename: geomTriangles.cxx 00002 // Created by: drose (06Mar05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "geomTriangles.h" 00016 #include "geomVertexRewriter.h" 00017 #include "pStatTimer.h" 00018 #include "bamReader.h" 00019 #include "bamWriter.h" 00020 #include "graphicsStateGuardianBase.h" 00021 00022 TypeHandle GeomTriangles::_type_handle; 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: GeomTriangles::Constructor 00026 // Access: Published 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 GeomTriangles:: 00030 GeomTriangles(GeomTriangles::UsageHint usage_hint) : 00031 GeomPrimitive(usage_hint) 00032 { 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: GeomTriangles::Copy Constructor 00037 // Access: Published 00038 // Description: 00039 //////////////////////////////////////////////////////////////////// 00040 GeomTriangles:: 00041 GeomTriangles(const GeomTriangles ©) : 00042 GeomPrimitive(copy) 00043 { 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: GeomTriangles::Destructor 00048 // Access: Published, Virtual 00049 // Description: 00050 //////////////////////////////////////////////////////////////////// 00051 GeomTriangles:: 00052 ~GeomTriangles() { 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: GeomTriangles::make_copy 00057 // Access: Public, Virtual 00058 // Description: 00059 //////////////////////////////////////////////////////////////////// 00060 PT(GeomPrimitive) GeomTriangles:: 00061 make_copy() const { 00062 return new GeomTriangles(*this); 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function: GeomTriangles::get_primitive_type 00067 // Access: Public, Virtual 00068 // Description: Returns the fundamental rendering type of this 00069 // primitive: whether it is points, lines, or polygons. 00070 // 00071 // This is used to set up the appropriate antialiasing 00072 // settings when AntialiasAttrib::M_auto is in effect; 00073 // it also implies the type of primitive that will be 00074 // produced when decompose() is called. 00075 //////////////////////////////////////////////////////////////////// 00076 GeomPrimitive::PrimitiveType GeomTriangles:: 00077 get_primitive_type() const { 00078 return PT_polygons; 00079 } 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: GeomTriangles::get_num_vertices_per_primitive 00083 // Access: Public, Virtual 00084 // Description: If the primitive type is a simple type in which all 00085 // primitives have the same number of vertices, like 00086 // triangles, returns the number of vertices per 00087 // primitive. If the primitive type is a more complex 00088 // type in which different primitives might have 00089 // different numbers of vertices, for instance a 00090 // triangle strip, returns 0. 00091 //////////////////////////////////////////////////////////////////// 00092 int GeomTriangles:: 00093 get_num_vertices_per_primitive() const { 00094 return 3; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: GeomTriangles::draw 00099 // Access: Public, Virtual 00100 // Description: Calls the appropriate method on the GSG to draw the 00101 // primitive. 00102 //////////////////////////////////////////////////////////////////// 00103 bool GeomTriangles:: 00104 draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, 00105 bool force) const { 00106 return gsg->draw_triangles(reader, force); 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: GeomTriangles::doubleside_impl 00111 // Access: Protected, Virtual 00112 // Description: The virtual implementation of doubleside(). 00113 //////////////////////////////////////////////////////////////////// 00114 CPT(GeomPrimitive) GeomTriangles:: 00115 doubleside_impl() const { 00116 Thread *current_thread = Thread::get_current_thread(); 00117 PT(GeomTriangles) reversed = new GeomTriangles(*this); 00118 00119 GeomPrimitivePipelineReader from(this, current_thread); 00120 00121 // This is like reverse(), except we don't clear the vertices first. 00122 // That way we double the vertices up. 00123 00124 // First, rotate the original copy, if necessary, so the 00125 // flat-first/flat-last nature of the vertices is consistent 00126 // throughout the primitive. 00127 bool needs_rotate = false; 00128 switch (from.get_shade_model()) { 00129 case SM_flat_first_vertex: 00130 case SM_flat_last_vertex: 00131 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate()); 00132 needs_rotate = true; 00133 00134 default: 00135 break; 00136 } 00137 00138 // Now append all the new vertices, in reverse order. 00139 for (int i = from.get_num_vertices() - 1; i >= 0; --i) { 00140 reversed->add_vertex(from.get_vertex(i)); 00141 } 00142 00143 // Finally, re-rotate the whole thing to get back to the original 00144 // shade model. 00145 if (needs_rotate) { 00146 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate()); 00147 } 00148 00149 return reversed.p(); 00150 } 00151 00152 //////////////////////////////////////////////////////////////////// 00153 // Function: GeomTriangles::reverse_impl 00154 // Access: Protected, Virtual 00155 // Description: The virtual implementation of reverse(). 00156 //////////////////////////////////////////////////////////////////// 00157 CPT(GeomPrimitive) GeomTriangles:: 00158 reverse_impl() const { 00159 Thread *current_thread = Thread::get_current_thread(); 00160 PT(GeomTriangles) reversed = new GeomTriangles(*this); 00161 00162 GeomPrimitivePipelineReader from(this, current_thread); 00163 reversed->clear_vertices(); 00164 00165 for (int i = from.get_num_vertices() - 1; i >= 0; --i) { 00166 reversed->add_vertex(from.get_vertex(i)); 00167 } 00168 00169 switch (from.get_shade_model()) { 00170 case SM_flat_first_vertex: 00171 reversed->set_shade_model(SM_flat_last_vertex); 00172 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate()); 00173 break; 00174 00175 case SM_flat_last_vertex: 00176 reversed->set_shade_model(SM_flat_first_vertex); 00177 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate()); 00178 break; 00179 00180 default: 00181 break; 00182 } 00183 00184 return reversed.p(); 00185 } 00186 00187 //////////////////////////////////////////////////////////////////// 00188 // Function: GeomTriangles::rotate_impl 00189 // Access: Protected, Virtual 00190 // Description: The virtual implementation of rotate(). 00191 //////////////////////////////////////////////////////////////////// 00192 CPT(GeomVertexArrayData) GeomTriangles:: 00193 rotate_impl() const { 00194 // To rotate triangles, we just move one vertex from the front to 00195 // the back, or vice-versa; but we have to know what direction we're 00196 // going. 00197 ShadeModel shade_model = get_shade_model(); 00198 int num_vertices = get_num_vertices(); 00199 00200 PT(GeomVertexArrayData) new_vertices = make_index_data(); 00201 new_vertices->set_num_rows(num_vertices); 00202 00203 if (is_indexed()) { 00204 CPT(GeomVertexArrayData) vertices = get_vertices(); 00205 GeomVertexReader from(vertices, 0); 00206 GeomVertexWriter to(new_vertices, 0); 00207 00208 switch (shade_model) { 00209 case SM_flat_first_vertex: 00210 // Move the first vertex to the end. 00211 { 00212 for (int begin = 0; begin < num_vertices; begin += 3) { 00213 from.set_row_unsafe(begin + 1); 00214 to.set_data1i(from.get_data1i()); 00215 to.set_data1i(from.get_data1i()); 00216 from.set_row_unsafe(begin); 00217 to.set_data1i(from.get_data1i()); 00218 } 00219 } 00220 break; 00221 00222 case SM_flat_last_vertex: 00223 // Move the last vertex to the front. 00224 { 00225 for (int begin = 0; begin < num_vertices; begin += 3) { 00226 from.set_row_unsafe(begin + 2); 00227 to.set_data1i(from.get_data1i()); 00228 from.set_row_unsafe(begin); 00229 to.set_data1i(from.get_data1i()); 00230 to.set_data1i(from.get_data1i()); 00231 } 00232 } 00233 break; 00234 00235 default: 00236 // This shouldn't get called with any other shade model. 00237 nassertr(false, vertices); 00238 } 00239 00240 nassertr(to.is_at_end(), NULL); 00241 00242 } else { 00243 // Nonindexed case. 00244 int first_vertex = get_first_vertex(); 00245 GeomVertexWriter to(new_vertices, 0); 00246 00247 switch (shade_model) { 00248 case SM_flat_first_vertex: 00249 // Move the first vertex to the end. 00250 { 00251 for (int begin = 0; begin < num_vertices; begin += 3) { 00252 to.set_data1i(begin + 1 + first_vertex); 00253 to.set_data1i(begin + 2 + first_vertex); 00254 to.set_data1i(begin + first_vertex); 00255 } 00256 } 00257 break; 00258 00259 case SM_flat_last_vertex: 00260 // Move the last vertex to the front. 00261 { 00262 for (int begin = 0; begin < num_vertices; begin += 3) { 00263 to.set_data1i(begin + 2 + first_vertex); 00264 to.set_data1i(begin + first_vertex); 00265 to.set_data1i(begin + 1 + first_vertex); 00266 } 00267 } 00268 break; 00269 00270 default: 00271 // This shouldn't get called with any other shade model. 00272 nassertr(false, NULL); 00273 } 00274 00275 nassertr(to.is_at_end(), NULL); 00276 } 00277 00278 return new_vertices; 00279 } 00280 00281 //////////////////////////////////////////////////////////////////// 00282 // Function: GeomTriangles::register_with_read_factory 00283 // Access: Public, Static 00284 // Description: Tells the BamReader how to create objects of type 00285 // Geom. 00286 //////////////////////////////////////////////////////////////////// 00287 void GeomTriangles:: 00288 register_with_read_factory() { 00289 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00290 } 00291 00292 //////////////////////////////////////////////////////////////////// 00293 // Function: GeomTriangles::make_from_bam 00294 // Access: Protected, Static 00295 // Description: This function is called by the BamReader's factory 00296 // when a new object of type Geom is encountered 00297 // in the Bam file. It should create the Geom 00298 // and extract its information from the file. 00299 //////////////////////////////////////////////////////////////////// 00300 TypedWritable *GeomTriangles:: 00301 make_from_bam(const FactoryParams ¶ms) { 00302 GeomTriangles *object = new GeomTriangles(UH_unspecified); 00303 DatagramIterator scan; 00304 BamReader *manager; 00305 00306 parse_params(params, scan, manager); 00307 object->fillin(scan, manager); 00308 00309 return object; 00310 }