Panda3D
 All Classes Functions Variables Enumerations
geomTriangles.cxx
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 &copy) :
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 &params) {
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 }
 All Classes Functions Variables Enumerations