/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- unit
1 #include "mesh/SphereMesh.hpp"
2
3 using namespace std;
4 using namespace osg;
5
6 SphereMesh::SphereMesh()
7 { }
8
9 const tuple< const Vec3Array * const
10 , const DrawElementsUShort * const
11 , const Vec3Array * const
12 >
13 SphereMesh::unit(unsigned int points)
14 {
15 //points should always be even
16
17 // First check if sphere with the required number of points already exists.
18 auto result = spheres.find(points);
19 if(result != spheres.end()) { return result -> second; }
20
21 // If a sphere is not found then create, cache and return it.
22
23 unsigned int vertex_count = (points * points) / 2 - points + 2;
24 unsigned int triangle_count = 3 * points * points - 6 * points;
25
26 unsigned int vertex_index = 1;
27 unsigned int triangle_index = 0;
28
29 unsigned int i, j;
30 unsigned int alpha, beta;
31
32 float phi_delta = 2.0 * M_PI / points;
33 float theta_delta = 2.0 * M_PI / points;
34 float z;
35 float radius;
36
37 Vec3Array * vertices = new Vec3Array(vertex_count);
38 Vec3Array * normals = new Vec3Array(vertex_count);
39 DrawElementsUShort * indices = new DrawElementsUShort(GL_TRIANGLES, triangle_count);
40
41 // Excluding the topmost and bottommost vertices there will be n - 2 vertices
42 // So there will be (n - 2)/2 vertices per side
43 // There will be a angle delta of n/2 between each vertex.
44
45 (*vertices)[0] = (*normals)[0] = Vec3f(0.0f, 0.0f, 1.0f);
46
47 for(i = 1; i < points / 2; ++i)
48 {
49 z = cos( i * phi_delta);
50 radius = sin( i * phi_delta );
51 for(j = 0; j < points; ++j)
52 {
53 (*vertices)[vertex_index] =
54 (*normals)[vertex_index] =
55 Vec3f( radius * cos(j * theta_delta)
56 , radius * sin(j * theta_delta)
57 , z
58 );
59 ++vertex_index;
60 }
61 }
62
63 (*vertices)[vertex_index] =
64 (*normals)[vertex_index] = Vec3f(0.0f, 0.0f, -1.0f);
65
66 for(i = 0; i < points; ++i)
67 {
68 (*indices)[triangle_index] = 0;
69 (*indices)[triangle_index + 1] = i + 1;
70 (*indices)[triangle_index + 2] = i + 2;
71 triangle_index += 3;
72 }
73
74 (*indices)[triangle_index - 1] = 1;
75
76 for(i = 1; i < points / 2 - 1; ++i)
77 {
78 alpha = 1 + points * (i - 1);
79 beta = 1 + points * i;
80
81 for(j = 0; j < points; ++j)
82 {
83 (*indices)[triangle_index ] = alpha + j;
84 (*indices)[triangle_index + 1] = beta + j;
85 (*indices)[triangle_index + 2] = beta + j + 1;
86
87 (*indices)[triangle_index + 3] = alpha + j + 1;
88 (*indices)[triangle_index + 4] = alpha + j;
89 (*indices)[triangle_index + 5] = beta + j + 1;
90 triangle_index += 6;
91 }
92 (*indices)[triangle_index - 4] = beta;
93 (*indices)[triangle_index - 3] = alpha;
94 (*indices)[triangle_index - 1] = beta;
95 }
96
97 for(i = 0; i < points; ++i)
98 {
99 (*indices)[triangle_index ] = vertex_count - 1;
100 (*indices)[triangle_index + 1] = beta + i + 1;
101 (*indices)[triangle_index + 2] = beta + i;
102 triangle_index += 3;
103 }
104
105 (*indices)[triangle_index - 2] = beta;
106
107 auto insert_position = spheres.insert(make_pair( points
108 , make_tuple( vertices
109 , indices
110 , normals
111 )
112 )
113 );
114 return insert_position.first -> second;
115 }
116
117 Geometry *
118 SphereMesh::operator()( Vec3f center
119 , float radius
120 , unsigned int points
121 , const Vec4& color
122 )
123 {
124 Geometry * geometry = new Geometry();
125 operator()( center
126 , radius
127 , geometry
128 , points
129 , color
130 );
131 return geometry;
132 }
133
134 void
135 SphereMesh::operator()( Vec3f center
136 , float radius
137 , Geometry * geometry
138 , unsigned int points
139 , const Vec4& color
140 )
141 {
142 const auto arrays = unit(points);
143
144 const auto unit_vertices = get<0>(arrays);
145 const auto unit_indices = get<1>(arrays);
146 const auto unit_normals = get<2>(arrays);
147
148 Vec3Array * vertices = new Vec3Array(unit_vertices -> size());
149 Vec3Array * normals = new Vec3Array(*unit_normals);
150 DrawElementsUShort * indices = new DrawElementsUShort(*unit_indices);
151
152 std::transform( unit_vertices -> begin()
153 , unit_vertices -> end()
154 , vertices -> begin()
155 , [&](const Vec3f& vertex)
156 {
157 return vertex * radius + center;
158 }
159 );
160
161 geometry -> setVertexArray(vertices);
162 geometry -> setNormalArray(normals);
163 geometry -> setNormalBinding(Geometry::BIND_PER_VERTEX);
164 geometry -> addPrimitiveSet(indices);
165 Vec4Array * colors = new Vec4Array();
166 colors -> push_back(color); //color);
167 geometry -> setColorArray(colors);
168 geometry -> setColorBinding( osg::Geometry::BIND_OVERALL );
169 }