Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

gfx/VisualTriangles.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)1996 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: VisualTriangles.cpp 1030 2004-02-11 20:46:17Z jungd $
00019   $Revision: 1.5 $
00020   $Date: 2004-02-11 15:46:17 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <gfx/VisualTriangles>
00026 
00027 #include <gfx/TriangleIterator>
00028 
00029 #include <osg/Node>
00030 #include <osg/Transform>
00031 #include <osg/MatrixTransform>
00032 #include <osg/PositionAttitudeTransform>
00033 #include <osg/Group>
00034 #include <osg/Switch>
00035 #include <osg/LOD>
00036 #include <osg/Geode>
00037 #include <osg/Drawable>
00038 #include <osg/Geometry>
00039 #include <osg/PrimitiveSet>
00040 
00041 
00042 using gfx::VisualTriangles;
00043 using gfx::TriangleContainer;
00044 using gfx::TriangleIterator;
00045 
00046 using osg::Node;
00047 using osg::Group;
00048 using osg::Switch;
00049 using osg::Transform;
00050 using osg::MatrixTransform;
00051 using osg::PositionAttitudeTransform;
00052 using osg::Geometry;
00053 using osg::PrimitiveSet;
00054 using osg::DrawArrays;
00055 using osg::DrawElementsUShort;
00056 using osg::Vec3;
00057 using osg::Array;
00058 using osg::Vec3Array;
00059 using osg::NodeVisitor;
00060 
00061 
00062 
00063 VisualTriangles::VisualTriangles(const Visual& visual)
00064   : LODChild(0)
00065 {
00066   if (visual.visualTypeSupported(Visual::OSGVisual)) {
00067     extractTriangles(visual.createOSGVisual(Visual::VerticesOnly));
00068   }
00069   else
00070     throw std::runtime_error(Exception("Visual type not supported")); 
00071 }
00072 
00073 
00074 VisualTriangles::VisualTriangles(const Visual& visual, Int LODChild)
00075   : LODChild(LODChild)
00076 {
00077   if (visual.visualTypeSupported(Visual::OSGVisual)) {
00078     extractTriangles(visual.createOSGVisual(Visual::VerticesOnly));
00079   }
00080   else
00081     throw std::runtime_error(Exception("Visual type not supported")); 
00082 }
00083 
00084 
00085 void VisualTriangles::extractTriangles(osg::Node* node)
00086 {
00087   TriangleExtractor extractor(triangles,LODChild);
00088   extractor.setTraversalMode(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
00089   node->accept(extractor);
00090 }
00091 
00092 
00093 
00094 VisualTriangles::const_iterator TriangleContainer::begin() const
00095 {
00096   return TriangleIterator(*this, true); 
00097 }
00098 
00099 VisualTriangles::const_iterator TriangleContainer::end() const 
00100 {
00101   return TriangleIterator(*this, false); 
00102 }
00103 
00104 
00105 void VisualTriangles::TriangleExtractor::apply(osg::Transform& node)
00106 {
00107   if (node.getName() != "debug") {
00108 
00109     if (instanceof(node, osg::MatrixTransform)) {
00110 
00111       osg::MatrixTransform& mt(narrow_cast<MatrixTransform>(node));
00112       
00113 
00114       Matrix4 t(mt.getMatrix());
00115       transform.push( transform.top()*t ); // !!! check mul order
00116       
00117       node.traverse(*this);
00118       
00119       transform.pop();
00120     }
00121     else if (instanceof(node, osg::PositionAttitudeTransform)) {
00122       //!!!
00123       throw std::runtime_error(Exception("PositionAttitudeTransform not implemented"));
00124     }
00125     else {
00126       Logln("unknown transform type, not applied (treated as identity)");
00127       node.traverse(*this);
00128     }
00129 
00130   }
00131 }
00132 
00133 
00134 void VisualTriangles::TriangleExtractor::apply(osg::Switch& node)
00135 {
00136   if (node.getName() != "debug") 
00137     node.traverse(*this);
00138 }
00139 
00140 void VisualTriangles::TriangleExtractor::apply(osg::Group& node)
00141 {
00142   if (node.getName() != "debug") // don't traverse debugging graphics (axes etc.)
00143     node.traverse(*this);
00144 }
00145 
00146 void VisualTriangles::TriangleExtractor::apply(osg::LOD& node)
00147 {
00148   if (node.getName() != "debug") {
00149     int n = node.getNumChildren();
00150     int child = (int(LODChild)<n)?LODChild:(n-1);
00151     node.getChild(child)->accept(*this);
00152   }
00153 }
00154 
00155 void VisualTriangles::TriangleExtractor::apply(osg::Geode &node)
00156 {
00157   // Extract triangles from any GeoSets in the Geode
00158   int numDrawables = node.getNumDrawables();
00159   for(Int d=0; d<Int(numDrawables); d++) {
00160     osg::Drawable* drawable = node.getDrawable(d);
00161 /*
00162     if (instanceof(*drawable,osg::GeoSet)) {
00163       GeoSet* geoSet = narrow_cast<GeoSet>((osg::Drawable*)drawable); // !!! check this
00164       
00165       Int numPrims = geoSet->getNumPrims();
00166       const Vec3* coords = geoSet->getCoords();
00167       const int* lens = geoSet->getPrimLengths();
00168       const Vec3* c=coords;
00169 
00170       Assertm(lens,"lens!=0"); //!!! why would it be 0? (it sometimes is - OSG bug?)
00171 
00172       switch (geoSet->getPrimType()) {
00173       case GeoSet::NO_TYPE: // no triangles
00174       case GeoSet::POINTS:
00175       case GeoSet::LINES:
00176       case GeoSet::LINE_STRIP:
00177       case GeoSet::FLAT_LINE_STRIP:
00178       case GeoSet::LINE_LOOP:
00179       break;
00180         
00181       case GeoSet::TRIANGLES: {
00182         for(Int p=0; p < numPrims; p++) {
00183           Int n = lens[p];
00184           for(Int v=0; v < n; v+=3) 
00185             triangles.push_back(Triangle3(c[v],c[v+1],c[v+2]));
00186           c +=n;
00187         }
00188       }
00189       break;
00190 
00191       case GeoSet::FLAT_TRIANGLE_STRIP:
00192       case GeoSet::TRIANGLE_STRIP: {
00193         for(Int p=0; p < numPrims; p++) {
00194           Int n = lens[p];
00195           for(Int v=2; v < n; v++) {
00196             if ((v%2)==0)
00197               triangles.push_back(Triangle3(c[v-2],c[v-1],c[v]));
00198             else
00199               triangles.push_back(Triangle3(c[v-1],c[v-2],c[v]));
00200           }
00201           c +=n;
00202         }
00203       }
00204       break;
00205         
00206       case GeoSet::TRIANGLE_FAN:
00207       case GeoSet::FLAT_TRIANGLE_FAN: {
00208         for(Int p=0; p < numPrims; p++) {
00209           Int n = lens[p];
00210           Vec3 f(c[0]);
00211           for(Int v=2; v < n; v++) 
00212             triangles.push_back(Triangle3(f,c[v-1],c[v]));
00213           c +=n;
00214         }
00215       }
00216       break;
00217         
00218       case GeoSet::QUADS: {
00219         for(Int p=0; p < numPrims; p++) {
00220           Int n = lens[p];
00221           for(Int v=0; v < n; v+=4) {
00222             triangles.push_back(Triangle3(c[v],c[v+1],c[v+2]));
00223             triangles.push_back(Triangle3(c[v+2],c[v+3],c[v]));
00224           }
00225           c +=n;
00226         }
00227       }
00228       break;
00229 
00230       case GeoSet::QUAD_STRIP: {
00231         for(Int p=0; p < numPrims; p++) {
00232           Int n = lens[p];
00233           for(Int v=2; v < n; v+=2) {
00234             triangles.push_back(Triangle3(c[v-2],c[v-1],c[v]));
00235             triangles.push_back(Triangle3(c[v],c[v-1],c[v+1]));
00236           }
00237           c +=n;
00238         }
00239       }
00240       break;
00241         
00242       case GeoSet::POLYGON: {
00243         Logln("Tesselation of polygons into triangles is not yet supported:");
00244         Logln(" will return convex version of polygon.");
00245         for(Int p=0; p < numPrims; p++) {
00246           Int n = lens[p];
00247           Vec3 f(c[0]);
00248           for(Int v=2; v < n; v++) 
00249             triangles.push_back(Triangle3(f,c[v-1],c[v]));
00250           c +=n;
00251         }
00252       }
00253       break;
00254 
00255       default: ;
00256       Logln("Warning: Unknown osg::GetSet primitive type.");
00257       }
00258 
00259    
00260     }
00261     else*/ if (instanceof(*drawable,osg::Geometry)) {
00262       Geometry* geom = narrow_cast<Geometry>((osg::Drawable*)drawable); 
00263 
00264       const Array& va(*geom->getVertexArray());
00265       Assert(va.getDataType() == Array::Vec3ArrayType);
00266       const Vec3Array& v(dynamic_cast<const Vec3Array&>(va));
00267 
00268       for(Int p=0; p<geom->getNumPrimitiveSets(); p++) {
00269         
00270         const PrimitiveSet* pset(geom->getPrimitiveSet(p));
00271         
00272         Int n = pset->getNumIndices();
00273 
00274         switch (pset->getMode()) {
00275           case PrimitiveSet::POINTS: // no triangles
00276           case PrimitiveSet::LINES:
00277           case PrimitiveSet::LINE_STRIP:
00278           case PrimitiveSet::LINE_LOOP:
00279           break; 
00280           
00281           case PrimitiveSet::TRIANGLES: {
00282             for(Int i=0; i<n; i+=3) {
00283               Int v0(pset->index(i));
00284               Int v1(pset->index(i+1));
00285               Int v2(pset->index(i+2));
00286               triangles.push_back(Triangle3(v[v0],v[v1],v[v2]));
00287             }
00288           } break;
00289           
00290           case PrimitiveSet::TRIANGLE_STRIP: {
00291             for(Int i=2; i < n; i++) {
00292               Int vi(pset->index(i));
00293               Int vim1(pset->index(i-1));
00294               Int vim2(pset->index(i-2));
00295               if ((i%2)==0)
00296                 triangles.push_back(Triangle3(v[vim2],v[vim1],v[vi]));
00297               else
00298                 triangles.push_back(Triangle3(v[vim1],v[vim2],v[vi]));
00299             }
00300             
00301           } break;
00302           
00303           case PrimitiveSet::TRIANGLE_FAN: {
00304             Point3 f(v[pset->index(0)]);
00305             for(Int i=2; i < n; i++) {
00306               Int vi(pset->index(i));
00307               Int vim1(pset->index(i-1));
00308               triangles.push_back(Triangle3(f,v[vim1],v[vi]));
00309             }
00310           } break;
00311           
00312           case PrimitiveSet::QUADS: {
00313             for(Int i=0; i < n; i+=4) {
00314               Int vi(pset->index(i));
00315               Int vip1(pset->index(i+1));
00316               Int vip2(pset->index(i+2));
00317               Int vip3(pset->index(i+3));
00318               triangles.push_back(Triangle3(v[vi],v[vip1],v[vip2]));
00319               triangles.push_back(Triangle3(v[vip2],v[vip3],v[vi]));
00320             }
00321           } break;
00322           
00323           case PrimitiveSet::QUAD_STRIP: {
00324             for(Int i=2; i < n; i+=2) {
00325               Int vi(pset->index(i));
00326               Int vim1(pset->index(i-1));
00327               Int vim2(pset->index(i-2));
00328               Int vip1(pset->index(i+1));
00329               triangles.push_back(Triangle3(v[vim2],v[vim1],v[vi]));
00330               triangles.push_back(Triangle3(v[vi],v[vim1],v[vip1]));
00331             }
00332           } break;
00333           
00334           case PrimitiveSet::POLYGON: {
00335             Logln("Tesselation of polygons into triangles is not yet supported.");
00336             Unimplemented;
00337           } break;
00338           
00339           default:
00340           Logln("Warning: Unsupported PrimitiveSet::Mode");
00341           
00342         } // switch
00343 
00344       }
00345     }
00346     else
00347       Logln("Warning: Unsupported osg::Drawable subclass " << drawable->className());
00348 
00349   }
00350 
00351 }

Generated on Thu Jul 29 15:56:20 2004 for OpenSim by doxygen 1.3.6