OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SphereModel.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2012-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "SphereModel.h"
22 #include "Platform.h"
23 #include "Mathematics.h"
24 
25 #include <cstdlib>
26 #include <cmath>
27 #include <cassert>
28 
29 namespace MaliSDK
30 {
31  void SphereModel::getPointRepresentation(const float radius, const int numberOfSamples, int* numberOfCoordinates, float** coordinates)
32  {
33  /*
34  * Sphere vertices are created according to rule:
35  * Create a circle at north pole of the sphere, consisting of numberOfSample points.
36  * Create following circles, ending at south pole of sphere. The sphere now consists of numberOfSample circles.
37  * Theta value (indicating longitude) runs from 0 to 2*M_PI.
38  * Radius value (indicating latitude) runs from -radius to radius.
39  */
40 
41  /* Check if parameters have compatibile values. */
42  if (radius <= 0.0f)
43  {
44  LOGE("radius value has to be greater than zero.");
45 
46  return;
47  }
48 
49  if (numberOfSamples <= 0)
50  {
51  LOGE("numberOfSamples value has to be greater than zero.");
52 
53  return;
54  }
55  if (coordinates == NULL)
56  {
57  LOGE("Cannot use null pointer while calculating coordinates.");
58 
59  return;
60  }
61 
62  /* Maximum value of an error (used to compare float values). */
63  const float epsilon = 0.001f;
64  /* Index of an array we will put new point coordinates at. */
65  int indexOfSphereArray = 0;
66  /* Maximum longitude. */
67  float maxTheta = (2.0f * M_PI);
68  /* Value of longitude step. */
69  float thetaStep = maxTheta / float(numberOfSamples);
70  /* Value of latitude step. */
71  float radiusStep = (2 * radius) / float(numberOfSamples-1);
72  /* Index of longitude loop. */
73  int thetaIndex = 0;
74  /* Index of latitude loop. */
75  int radiusIndex = 0;
76  /* Number of coordinates which a sphere consists of. Each point (which a sphere consists of) consists of 3 coordinates: x, y, z. */
77  const int numberOfSphereCoordinates = numberOfSamples * numberOfSamples * 3;
78 
79  /* Allocate memory for result array. */
80  *coordinates = (float*) malloc (numberOfSphereCoordinates * sizeof(float));
81 
82  if (*coordinates == NULL)
83  {
84  LOGE("Could not allocate memory for result array.");
85 
86  return;
87  }
88 
89  /* Loop through circles from north to south. */
90  for (float r = -radius;
91  r < radius + epsilon;
92  r = -radius + radiusIndex * radiusStep)
93  {
94  thetaIndex = 0;
95 
96  /* Protect against rounding errors.. */
97  if (r > radius)
98  {
99  r = radius;
100  }
101 
102  /* Loop through all points of the circle. */
103  for (float theta = 0.0f;
104  theta < maxTheta;
105  theta = thetaIndex * thetaStep)
106  {
107  /* Compute x, y and z coordinates for the considered point. */
108  float x = sqrt((radius * radius) - (r * r)) * cosf(theta);
109  float y = sqrt((radius * radius) - (r * r)) * sinf(theta);
110  float z = r;
111 
112  (*coordinates)[indexOfSphereArray] = x;
113  indexOfSphereArray++;
114 
115  (*coordinates)[indexOfSphereArray] = y;
116  indexOfSphereArray++;
117 
118  (*coordinates)[indexOfSphereArray] = z;
119  indexOfSphereArray++;
120 
121  thetaIndex ++;
122  }
123 
124  radiusIndex ++;
125  }
126 
127  if (numberOfCoordinates != NULL)
128  {
129  *numberOfCoordinates = numberOfSphereCoordinates;
130  }
131  }
132 
133  void SphereModel::getTriangleRepresentation(const float radius, const int numberOfSamples, int* numberOfCoordinates, float** coordinates)
134  {
135  /* Check if parameters have compatibile values. */
136  if (radius <= 0.0f)
137  {
138  LOGE("radius value has to be greater than zero.");
139 
140  return;
141  }
142 
143  if (numberOfSamples <= 0)
144  {
145  LOGE("numberOfSamples value has to be greater than zero.");
146 
147  return;
148  }
149  if (coordinates == NULL)
150  {
151  LOGE("Cannot use null pointer while calculating coordinates.");
152 
153  return;
154  }
155  /* Array holding coordinates of points which a sphere consists of. */
156  float* pointCoordinates = NULL;
157  /* Current index used for accessing coordinates array. */
158  int sphereTriangleCoordinateIndex = 0;
159  /* Index of current loop iteration. */
160  int iterationIndex = 1;
161  /* There are 18 coordinates created in one loop: 3 coordinates * 3 triangle vertices * 2 triangles. */
162  int numberOfCoordinatesCreatedInOneLoop = 18;
163  /* Number of coordinates of all triangles which a sphere consists of.
164  * (numberOfSamples - 1) - for each circle (excluding last one)
165  * numberOfSamples - for each point on a single circle
166  * 2 - number of triangles that start at given point
167  * 3 - number of points that make up a triangle
168  * 3 - coordinates per each point.
169  */
170  const int numberOfSphereTriangleCoordinates = (numberOfSamples - 1) * numberOfSamples * 2 * 3 * 3;
171 
172  /* Compute coordinates of points which make up a sphere. */
173  getPointRepresentation(radius, numberOfSamples, NULL, &pointCoordinates);
174 
175  if (pointCoordinates == NULL)
176  {
177  LOGE("Could not get coordinates of points which make up a sphere.");
178  return;
179  }
180 
181  *coordinates = (float*) malloc (numberOfSphereTriangleCoordinates * sizeof(float));
182 
183  if (*coordinates == NULL)
184  {
185  LOGE("Could not allocate memory for result array.");
186  return;
187  }
188 
189  /* Each point has 3 coordinates: x, y, z. */
190  for (int pointIndex = 0;
191  pointIndex < (numberOfSphereTriangleCoordinates / numberOfCoordinatesCreatedInOneLoop) * 3;
192  pointIndex += 3)
193  {
194  /* First triangle. ==> */
195 
196  /* Building of a triangle is started from point at index described by pointIndex.
197  * Values of x, y and z coordinates are written one after another in pointCoordinates array starting at index of point value.
198  */
199  /* Coordinate x. */
200  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex];
201  sphereTriangleCoordinateIndex++;
202  /* Coordinate y. */
203  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 1];
204  sphereTriangleCoordinateIndex++;
205  /* Coordinate z. */
206  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 2];
207  sphereTriangleCoordinateIndex++;
208 
209  /* Check if this is the last point of circle. */
210  if ((iterationIndex % numberOfSamples) == 0 )
211  {
212  /* Second point of triangle.
213  * If this is the last point lying on a circle,
214  * second point that makes up a triangle is the point with coordinates taken from the first point lying on current circle.
215  * According to example above: the second point for first triangle starting at point D1 (last point on a current circle) is point A1.
216  * Index (to receive x coordinate): [point - 3 * (numberOfSamples)] stands for x coordinate of point D0 (corresponding point from previous circle),
217  * [+ 3] stands for next point (first point of current circle - A1).
218  */
219  /* Coordinate x. */
220  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex - 3 * (numberOfSamples) + 3];
221  sphereTriangleCoordinateIndex++;
222  /* Coordinate y. */
223  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex - 3 * (numberOfSamples) + 3 + 1];
224  sphereTriangleCoordinateIndex++;
225  /* Coordinate z. */
226  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex - 3 * (numberOfSamples) + 3 + 2];
227  sphereTriangleCoordinateIndex++;
228 
229  /* Third point of triangle.
230  * If this is the last point lying on a circle,
231  * third point that makes up a triangle is the point with coordinates taken from the first point lying on next circle.
232  * According to example above: the third point for first triangle starting at point D1 (last point on a current circle) is point A2.
233  * Index (to receive x coordinate): [point + 3] stands for x coordinate of point A2 (first point on next circle).
234  */
235  /* Coordinate x. */
236  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3];
237  sphereTriangleCoordinateIndex++;
238  /* Coordinate y. */
239  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 1];
240  sphereTriangleCoordinateIndex++;
241  /* Coordinate z. */
242  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 2];
243  sphereTriangleCoordinateIndex++;
244  }
245  else
246  {
247  /* Second point of triangle.
248  * If this is not the last point lying on a circle,
249  * second point that makes up a triangle is the point with coordinates taken from the next point lying on current circle.
250  * According to example above: the second point for first triangle starting at (for example) point A1 (not last point on a circle) is point B1.
251  * Index (to receive x coordinate): [point + 3] stands for x coordinate of point B1 (next point in array).
252  */
253  /* Coordinate x. */
254  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3];
255  sphereTriangleCoordinateIndex++;
256  /* Coordinate y. */
257  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 1];
258  sphereTriangleCoordinateIndex++;
259  /* Coordinate z. */
260  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 2];
261  sphereTriangleCoordinateIndex++;
262 
263  /* Third point of triangle.
264  * If this is not the last point lying on a circle,
265  * third point that makes up a triangle is the point with coordinates taken from the next from corresponding point lying on next circle.
266  * According to example above: the third point for first triangle starting at (for example) point A1 (not last point on a circle) is point B2.
267  * Index (to receive x coordinate): [point + numberOfSamples * 3] stands for x coordinate of point A2 (corresponding point lying on next circle),
268  * [+ 3] stands for nex point on that circle - B2.
269  */
270  /* Coordinate x. */
271  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + numberOfSamples * 3 + 3];
272  sphereTriangleCoordinateIndex++;
273  /* Coordinate y. */
274  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + numberOfSamples * 3 + 3 + 1];
275  sphereTriangleCoordinateIndex++;
276  /* Coordinate z. */
277  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + numberOfSamples * 3 + 3 + 2];
278  sphereTriangleCoordinateIndex++;
279  }
280  /* <== First triangle. */
281 
282  /* Second triangle. ==> */
283 
284  /* Building of a triangle is started from point at index described by pointIndex.
285  * Values of x, y and z coordinates are written one after another in pointCoordinates array starting at index of point value.
286  */
287  /* Coordinate x. */
288  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex];
289  sphereTriangleCoordinateIndex++;
290  /* Coordinate y. */
291  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 1];
292  sphereTriangleCoordinateIndex++;
293  /* Coordinate z. */
294  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 2];
295  sphereTriangleCoordinateIndex++;
296 
297  /* Check if this is a last point of circle. */
298  if ((iterationIndex % numberOfSamples) == 0 )
299  { /* Second point of triangle.
300  * If this is the last point lying on a circle,
301  * second point that makes up a triangle is the point with coordinates taken from the first point lying on next circle.
302  * According to example above: the second point for first triangle starting at point D1 (last point on a current circle) is point A2.
303  * Index (to receive x coordinate): [point + 3] stands for x coordinate of point A2 (first point on next circle).
304  */
305  /* Coordinate x. */
306  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3];
307  sphereTriangleCoordinateIndex++;
308  /* Coordinate y. */
309  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 1];
310  sphereTriangleCoordinateIndex++;
311  /* Coordinate z. */
312  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 + 2];
313  sphereTriangleCoordinateIndex++;
314  }
315  else
316  {
317  /* Second point of triangle.
318  * If this is not the last point lying on a circle,
319  * second point that makes up a triangle is the point with coordinates taken from the next from corresponding point lying on next circle.
320  * According to example above: the second point for first triangle starting at (for example) point A1 (not last point on a circle) is point B2.
321  * Index (to receive x coordinate): [point + numberOfSamples * 3] stands for x coordinate of point A2 (corresponding point lying on next circle),
322  * [+ 3] stands for nex point on that circle - B2.
323  */
324  /* Coordinate x. */
325  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 * numberOfSamples + 3];
326  sphereTriangleCoordinateIndex++;
327  /* Coordinate y. */
328  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 * numberOfSamples + 3 + 1];
329  sphereTriangleCoordinateIndex++;
330  /* Coordinate z. */
331  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 * numberOfSamples + 3 + 2];
332  sphereTriangleCoordinateIndex++;
333  }
334 
335  /* Third point of triangle that makes up a triangle is the point with coordinates taken from the corresponding point lying on next circle.
336  * According to example above: the third point for second triangle starting at point A1 (for example) is point A2.
337  * Index (to receive x coordinate): [point + 3 * (numberOfSamples)] stands for x coordinate of point A2 (corresponding point from next circle).
338  */
339  /* Coordinate x. */
340  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 * numberOfSamples];
341  sphereTriangleCoordinateIndex++;
342  /* Coordinate y. */
343  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 *numberOfSamples + 1];
344  sphereTriangleCoordinateIndex++;
345  /* Coordinate z. */
346  (*coordinates)[sphereTriangleCoordinateIndex] = pointCoordinates[pointIndex + 3 * numberOfSamples + 2];
347  sphereTriangleCoordinateIndex++;
348 
349  /* <== Second triangle. */
350 
351  iterationIndex++;
352  }
353 
354  if (numberOfCoordinates != NULL)
355  {
356  *numberOfCoordinates = numberOfSphereTriangleCoordinates;
357  }
358 
359  /* Deallocate memory. */
360  free(pointCoordinates);
361  pointCoordinates = NULL;
362  }
363 
364 
365 
366 }
static void getTriangleRepresentation(const float radius, const int numberOfSamples, int *numberOfCoordinates, float **coordinates)
Create triangular representation of a sphere.
GLboolean r
Definition: gl2ext.h:306
static void getPointRepresentation(const float radius, const int numberOfSamples, int *numberOfCoordinates, float **coordinates)
Compute coordinates of points which make up a sphere.
Definition: SphereModel.cpp:31
GLfloat GLfloat f
Definition: gl2ext.h:2707
int numberOfSphereTriangleCoordinates
Definition: Native.cpp:75
#define M_PI
The value of pi.
Definition: Mathematics.h:37
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
int numberOfSamples
Definition: AntiAlias.cpp:66
#define LOGE(...)
Definition: AstcTextures.h:30
precision highp float
Definition: hiz_cull.cs:37
GLint y
Definition: gl2ext.h:179