gitignore: Updated
[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         /* let the context driver have a chance to clear it's own stuff */
46         if (g->object && g->object->context)
47                 C3_DRIVER(g->object->context, geometry_dispose, g);
48         str_free(g->name);
49         c3vertex_array_free(&g->vertice);
50         c3vertex_array_free(&g->projected);
51         c3tex_array_free(&g->textures);
52         c3colorf_array_free(&g->colorf);
53         free(g);
54 //      C3_DRIVER_INHERITED(g, d, dispose);
55 }
56
57 static void
58 _c3geometry_project(
59                 c3geometry_p g,
60                 const struct c3driver_geometry_t *d,
61                 c3mat4p m)
62 {
63         if (g->vertice.count) {
64                 c3vertex_array_realloc(&g->projected, g->vertice.count);
65                 g->projected.count = g->vertice.count;
66                 for (int vi = 0; vi < g->vertice.count; vi++) {
67                         g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
68                         if (vi == 0)
69                                 g->bbox.min = g->bbox.max = g->projected.e[vi];
70                         else {
71                                 g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
72                                 g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
73                         }
74                 }
75         }
76
77         if (g->object && g->object->context)
78                 C3_DRIVER(g->object->context, geometry_project, g, m);
79         g->dirty = 0;
80 //      C3_DRIVER_INHERITED(g, d, project);
81 }
82
83 static void
84 _c3geometry_draw(
85                 c3geometry_p g,
86                 const struct c3driver_geometry_t *d)
87 {
88         if (g->object && g->object->context)
89                 C3_DRIVER(g->object->context, geometry_draw, g);
90 //      C3_DRIVER_INHERITED(g, d, draw);
91 }
92
93 const  c3driver_geometry_t c3geometry_driver = {
94         .dispose = _c3geometry_dispose,
95         .project = _c3geometry_project,
96         .draw = _c3geometry_draw,
97 };
98
99 c3geometry_p
100 c3geometry_new(
101                 c3geometry_type_t type,
102                 c3object_p o /* = NULL */)
103 {
104         c3geometry_p res = malloc(sizeof(c3geometry_t));
105         return c3geometry_init(res, type, o);
106 }
107
108 c3geometry_p
109 c3geometry_init(
110                 c3geometry_p g,
111                 c3geometry_type_t type,
112                 struct c3object_t * o /* = NULL */)
113 {
114         memset(g, 0, sizeof(*g));
115         static const c3driver_geometry_t * list[] = {
116                         &c3geometry_driver, NULL,
117         };
118         g->driver = list;
119         g->type = type;
120         g->dirty = 1;
121         if (o)
122                 c3object_add_geometry(o, g);
123         return g;
124 }
125
126 c3driver_geometry_p
127 c3geometry_get_custom(
128                 c3geometry_p g )
129 {
130         if (g->custom)
131                 return (c3driver_geometry_p)g->driver[0];
132         int cnt = 0;
133         for (int di = 0; g->driver[di]; di++)
134                 cnt++;
135         c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
136         memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
137         newd[0] = malloc(sizeof(c3driver_geometry_t));
138         memset(newd[0], 0, sizeof(c3driver_geometry_t));
139         g->custom = 1;
140         g->driver = (typeof(g->driver))newd;
141         return newd[0];
142 }
143
144 void
145 c3geometry_dispose(
146                 c3geometry_p g)
147 {
148         C3_DRIVER(g, dispose);
149 }
150
151 void
152 c3geometry_project(
153                 c3geometry_p g,
154                 c3mat4p m)
155 {
156         if (!g->dirty)
157                 return;
158         C3_DRIVER(g, project, m);
159 }
160
161 void
162 c3geometry_draw(
163                 c3geometry_p g )
164 {
165         C3_DRIVER(g, draw);
166 }
167
168