4 Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
6 This file is part of libc3.
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.
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.
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/>.
26 #include "c3context.h"
27 #include "c3driver_geometry.h"
28 #include "c3driver_context.h"
33 const struct c3driver_geometry_t *d)
36 * If we're still attached to an object, detach
39 for (int oi = 0; oi < g->object->geometry.count; oi++)
40 if (g->object->geometry.e[oi] == g) {
41 c3geometry_array_delete(&g->object->geometry, oi, 1);
42 c3object_set_dirty(g->object, true);
47 /* let the context driver have a chance to clear it's own stuff */
48 if (g->object && g->object->context)
49 C3_DRIVER(g->object->context, geometry_dispose, g);
51 c3vertex_array_free(&g->vertice);
52 c3vertex_array_free(&g->projected);
53 c3tex_array_free(&g->textures);
54 c3colorf_array_free(&g->colorf);
56 // C3_DRIVER_INHERITED(g, d, dispose);
62 const struct c3driver_geometry_t *d,
65 if (g->vertice.count) {
66 c3vertex_array_realloc(&g->projected, g->vertice.count);
67 g->projected.count = g->vertice.count;
68 for (int vi = 0; vi < g->vertice.count; vi++) {
69 g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
71 g->bbox.min = g->bbox.max = g->projected.e[vi];
73 g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
74 g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
79 if (g->object && g->object->context)
80 C3_DRIVER(g->object->context, geometry_project, g, m);
82 // C3_DRIVER_INHERITED(g, d, project);
88 const struct c3driver_geometry_t *d)
90 if (g->object && g->object->context)
91 C3_DRIVER(g->object->context, geometry_draw, g);
92 // C3_DRIVER_INHERITED(g, d, draw);
95 const c3driver_geometry_t c3geometry_driver = {
96 .dispose = _c3geometry_dispose,
97 .project = _c3geometry_project,
98 .draw = _c3geometry_draw,
103 c3geometry_type_t type,
104 c3object_p o /* = NULL */)
106 c3geometry_p res = malloc(sizeof(c3geometry_t));
107 return c3geometry_init(res, type, o);
113 c3geometry_type_t type,
114 struct c3object_t * o /* = NULL */)
116 memset(g, 0, sizeof(*g));
117 static const c3driver_geometry_t * list[] = {
118 &c3geometry_driver, NULL,
124 c3object_add_geometry(o, g);
129 c3geometry_get_custom(
133 return (c3driver_geometry_p)g->driver[0];
135 for (int di = 0; g->driver[di]; di++)
137 c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
138 memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
139 newd[0] = malloc(sizeof(c3driver_geometry_t));
140 memset(newd[0], 0, sizeof(c3driver_geometry_t));
142 g->driver = (typeof(g->driver))newd;
150 C3_DRIVER(g, dispose);
160 C3_DRIVER(g, project, m);
176 printf("%s Start geometry has %d vertices and %d indexes\n", __func__,
177 g->vertice.count, g->indices.count);
178 printf("%s Start geometry has %d normals and %d tex\n", __func__,
179 g->normals.count, g->textures.count);
181 c3f tolerance2 = tolerance * tolerance;
183 int in_index = g->indices.count;
184 int vcount = in_index ? in_index : g->vertice.count;
187 g->indices.count = 0;
188 while (input < vcount) {
189 int current = in_index ? g->indices.e[input] : input;
190 c3vec3 v = g->vertice.e[current];
191 c3vec3 n = g->normals.count ? g->normals.e[current] : c3vec3f(0,0,0);
192 c3vec3 np = c3vec3_polar(n); // normal in polar coord
195 for (int ci = 0; ci < output && oi == -1; ci++)
196 if (c3vec3_length2(c3vec3_sub(g->vertice.e[ci], v)) < tolerance2) {
197 if (g->normals.count) {
198 c3vec3 nc = g->normals.e[ci];
199 c3vec3 pc = c3vec3_polar(nc);
201 c3vec3 d = c3vec3_sub(np, pc);
202 while (d.n[0] <= -M_PI) d.n[0] += (2*M_PI);
203 while (d.n[1] <= -M_PI) d.n[1] += (2*M_PI);
205 if (fabs(d.n[0]) < normaltolerance &&
206 fabs(d.n[1]) < normaltolerance) {
208 // replace the compared normal with the 'merged' one
209 // that should hopefully trim it to the right direction
210 // somehow. Not perfect obviously
211 g->normals.e[ci] = c3vec3_add(n, nc);
218 g->vertice.e[output] = g->vertice.e[current];
219 if (g->textures.count)
220 g->textures.e[output] = g->textures.e[current];
221 if (g->normals.count)
222 g->normals.e[output] = n;
224 g->colorf.e[output] = g->colorf.e[current];
227 c3indices_array_add(&g->indices, oi);
230 g->vertice.count = output;
231 c3vertex_array_realloc(&g->vertice, output);
232 if (g->textures.count) {
233 g->textures.count = output;
234 c3tex_array_realloc(&g->textures, output);
236 if (g->normals.count) {
237 g->normals.count = output;
238 c3vertex_array_realloc(&g->normals, output);
239 for (int ni = 0; ni < output; ni++)
240 g->normals.e[ni] = c3vec3_normalize(g->normals.e[ni]);
242 if (g->colorf.count) {
243 g->colorf.count = output;
244 c3colorf_array_realloc(&g->colorf, output);
248 printf("%s end geometry has %d vertices and %d indexes\n", __func__,
249 g->vertice.count, g->indices.count);