00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00030 enum StelPrimitiveType
00031 {
00032 Points = 0x0000,
00033 Lines = 0x0001,
00034 LineLoop = 0x0002,
00035 LineStrip = 0x0003,
00036 Triangles = 0x0004,
00037 TriangleStrip = 0x0005,
00038 TriangleFan = 0x0006
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
00074
00075
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
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__