~ubuntu-branches/debian/sid/stellarium/sid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Stellarium
 * Copyright (C) 2009 Fabien Chereau
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
 */

#ifndef __STELVERTEXARRAY_HPP__
#define __STELVERTEXARRAY_HPP__

#include "VecMath.hpp"

#include <QVector>
#include <QDebug>

struct StelVertexArray
{
	// TODO maybe merge this with StelPainter DrawingMode
	enum StelPrimitiveType
	{
		Points                      = 0x0000, // GL_POINTS
		Lines                       = 0x0001, // GL_LINES
		LineLoop                    = 0x0002, // GL_LINE_LOOP
		LineStrip                   = 0x0003, // GL_LINE_STRIP
		Triangles                   = 0x0004, // GL_TRIANGLES
		TriangleStrip               = 0x0005, // GL_TRIANGLE_STRIP
		TriangleFan                 = 0x0006  // GL_TRIANGLE_FAN
	};

	StelVertexArray(StelPrimitiveType pType=StelVertexArray::Triangles) : primitiveType(pType) {;}
	StelVertexArray(const QVector<Vec3d>& v, StelPrimitiveType pType=StelVertexArray::Triangles,const QVector<Vec2f>& t=QVector<Vec2f>(), const QVector<unsigned short> i=QVector<unsigned short>()) :
		vertex(v), texCoords(t), indices(i), primitiveType(pType) {;}

	//! OpenGL compatible array of 3D vertex to be displayed using vertex arrays.
	//! TODO, move to float? Most of the vectors are normalized, thus the precision is around 1E-45 using float
	//! which is enough (=2E-37 milli arcsec).
	QVector<Vec3d> vertex;
	//! OpenGL compatible array of edge flags to be displayed using vertex arrays.
	QVector<Vec2f> texCoords;
	//! OpenGL compatible array of vertex colors to be displayed using arrays. (GZ/NEW)
	//! The color (if exists) shall be multiplied with texture to modulate e.g. for extinction of Milky Way or other large items.
	QVector<Vec3f> colors;
	//! OpenGL compatible array of indices for the vertex and the textures
	QVector<unsigned short> indices;

	StelPrimitiveType primitiveType;

	bool isIndexed() const {return !indices.isEmpty();}

	bool isTextured() const {return !texCoords.isEmpty();}

	bool isColored() const {return !colors.isEmpty();}


	//! call a function for each triangle of the array.
	//! func should define the following method : // GZ NEW: colors
	//!     void operator() (const Vec3d* vertex[3], const Vec2f* tex[3], const Vec3f* colors[3], unsigned int indices[3])
	//! The method takes arrays of *pointers* as arguments because we can't assume the values are contiguous
	template<class Func>
	inline Func foreachTriangle(Func func) const;

	//! Create a copy of the array with all the triangles intersecting the projector discontinuity removed.
	StelVertexArray removeDiscontinuousTriangles(const class StelProjector* prj) const;

private:
	// Below we define a few methods that are templated to be optimized according to different types of VertexArray :
	// The template parameter <bool T> defines whether the array has a texture.
	// The template parameter <bool I> defines whether the array is indexed.
	// The template parameter <bool C> defines whether the array is colored. // NEW GZ
	template <bool I>
	const Vec3d* specVertexAt(int i) const {
		return &vertex.at(specIndiceAt<I>(i));
	}

	template <bool T, bool I>
	const Vec2f* specTexCoordAt(int i) const {
		return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;
	}

	// NEW GZ
	template <bool C, bool I>
	const Vec3f* specColorAt(int i) const {
		return C ? &colors.at(specIndiceAt<I>(i)) : NULL;
	}

	template<bool I>
	unsigned int specIndiceAt(unsigned int i) const {
		return I ? indices.at(i) : i;
	}

	template<bool T, bool I, bool C, class Func> // GZ added bool C
	inline Func specForeachTriangle(Func func) const;

};

// Serialization routines
QDataStream& operator<<(QDataStream& out, const StelVertexArray&);
QDataStream& operator>>(QDataStream& in, StelVertexArray&);

template<class Func>
Func StelVertexArray::foreachTriangle(Func func) const
{
	// Here we just dispatch the method into one of the 8 possible cases // GZ NEW: 8, not 4, cases
	bool textured = isTextured();
	bool colored  = isColored();
	bool useIndice = isIndexed();

	if (textured)
	{
		if (useIndice)
		{
			if (colored)
				return specForeachTriangle<true, true, true, Func>(func);
			else
				return specForeachTriangle<true, true, false, Func>(func);
		}
		else // not indiced
		{
			if (colored)
				return specForeachTriangle<true, false, true, Func>(func);
			else
				return specForeachTriangle<true, false, false, Func>(func);
		}
	}
	else // not textured
	{
		if (useIndice)
		{
			if (colored)
				return specForeachTriangle<false, true, true, Func>(func);
			else
				return specForeachTriangle<false, true, false, Func>(func);
		}
		else // not indiced
		{
			if (colored)
				return specForeachTriangle<false, false, true, Func>(func);
			else
				return specForeachTriangle<false, false, false, Func>(func);
		}
	}
	Q_ASSERT(0); // GZ. Just make sure...
}

template<bool T, bool I, bool C, class Func>
Func StelVertexArray::specForeachTriangle(Func func) const
{
	switch (primitiveType)
	{
		case StelVertexArray::Triangles:
			Q_ASSERT(vertex.size() % 3 == 0);
			for (int i = 0; i < vertex.size(); i += 3)
			{
				func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
					 specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
					 specColorAt<C, I>(i), specColorAt<C, I>(i+1), specColorAt<C, I>(i+2),
					 specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
			}
			break;
		case StelVertexArray::TriangleFan:
		{
			const Vec3d* v0 = specVertexAt<I>(0);
			const Vec2f* t0 = specTexCoordAt<T, I>(0);
			const Vec3f* c0 = specColorAt<C, I>(0);
			unsigned int i0 = specIndiceAt<I>(0);
			for (int i = 1; i < vertex.size() - 1; ++i)
			{
				func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
					 t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
					 c0, specColorAt<C, I>(i),    specColorAt<C, I>(i+1),
					 i0, specIndiceAt<I>(i),      specIndiceAt<I>(i+1));
			}
			break;
		}
		case StelVertexArray::TriangleStrip:
		{
			for (int i = 2; i < vertex.size(); ++i)
			{
				if (i % 2 == 0)
					func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
						 specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
						 specColorAt<C, I>(i-2), specColorAt<C, I>(i-1), specColorAt<C, I>(i),
						 specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
				else
					func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
						 specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
						 specColorAt<C, I>(i-1), specColorAt<C, I>(i-2), specColorAt<C, I>(i),
						 specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
			}
			break;
		}
		default:
			Q_ASSERT_X(0, Q_FUNC_INFO, "unsupported primitive type");
	}
	return func;
}


#endif // __STELVERTEXARRAY_HPP__