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 private:
00071
00072
00073
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
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
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__