Home · All Namespaces · All Classes · Functions · Coding Style · Scripting · Plugins · File Structure

core/StelVertexArray.hpp

00001 /*
00002  * Stellarium
00003  * Copyright (C) 2009 Fabien Chereau
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 #ifndef __STELVERTEXARRAY_HPP__
00021 #define __STELVERTEXARRAY_HPP__
00022 
00023 #include <QVector>
00024 #include <QDebug>
00025 #include "VecMath.hpp"
00026 
00027 struct StelVertexArray
00028 {
00029     // TODO maybe merge this with StelPainter DrawingMode
00030     enum StelPrimitiveType
00031     {
00032         Points                      = 0x0000, // GL_POINTS
00033         Lines                       = 0x0001, // GL_LINES
00034         LineLoop                    = 0x0002, // GL_LINE_LOOP
00035         LineStrip                   = 0x0003, // GL_LINE_STRIP
00036         Triangles                   = 0x0004, // GL_TRIANGLES
00037         TriangleStrip               = 0x0005, // GL_TRIANGLE_STRIP
00038         TriangleFan                 = 0x0006  // GL_TRIANGLE_FAN
00039     };
00040 
00041     StelVertexArray(StelPrimitiveType pType=StelVertexArray::Triangles) : primitiveType(pType) {;}
00042     StelVertexArray(const QVector<Vec3d>& v, StelPrimitiveType pType=StelVertexArray::Triangles,const QVector<Vec2f>& t=QVector<Vec2f>(), const QVector<unsigned int> i=QVector<unsigned int>()) :
00043         vertex(v), texCoords(t), indices(i), primitiveType(pType) {;}
00044 
00048     QVector<Vec3d> vertex;
00050     QVector<Vec2f> texCoords;
00052     QVector<unsigned int> indices;
00053 
00054     StelPrimitiveType primitiveType;
00055 
00056     bool isIndexed() const {return !indices.isEmpty();}
00057 
00058     bool isTextured() const {return !texCoords.isEmpty();}
00059 
00064     template<class Func>
00065     inline Func foreachTriangle(Func func) const;
00066 
00068     StelVertexArray removeDiscontinuousTriangles(const class StelProjector* prj) const;
00069 
00070     void draw(class StelPainter* painter) const;
00071 
00072 private:
00073     // Below we define a few methods that are templated to be optimized according to different types of VertexArray :
00074     // The template parameter <bool T> defines whether the array has a texture.
00075     // The template parameter <bool I> defines whether the array is indexed.
00076     template <bool I>
00077     const Vec3d* specVertexAt(int i) const {
00078         return &vertex.at(specIndiceAt<I>(i));
00079     }
00080 
00081     template <bool T, bool I>
00082     const Vec2f* specTexCoordAt(int i) const {
00083         return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;
00084     }
00085 
00086     template<bool I>
00087     unsigned int specIndiceAt(unsigned int i) const {
00088         return I ? indices.at(i) : i;
00089     }
00090 
00091     template<bool T, bool I, class Func>
00092     inline Func specForeachTriangle(Func func) const;
00093 
00094 };
00095 
00096 template<class Func>
00097 Func StelVertexArray::foreachTriangle(Func func) const
00098 {
00099     // Here we just dispach the method into one of the 4 possible cases
00100     bool textured = isTextured();
00101     bool useIndice = isIndexed();
00102 
00103     if (textured)
00104         if (useIndice)
00105             return specForeachTriangle<true, true, Func>(func);
00106         else
00107             return specForeachTriangle<true, false, Func>(func);
00108     else
00109         if (useIndice)
00110             return specForeachTriangle<false, true, Func>(func);
00111         else
00112             return specForeachTriangle<false, false, Func>(func);
00113 }
00114 
00115 template<bool T, bool I, class Func>
00116 Func StelVertexArray::specForeachTriangle(Func func) const
00117 {
00118     switch (primitiveType)
00119     {
00120         case StelVertexArray::Triangles:
00121             Q_ASSERT(vertex.size() % 3 == 0);
00122             for (int i = 0; i < vertex.size(); i += 3)
00123             {
00124                 func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
00125                      specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
00126                      specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
00127             }
00128             break;
00129         case StelVertexArray::TriangleFan:
00130         {
00131             const Vec3d* v0 = specVertexAt<I>(0);
00132             const Vec2f* t0 = specTexCoordAt<T, I>(0);
00133             unsigned int i0 = specIndiceAt<I>(0);
00134             for (int i = 1; i < vertex.size() - 1; ++i)
00135             {
00136                 func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
00137                      t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
00138                      i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
00139             }
00140             break;
00141         }
00142         case StelVertexArray::TriangleStrip:
00143         {
00144             for (int i = 2; i < vertex.size(); ++i)
00145             {
00146                 if (i % 2 == 0)
00147                     func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
00148                          specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
00149                          specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
00150                 else
00151                     func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
00152                          specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
00153                          specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
00154             }
00155             break;
00156         }
00157         default:
00158             Q_ASSERT_X(0, Q_FUNC_INFO, "unsuported primitive type");
00159     }
00160     return func;
00161 }
00162 
00163 
00164 #endif // __STELVERTEXARRAY_HPP__

Generated on Mon Mar 22 09:55:38 2010 for Stellarium by  doxygen 1.5.5