Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/gobj/geomTrifan.cxx

Go to the documentation of this file.
00001 // Filename: geomTrifan.cxx
00002 // Created by:  charles (13Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include <datagram.h>
00020 #include <datagramIterator.h>
00021 #include <bamReader.h>
00022 #include <bamWriter.h>
00023 #include <ioPtaDatagramShort.h>
00024 #include <ioPtaDatagramInt.h>
00025 #include <ioPtaDatagramLinMath.h>
00026 #include <graphicsStateGuardianBase.h>
00027 
00028 #include "geomTri.h"
00029 #include "geomTrifan.h"
00030 
00031 TypeHandle GeomTrifan::_type_handle;
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: GeomTrifan::get_num_tris
00035 //       Access:
00036 //  Description:
00037 ////////////////////////////////////////////////////////////////////
00038 int GeomTrifan::
00039 get_num_tris() const {
00040   int numtris = 0;
00041   for (int i = 0; i < _numprims; i++) {
00042     numtris += _primlengths[i] - 2;
00043   }
00044   return numtris;
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: GeomTrifan::make_copy
00049 //       Access: Public, Virtual
00050 //  Description: Returns a newly-allocated Geom that is a shallow copy
00051 //               of this one.  It will be a different Geom pointer,
00052 //               but its internal data may or may not be shared with
00053 //               that of the original Geom.
00054 ////////////////////////////////////////////////////////////////////
00055 Geom *GeomTrifan::
00056 make_copy() const {
00057   return new GeomTrifan(*this);
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: GeomTrifan::print_draw_immediate
00062 //       Access:
00063 //  Description:
00064 ////////////////////////////////////////////////////////////////////
00065 void GeomTrifan::
00066 print_draw_immediate( void ) const
00067 {
00068   /*
00069     int i;
00070     int j;
00071     int nprims = _numprims;
00072     int* plen = _primlengths;
00073     Vertexf* tcoords = _coords;
00074     Normalf* tnorms = _norms;
00075     Colorf* tcolors = _colors;
00076     TexCoordf* ttexcoords = _texcoords;
00077     ushort* tvindex = _vindex;
00078     ushort* tnindex = _nindex;
00079     ushort* tcindex = _cindex;
00080     ushort* ttindex = _tindex;
00081 
00082     // Draw overall
00083     if ( _color_command[G_OVERALL] != _issue_color_noop )
00084     {
00085         nout << "Color (Overall): ";
00086         if ( tcindex )
00087         {
00088             nout << "idx: " << *tcindex << " ";
00089             nout << tcolors[*(tcindex++)];
00090         }
00091         else
00092             nout << *(tcolors++);
00093         nout << endl;
00094     }
00095     if ( _normal_command[G_OVERALL] != _issue_normal_noop )
00096     {
00097         nout << "Normal (Overall): ";
00098         if ( tnindex )
00099         {
00100             nout << "idx: " << *tnindex << " ";
00101             nout << tnorms[*(tnindex++)];
00102         }
00103         else
00104             nout << *(tnorms++);
00105         nout << endl;
00106     }
00107 
00108     for ( i = nprims; i > 0; i-- )
00109     {
00110         // Draw per primitive
00111         if ( _color_command[G_PER_PRIM] != _issue_color_noop )
00112         {
00113             nout << "Color (Per Prim): ";
00114             if ( tcindex )
00115             {
00116                 nout << "idx: " << *tcindex << " ";
00117                 nout << tcolors[*(tcindex++)];
00118             }
00119             else
00120                 nout << *(tcolors++);
00121             nout << endl;
00122         }
00123         if ( _normal_command[G_PER_PRIM] != _issue_normal_noop )
00124         {
00125             nout << "Normal (Per Prim): ";
00126             if ( tnindex )
00127             {
00128                 nout << "idx: " << *tnindex << " ";
00129                 nout << tnorms[*(tnindex++)];
00130             }
00131             else
00132                 nout << *(tnorms++);
00133             nout << endl;
00134         }
00135 
00136         nout << "BeginGfx()" << endl;
00137 
00138         for ( j = *(plen++); j > 0; j-- )
00139         {
00140             // Draw per vertex
00141             if ( _color_command[G_PER_VERTEX] != _issue_color_noop )
00142             {
00143                 nout << "Color (Per Vertex): ";
00144                 if ( tcindex )
00145                 {
00146                     nout << "idx: " << *tcindex << " ";
00147                     nout << tcolors[*(tcindex++)];
00148                 }
00149                 else
00150                     nout << *(tcolors++);
00151                 nout << endl;
00152             }
00153             if ( _normal_command[G_PER_VERTEX] != _issue_normal_noop )
00154             {
00155                 nout << "Normal (Per Vertex): ";
00156                 if ( tnindex )
00157                 {
00158                     nout << "idx: " << *tnindex << " ";
00159                     nout << tnorms[*(tnindex++)];
00160                 }
00161                 else
00162                     nout << *(tnorms++);
00163                 nout << endl;
00164             }
00165             if ( _texcoord_command[G_PER_VERTEX] != _issue_texcoord_noop )
00166             {
00167                 nout << "TexCoord (Per Vertex): ";
00168                 if ( ttindex )
00169                 {
00170                     nout << "idx: " << *ttindex << " ";
00171                     nout << ttexcoords[*(ttindex++)];
00172                 }
00173                 else
00174                     nout << *(ttexcoords++);
00175                 nout << endl;
00176             }
00177             if ( _vertex_command[G_PER_VERTEX] != _issue_vertex_noop )
00178             {
00179                 nout << "Vertex (Per Vertex): ";
00180                 if ( tvindex )
00181                 {
00182                     nout << "idx: " << *tvindex << " ";
00183                     nout << tcoords[*(tvindex++)];
00184                 }
00185                 else
00186                     nout << *(tcoords++);
00187                 nout << endl;
00188             }
00189         }
00190 
00191         nout << "EndGfx()" << endl;
00192     }
00193     */
00194 }
00195 
00196 ////////////////////////////////////////////////////////////////////
00197 //     Function: GeomTrifan::draw_immediate
00198 //       Access:
00199 //  Description:
00200 ////////////////////////////////////////////////////////////////////
00201 void GeomTrifan::
00202 draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
00203   gsg->draw_trifan(this, gc);
00204 }
00205 
00206 ////////////////////////////////////////////////////////////////////
00207 //     Function: GeomTrifan::explode
00208 //       Access: Public, Virtual
00209 //  Description: Allocate and return a new Geom which represents the
00210 //               individual triangles that make up the trifan.
00211 ////////////////////////////////////////////////////////////////////
00212 Geom *GeomTrifan::
00213 explode() const {
00214   PTA_Vertexf coords=PTA_Vertexf::empty_array(0);
00215   PTA_Normalf normals=PTA_Normalf::empty_array(0);
00216   PTA_TexCoordf texcoords=PTA_TexCoordf::empty_array(0);
00217   PTA_Colorf colors=PTA_Colorf::empty_array(0);
00218 
00219   VertexIterator vi = make_vertex_iterator();
00220   NormalIterator ni = make_normal_iterator();
00221   TexCoordIterator ti = make_texcoord_iterator();
00222   ColorIterator ci = make_color_iterator();
00223 
00224   // Get overall values
00225   if (get_binding(G_COLOR) == G_OVERALL) {
00226     colors.push_back(get_next_color(ci));
00227   }
00228   if (get_binding(G_NORMAL) == G_OVERALL) {
00229     normals.push_back(get_next_normal(ni));
00230   }
00231 
00232   int num_tris = 0;
00233   int num_prims = get_num_prims();
00234 
00235   for (int i = 0; i < num_prims; i++) {
00236     // Get per-primitive values
00237     Colorf per_trifan_color;
00238     Normalf per_trifan_normal;
00239     if (get_binding(G_COLOR) == G_PER_PRIM) {
00240       per_trifan_color = get_next_color(ci);
00241     }
00242     if (get_binding(G_NORMAL) == G_PER_PRIM) {
00243       per_trifan_normal = get_next_normal(ni);
00244     }
00245 
00246     int num_verts = get_length(i);
00247     assert(num_verts >= 3);
00248 
00249     // A few temporary arrays to hold the three most recent per-vertex
00250     // values.
00251     Vertexf f3vertex[3];
00252     Normalf f3normal[3];
00253     Colorf f3color[3];
00254     TexCoordf f3texcoord[3];
00255 
00256     // Get the first two vertices.  We get these into positions [0]
00257     // and [2].
00258 
00259     int v;
00260     for (v = 0; v <= 2; v += 2) {
00261       if (get_binding(G_COORD) == G_PER_VERTEX) {
00262         f3vertex[v] = get_next_vertex(vi);
00263       }
00264       if (get_binding(G_NORMAL) == G_PER_VERTEX) {
00265         f3normal[v] = get_next_normal(ni);
00266       }
00267       if (get_binding(G_TEXCOORD) == G_PER_VERTEX) {
00268         f3texcoord[v] = get_next_texcoord(ti);
00269       }
00270       if (get_binding(G_COLOR) == G_PER_VERTEX) {
00271         f3color[v] = get_next_color(ci);
00272       }
00273     }
00274 
00275     // Now fill each triangle.  Each vertex from this point on defines
00276     // a new triangle.
00277     for (v = 2; v < num_verts; v++) {
00278       num_tris++;
00279 
00280       f3vertex[1] = f3vertex[2];
00281       f3normal[1] = f3normal[2];
00282       f3texcoord[1] = f3texcoord[2];
00283       f3color[1] = f3color[2];
00284 
00285       if (get_binding(G_COLOR) == G_PER_PRIM) {
00286         colors.push_back(per_trifan_color);
00287       } else if (get_binding(G_COLOR) == G_PER_COMPONENT) {
00288         colors.push_back(get_next_color(ci));
00289       }
00290 
00291       if (get_binding(G_NORMAL) == G_PER_PRIM) {
00292         normals.push_back(per_trifan_normal);
00293       } else if (get_binding(G_NORMAL) == G_PER_COMPONENT) {
00294         normals.push_back(get_next_normal(ni));
00295       }
00296 
00297       // Per-vertex attributes.
00298       assert(get_binding(G_COORD) == G_PER_VERTEX);
00299       f3vertex[2] = get_next_vertex(vi);
00300       coords.push_back(f3vertex[0]);
00301       coords.push_back(f3vertex[1]);
00302       coords.push_back(f3vertex[2]);
00303 
00304       if (get_binding(G_NORMAL) == G_PER_VERTEX) {
00305         f3normal[2] = get_next_normal(ni);
00306         normals.push_back(f3normal[0]);
00307         normals.push_back(f3normal[1]);
00308         normals.push_back(f3normal[2]);
00309       }
00310       if (get_binding(G_TEXCOORD) == G_PER_VERTEX) {
00311         f3texcoord[2] = get_next_texcoord(ti);
00312         texcoords.push_back(f3texcoord[0]);
00313         texcoords.push_back(f3texcoord[1]);
00314         texcoords.push_back(f3texcoord[2]);
00315       }
00316       if (get_binding(G_COLOR) == G_PER_VERTEX) {
00317         f3color[2] = get_next_color(ci);
00318         colors.push_back(f3color[0]);
00319         colors.push_back(f3color[1]);
00320         colors.push_back(f3color[2]);
00321       }
00322     }
00323   }
00324 
00325   Geom *tris = new GeomTri;
00326   tris->set_coords(coords);
00327 
00328   tris->set_normals(normals,
00329                     get_binding(G_NORMAL) == G_PER_COMPONENT ?
00330                     G_PER_PRIM : get_binding(G_NORMAL));
00331   tris->set_texcoords(texcoords, get_binding(G_TEXCOORD));
00332   tris->set_colors(colors,
00333                    get_binding(G_COLOR) == G_PER_COMPONENT ?
00334                    G_PER_PRIM : get_binding(G_COLOR));
00335   tris->set_num_prims(num_tris);
00336 
00337   return tris;
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: GeomTrifan::get_tris
00342 //       Access: Public, Virtual
00343 //  Description: This is similar in principle to explode(), except it
00344 //               returns only a list of triangle vertex indices, with
00345 //               no information about color or whatever.  The array
00346 //               returned is a set of indices into the geom's _coords
00347 //               array, as retrieve by get_coords(); there will be 3*n
00348 //               elements in the array, where n is the number of
00349 //               triangles described by the geometry.  This is useful
00350 //               when it's important to determine the physical
00351 //               structure of the geometry, without necessarily
00352 //               worrying about its rendering properties, and when
00353 //               performance considerations are not overwhelming.
00354 ////////////////////////////////////////////////////////////////////
00355 PTA_ushort GeomTrifan::
00356 get_tris() const {
00357   int num_tris = get_num_tris();
00358   PTA_ushort tris;
00359   tris.reserve(num_tris * 3);
00360 
00361   int k = 0;
00362 
00363   for (int i = 0; i < _numprims; i++) {
00364     ushort v0, v1, v2;
00365     if (_vindex.empty()) {
00366       v0 = k++;
00367       v1 = k++;
00368     } else {
00369       v0 = _vindex[k++];
00370       v1 = _vindex[k++];
00371     }
00372 
00373     int len = _primlengths[i] - 2;
00374 
00375     for (int j = 0; j < len; j++) {
00376       if (_vindex.empty()) {
00377         v2 = k++;
00378       } else {
00379         v2 = _vindex[k++];
00380       }
00381 
00382       tris.push_back(v0);
00383       tris.push_back(v1);
00384       tris.push_back(v2);
00385 
00386       v1 = v2;
00387     }
00388   }
00389 
00390   nassertr((int)tris.size() == num_tris * 3, PTA_ushort());
00391   return tris;
00392 }
00393 
00394 ////////////////////////////////////////////////////////////////////
00395 //     Function: GeomTrifan::make_GeomTrifan
00396 //       Access: Protected
00397 //  Description: Factory method to generate a GeomTrifan object
00398 ////////////////////////////////////////////////////////////////////
00399 TypedWritable* GeomTrifan::
00400 make_GeomTrifan(const FactoryParams &params) {
00401   GeomTrifan *me = new GeomTrifan;
00402   DatagramIterator scan;
00403   BamReader *manager;
00404 
00405   parse_params(params, scan, manager);
00406   me->fillin(scan, manager);
00407   me->make_dirty();
00408   me->config();
00409   return me;
00410 }
00411 
00412 ////////////////////////////////////////////////////////////////////
00413 //     Function: GeomTrifan::register_with_factory
00414 //       Access: Public, Static
00415 //  Description: Factory method to generate a GeomTrifan object
00416 ////////////////////////////////////////////////////////////////////
00417 void GeomTrifan::
00418 register_with_read_factory(void) {
00419   BamReader::get_factory()->register_factory(get_class_type(), make_GeomTrifan);
00420 }
00421 

Generated on Fri May 2 00:39:29 2003 for Panda by doxygen1.3