Omnidome
Fulldome Mapping Software Toolkit
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.h
Go to the documentation of this file.
1 /* Copyright (c) 2014-2015 "Omnidome" by cr8tr
2  * Dome Mapping Projection Software (http://omnido.me).
3  * Omnidome was created by Michael Winkelmann aka Wilston Oreo (@WilstonOreo)
4  *
5  * This file is part of Omnidome.
6  *
7  * Omnidome is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Affero General Public License for more details.
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef OMNI_CANVAS_UTIL_HPP_
21 #define OMNI_CANVAS_UTIL_HPP_
22 
23 #include <QVector3D>
24 #include <QPointF>
25 
26 namespace omni {
27  namespace canvas {
28  namespace util {
29  /// Generate a cone with vertices and indices
30  template<typename VERTICES, typename INDICES>
31  static void generateCone(size_t _slices,
32  float _zTop,
33  float _zBottom,
34  float _radius,
35  VERTICES& _vertices,
36  INDICES& indices)
37  {
38  size_t _startIndex = _vertices.size();
39 
40  QVector3D _p(0, 0, _zTop);
41 
42  _vertices.emplace_back(_p, _p.normalized(), QPointF(0.5, 0.0));
43 
44  for_each_circle_point(_slices, _radius, [&](size_t i, const QPointF& _p2)
45  {
46  _p = QVector3D(_p2.x(), _p2.y(), _zBottom);
47  QVector3D _normal = _p.normalized();
48  _vertices.emplace_back(_p, _normal,
49  QPointF(float(i) / _slices,
50  acos(_normal.z()) / M_PI));
51 
52  if (_zTop > _zBottom)
53  {
54  indices.push_back(_startIndex);
55  indices.push_back(_startIndex + 1 + i);
56  indices.push_back(_startIndex + 1 + (i + 1) % _slices);
57  } else
58  {
59  indices.push_back(_startIndex + 1 + (i + 1) % _slices);
60  indices.push_back(_startIndex + 1 + i);
61  indices.push_back(_startIndex);
62  }
63  });
64  }
65 
66  /// Generate a stack with top and bottom radius
67  template<typename VERTICES, typename INDICES>
68  static void generateSphereStack(size_t _slices,
69  float _zTop, float _zBottom,
70  float _topRadius, float _bottomRadius,
71  VERTICES& _vertices, INDICES& indices)
72  {
73  size_t _startIndex = _vertices.size();
74 
75  for (size_t i = 0; i <= _slices; ++i)
76  {
77  float _m = 2.0 * M_PI * float(i) / _slices;
78  float _cos = cos(_m), _sin = sin(_m);
79  QVector3D _top(_cos * _topRadius, _sin * _topRadius, _zTop);
80  QVector3D _bottom(_cos * _bottomRadius, _sin * _bottomRadius, _zBottom);
81  QVector3D _normalTop(_top.normalized());
82  QVector3D _normalBottom(_bottom.normalized());
83  _vertices.emplace_back(_top, _normalTop,
84  QPointF(float(i) / _slices,
85  acos(_normalTop.z()) / M_PI));
86  _vertices.emplace_back(_bottom, _normalBottom,
87  QPointF(float(i) / _slices,
88  acos(_normalBottom.z()) / M_PI));
89  }
90 
91  for (size_t i = 0; i < _slices; ++i)
92  {
93  /// Top triangle
94  indices.push_back(_startIndex + 2 * i);
95  indices.push_back(_startIndex + 2 * i + 1);
96  indices.push_back(_startIndex + 2 * (i + 1));
97 
98  /// Bottom triangle
99  indices.push_back(_startIndex + 2 * i + 1);
100  indices.push_back(_startIndex + 2 * (i + 1) + 1);
101  indices.push_back(_startIndex + 2 * (i + 1));
102  }
103  }
104 
105  /// Generate a sphere
106  template<typename VERTICES, typename INDICES>
107  static void generateSphere(size_t _stacks,
108  size_t _slices,
109  VERTICES& _vertices,
110  INDICES& indices)
111  {
112  // If there are M lines of latitude (horizontal) and
113  // N lines of longitude (vertical), then put dots at
114  // (x, y, z) = (sin(Pi * m/M) cos(2Pi * n/N), sin(Pi * m/M) sin(2Pi *
115  // n/N), cos(Pi * m/M))
116  auto stackRadius = [&_stacks](size_t index)
117  {
118  return sin(M_PI * float(index) / _stacks);
119  };
120  auto stackPos = [&_stacks](size_t index)
121  {
122  return cos(M_PI * float(index) / _stacks);
123  };
124 
125  /// Top cone
126  generateCone(_slices, 1.0, stackPos(1), stackRadius(1), _vertices,
127  indices);
128 
129  /// Bottom cone
130  generateCone(_slices, -1.0, stackPos(_stacks - 1), stackRadius(
131  1), _vertices, indices);
132 
133  for (size_t i = 1; i < _stacks - 1; ++i)
134  {
135  generateSphereStack(_slices,
136  stackPos(i), stackPos(i + 1),
137  stackRadius(i), stackRadius(i + 1),
138  _vertices, indices);
139  }
140  }
141 
142  /// Generate bottom cut off sphere
143  template<typename VERTICES, typename INDICES>
144  static void generateSphereUpper(size_t _stacks,
145  size_t _slices,
146  float _bottom,
147  VERTICES& _vertices,
148  INDICES& indices)
149  {
150  /// Top cone
151  auto stackRadius = [&_stacks](size_t index)
152  {
153  return sin(M_PI * float(index) / _stacks);
154  };
155  auto stackPos = [&_stacks](size_t index)
156  {
157  return cos(M_PI * float(index) / _stacks);
158  };
159 
160  generateCone(_slices, 1.0, stackPos(1), stackRadius(1), _vertices,
161  indices);
162 
163  for (size_t i = 1; i < _stacks - 1; ++i)
164  {
165  float _stackPos = stackPos(i + 1);
166 
167  if (_stackPos < _bottom) continue;
168  generateSphereStack(_slices,
169  stackPos(i), stackPos(i + 1),
170  stackRadius(i), stackRadius(i + 1),
171  _vertices, indices);
172  }
173  }
174  }
175  }
176 }
177 
178 #endif /* OMNI_CANVAS_UTIL_HPP_ */
static void generateSphereUpper(size_t _stacks, size_t _slices, float _bottom, VERTICES &_vertices, INDICES &indices)
Generate bottom cut off sphere.
Definition: util.h:144
static void generateSphereStack(size_t _slices, float _zTop, float _zBottom, float _topRadius, float _bottomRadius, VERTICES &_vertices, INDICES &indices)
Generate a stack with top and bottom radius.
Definition: util.h:68
static void generateCone(size_t _slices, float _zTop, float _zBottom, float _radius, VERTICES &_vertices, INDICES &indices)
Generate a cone with vertices and indices.
Definition: util.h:31
void for_each_circle_point(size_t _numVertices, float _radius, F _f)
Definition: util.h:44
static void generateSphere(size_t _stacks, size_t _slices, VERTICES &_vertices, INDICES &indices)
Generate a sphere.
Definition: util.h:107