-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsphere.cpp
More file actions
104 lines (87 loc) · 2.95 KB
/
sphere.cpp
File metadata and controls
104 lines (87 loc) · 2.95 KB
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
#include "sphere.h"
#include <cmath>
#include <iostream>
#include <vector>
/** Three.js `SphereGeometry` (r162) - same vertex, normal, and index order. */
Sphere::Sphere(SphereDimensions const &dimensions, SphereParameters const ¶meters) : Mesh{}, dimensions{dimensions}, parameters{parameters}
{
createVertices();
computeFaces();
createMesh();
}
Sphere::~Sphere()
{
}
void Sphere::rebuildGeometry()
{
ClearMesh();
vertices.clear();
normals.clear();
faces.clear();
indices.clear();
createVertices();
computeFaces();
createMesh();
threeBSPDone = false;
}
void Sphere::createVertices()
{
widthSegments = std::max(3, parameters.widthSegments);
heightSegments = std::max(2, parameters.heightSegments);
float const radius = std::max(1e-4f, dimensions.radius);
float const phiStart = parameters.phiStart;
float const phiLength = parameters.phiLength;
float const thetaStart = parameters.thetaStart;
float const thetaLength = parameters.thetaLength;
float const thetaEnd = std::min(thetaStart + thetaLength, static_cast<float>(M_PI));
vertices.clear();
normals.clear();
indices.clear();
std::vector<std::vector<int>> grid;
int index = 0;
for (size_t iy = 0; iy <= static_cast<size_t>(heightSegments); ++iy)
{
std::vector<int> verticesRow;
float const v = static_cast<float>(iy) / static_cast<float>(heightSegments);
float uOffset = 0.0f;
if (iy == 0 && thetaStart == 0.0f)
uOffset = 0.5f / static_cast<float>(widthSegments);
else if (static_cast<int>(iy) == heightSegments && thetaEnd >= static_cast<float>(M_PI))
uOffset = -0.5f / static_cast<float>(widthSegments);
for (size_t ix = 0; ix <= static_cast<size_t>(widthSegments); ++ix)
{
float const u = static_cast<float>(ix) / static_cast<float>(widthSegments);
glm::vec3 vertex;
vertex.x = -radius * std::cos(phiStart + u * phiLength) * std::sin(thetaStart + v * thetaLength);
vertex.y = radius * std::cos(thetaStart + v * thetaLength);
vertex.z = radius * std::sin(phiStart + u * phiLength) * std::sin(thetaStart + v * thetaLength);
vertices.push_back(vertex);
glm::vec3 const normal = glm::normalize(vertex);
normals.push_back(normal);
verticesRow.push_back(index++);
}
grid.push_back(std::move(verticesRow));
}
for (size_t iy = 0; iy < static_cast<size_t>(heightSegments); ++iy)
{
for (size_t ix = 0; ix < static_cast<size_t>(widthSegments); ++ix)
{
int const a = grid[iy][ix + 1];
int const b = grid[iy][ix];
int const c = grid[iy + 1][ix];
int const d = grid[iy + 1][ix + 1];
if (iy != 0 || thetaStart > 0.0f)
{
indices.push_back(static_cast<unsigned int>(a));
indices.push_back(static_cast<unsigned int>(b));
indices.push_back(static_cast<unsigned int>(d));
}
if (static_cast<int>(iy) != heightSegments - 1 || thetaEnd < static_cast<float>(M_PI))
{
indices.push_back(static_cast<unsigned int>(b));
indices.push_back(static_cast<unsigned int>(c));
indices.push_back(static_cast<unsigned int>(d));
}
}
}
}