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 private:
00071     // Below we define a few methods that are templated to be optimized according to different types of VertexArray :
00072     // The template parameter <bool T> defines whether the array has a texture.
00073     // The template parameter <bool I> defines whether the array is indexed.
00074     template <bool I>
00075     const Vec3d* specVertexAt(int i) const {
00076         return &vertex.at(specIndiceAt<I>(i));
00077     }
00078 
00079     template <bool T, bool I>
00080     const Vec2f* specTexCoordAt(int i) const {
00081         return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;
00082     }
00083 
00084     template<bool I>
00085     unsigned int specIndiceAt(unsigned int i) const {
00086         return I ? indices.at(i) : i;
00087     }
00088 
00089     template<bool T, bool I, class Func>
00090     inline Func specForeachTriangle(Func func) const;
00091 
00092 };
00093 
00094 // Serialization routines
00095 QDataStream& operator<<(QDataStream& out, const StelVertexArray&);
00096 QDataStream& operator>>(QDataStream& in, StelVertexArray&);
00097 
00098 template<class Func>
00099 Func StelVertexArray::foreachTriangle(Func func) const
00100 {
00101     // Here we just dispach the method into one of the 4 possible cases
00102     bool textured = isTextured();
00103     bool useIndice = isIndexed();
00104 
00105     if (textured)
00106         if (useIndice)
00107             return specForeachTriangle<true, true, Func>(func);
00108         else
00109             return specForeachTriangle<true, false, Func>(func);
00110     else
00111         if (useIndice)
00112             return specForeachTriangle<false, true, Func>(func);
00113         else
00114             return specForeachTriangle<false, false, Func>(func);
00115 }
00116 
00117 template<bool T, bool I, class Func>
00118 Func StelVertexArray::specForeachTriangle(Func func) const
00119 {
00120     switch (primitiveType)
00121     {
00122         case StelVertexArray::Triangles:
00123             Q_ASSERT(vertex.size() % 3 == 0);
00124             for (int i = 0; i < vertex.size(); i += 3)
00125             {
00126                 func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
00127                      specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
00128                      specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
00129             }
00130             break;
00131         case StelVertexArray::TriangleFan:
00132         {
00133             const Vec3d* v0 = specVertexAt<I>(0);
00134             const Vec2f* t0 = specTexCoordAt<T, I>(0);
00135             unsigned int i0 = specIndiceAt<I>(0);
00136             for (int i = 1; i < vertex.size() - 1; ++i)
00137             {
00138                 func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
00139                      t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
00140                      i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
00141             }
00142             break;
00143         }
00144         case StelVertexArray::TriangleStrip:
00145         {
00146             for (int i = 2; i < vertex.size(); ++i)
00147             {
00148                 if (i % 2 == 0)
00149                     func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
00150                          specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
00151                          specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
00152                 else
00153                     func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
00154                          specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
00155                          specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
00156             }
00157             break;
00158         }
00159         default:
00160             Q_ASSERT_X(0, Q_FUNC_INFO, "unsuported primitive type");
00161     }
00162     return func;
00163 }
00164 
00165 
00166 #endif // __STELVERTEXARRAY_HPP__