5a8db4ceb8ba9257657ddcf6c1e91701674d2c0c
[simavr] / examples / shared / libc3 / src / c3sphere.c
1 /*
2         c3sphere.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of libc3.
7
8         libc3 is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         libc3 is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with libc3.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include <math.h>
24 #include "c3geometry.h"
25 #include "c3sphere.h"
26
27 c3geometry_p
28 c3sphere_uv(
29                 struct c3object_t * parent,
30                 c3vec3 center,
31                 c3f radius,
32                 int rings,
33                 int sectors )
34 {
35         float const R = 1. / (float) (rings - 1);
36         float const S = 1. / (float) (sectors - 1);
37
38         c3geometry_p g = c3geometry_new(c3geometry_type(C3_SPHERE_TYPE, 0), parent);
39
40         c3vertex_array_realloc(&g->vertice, rings * sectors);
41         c3vertex_array_realloc(&g->normals, rings * sectors);
42         c3tex_array_realloc(&g->textures, rings * sectors);
43         c3indices_array_realloc(&g->indices, rings * sectors * 6);
44
45         for (int r = 0; r < rings; r++)
46                 for (int s = 0; s < sectors; s++) {
47                         float const y = sin(-M_PI_2 + M_PI * r * R);
48                         float const x = cos(2 * M_PI * s * S) * sin(M_PI * r * R);
49                         float const z = sin(2 * M_PI * s * S) * sin(M_PI * r * R);
50
51                         c3tex_array_add(&g->textures, c3vec2f(s * S, r * R));
52                         c3vertex_array_add(&g->vertice,
53                                         c3vec3_add(center, c3vec3f(x * radius, y * radius, z * radius)));
54                         c3vertex_array_add(&g->normals, c3vec3_normalize(c3vec3f(x, y, z)));
55                 }
56
57         for (int r = 0; r < rings - 1; r++)
58                 for (int s = 0; s < sectors - 1; s++) {
59                         uint16_t i[6] = {
60                                 r * sectors + (s + 1), r * sectors + s, (r + 1) * sectors + (s + 1),
61                                 (r + 1) * sectors + (s + 1), r * sectors + s, (r + 1) * sectors + s,
62                         };
63                         c3indices_array_insert(&g->indices, g->indices.count, i, 6);
64                 }
65         return g;
66 }
67