reprap: Compatibility with OSX
[simavr] / examples / shared / libc3 / src / c3geometry.c
1 /*
2         c3geometry.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr 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         simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include "c3object.h"
24 #include "c3context.h"
25 #include "c3driver_geometry.h"
26 #include "c3driver_context.h"
27
28 static void
29 _c3geometry_dispose(
30                 c3geometry_p  g,
31                 const struct c3driver_geometry_t *d)
32 {
33         /*
34          * If we're still attached to an object, detach
35          */
36         if (g->object) {
37                 for (int oi = 0; oi < g->object->geometry.count; oi++)
38                         if (g->object->geometry.e[oi] == g) {
39                                 c3geometry_array_delete(&g->object->geometry, oi, 1);
40                                 c3object_set_dirty(g->object, true);
41                                 break;
42                         }
43                 g->object = NULL;
44         }
45         str_free(g->name);
46         c3vertex_array_free(&g->vertice);
47         c3vertex_array_free(&g->projected);
48         c3tex_array_free(&g->textures);
49         c3colorf_array_free(&g->colorf);
50         free(g);
51 //      C3_DRIVER_INHERITED(g, d, dispose);
52 }
53
54 static void
55 _c3geometry_project(
56                 c3geometry_p g,
57                 const struct c3driver_geometry_t *d,
58                 c3mat4p m)
59 {
60         if (g->vertice.count) {
61                 c3vertex_array_realloc(&g->projected, g->vertice.count);
62                 g->projected.count = g->vertice.count;
63                 for (int vi = 0; vi < g->vertice.count; vi++) {
64                         g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
65                         if (vi == 0)
66                                 g->bbox.min = g->bbox.max = g->projected.e[vi];
67                         else {
68                                 g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
69                                 g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
70                         }
71                 }
72         }
73
74         if (g->object && g->object->context)
75                 C3_DRIVER(g->object->context, geometry_project, g, m);
76         g->dirty = 0;
77 //      C3_DRIVER_INHERITED(g, d, project);
78 }
79
80 static void
81 _c3geometry_draw(
82                 c3geometry_p g,
83                 const struct c3driver_geometry_t *d)
84 {
85         if (g->object && g->object->context)
86                 C3_DRIVER(g->object->context, geometry_draw, g);
87 //      C3_DRIVER_INHERITED(g, d, draw);
88 }
89
90 const  c3driver_geometry_t c3geometry_driver = {
91         .dispose = _c3geometry_dispose,
92         .project = _c3geometry_project,
93         .draw = _c3geometry_draw,
94 };
95
96 c3geometry_p
97 c3geometry_new(
98                 c3geometry_type_t type,
99                 c3object_p o /* = NULL */)
100 {
101         c3geometry_p res = malloc(sizeof(c3geometry_t));
102         return c3geometry_init(res, type, o);
103 }
104
105 c3geometry_p
106 c3geometry_init(
107                 c3geometry_p g,
108                 c3geometry_type_t type,
109                 struct c3object_t * o /* = NULL */)
110 {
111         memset(g, 0, sizeof(*g));
112         static const c3driver_geometry_t * list[] = {
113                         &c3geometry_driver, NULL,
114         };
115         g->driver = list;
116         g->type = type;
117         g->dirty = 1;
118         if (o)
119                 c3object_add_geometry(o, g);
120         return g;
121 }
122
123 c3driver_geometry_p
124 c3geometry_get_custom(
125                 c3geometry_p g )
126 {
127         if (g->custom)
128                 return (c3driver_geometry_p)g->driver[0];
129         int cnt = 0;
130         for (int di = 0; g->driver[di]; di++)
131                 cnt++;
132         c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
133         memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
134         newd[0] = malloc(sizeof(c3driver_geometry_t));
135         memset(newd[0], 0, sizeof(c3driver_geometry_t));
136         g->custom = 1;
137         g->driver = (typeof(g->driver))newd;
138         return newd[0];
139 }
140
141 void
142 c3geometry_dispose(
143                 c3geometry_p g)
144 {
145         C3_DRIVER(g, dispose);
146 }
147
148 void
149 c3geometry_project(
150                 c3geometry_p g,
151                 c3mat4p m)
152 {
153         if (!g->dirty)
154                 return;
155         C3_DRIVER(g, project, m);
156 }
157
158 void
159 c3geometry_draw(
160                 c3geometry_p g )
161 {
162         C3_DRIVER(g, draw);
163 }
164
165