1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
26 /* create a new mesh */
27 mesh_t
*mesh_create(GLenum mode
)
29 mesh_t
*m
= malloc(sizeof(mesh_t
));
33 m
->v
= array_create(ARRAY_TYPE_FLOAT
);
36 m
->i
= array_create(ARRAY_TYPE_INT
);
44 m
->bounds
.max
.x
= 0.0;
45 m
->bounds
.max
.y
= 0.0;
46 m
->bounds
.max
.z
= 0.0;
47 m
->bounds
.min
.x
= 0.0;
48 m
->bounds
.min
.y
= 0.0;
49 m
->bounds
.min
.z
= 0.0;
55 void mesh_free(mesh_t
*m
)
72 glDeleteBuffers(1,&m
->vao
.vertices
);
74 glDeleteBuffers(1,&m
->vao
.normals
);
76 glDeleteBuffers(1,&m
->vao
.texcoords
);
78 glDeleteBuffers(1,&m
->vao
.indices
);
80 glDeleteVertexArrays(1,&m
->vao
.list
);
86 /* create a mesh for a material */
87 mesh_t
*mesh_create_material(material_t
*mat
)
89 mesh_t
*m
= mesh_create(GL_TRIANGLES
);
91 m
->t
= array_create(ARRAY_TYPE_FLOAT
);
92 m
->n
= array_create(ARRAY_TYPE_FLOAT
);
96 /* create a mesh for a colour */
97 mesh_t
*mesh_create_colour(colour_t
*c
)
99 mesh_t
*m
= mesh_create(GL_TRIANGLES
);
100 m
->col
= malloc(sizeof(colour_t
));
105 m
->n
= array_create(ARRAY_TYPE_FLOAT
);
109 /* duplicate a mesh */
110 mesh_t
*mesh_copy(mesh_t
*om
)
112 mesh_t
*m
= mesh_create(om
->mode
);
115 m
->v
= array_copy(om
->v
);
117 m
->n
= array_copy(om
->n
);
119 m
->t
= array_copy(om
->t
);
120 m
->i
= array_copy(om
->i
);
122 m
->option
= om
->option
;
127 /* push a vertex onto a mesh */
128 int mesh_push_point(mesh_t
*m
, v3_t
*v1
)
131 for (i
=0; i
<m
->v
->length
; i
+=3) {
133 v1
->x
== AFLOAT(m
->v
->data
,i
)
134 && v1
->y
== AFLOAT(m
->v
->data
,i
+1)
135 && v1
->z
== AFLOAT(m
->v
->data
,i
+2)
137 array_push_int(m
->i
,i
/3);
141 array_push_int(m
->i
,i
/3);
142 array_push_float(m
->v
,v1
->x
);
143 array_push_float(m
->v
,v1
->y
);
144 array_push_float(m
->v
,v1
->z
);
149 /* push a poly point onto a mesh */
150 int mesh_push_polypoint(mesh_t
*m
, v3_t
*v
, v2_t
*t
)
155 for (i
=0; (i
*3)<m
->v
->length
; i
++) {
159 v
->x
== AFLOAT(m
->v
->data
,vi
)
160 && v
->y
== AFLOAT(m
->v
->data
,vi
+1)
161 && v
->z
== AFLOAT(m
->v
->data
,vi
+2)
162 && t
->x
== AFLOAT(m
->t
->data
,ti
)
163 && t
->y
== AFLOAT(m
->t
->data
,ti
+1)
165 array_push_int(m
->i
,i
);
169 array_push_int(m
->i
,i
);
170 array_push_v3t(m
->v
,v
);
171 array_push_v2t(m
->t
,t
);
176 /* push a poly point with normal onto a mesh */
177 int mesh_push_polypoint_n(mesh_t
*m
, v3_t
*v
, v3_t
*n
, v2_t
*t
)
182 for (i
=0; (i
*3)<m
->v
->length
; i
++) {
186 v
->x
== AFLOAT(m
->v
->data
,vi
)
187 && v
->y
== AFLOAT(m
->v
->data
,vi
+1)
188 && v
->z
== AFLOAT(m
->v
->data
,vi
+2)
189 && n
->x
== AFLOAT(m
->n
->data
,vi
)
190 && n
->y
== AFLOAT(m
->n
->data
,vi
+1)
191 && n
->z
== AFLOAT(m
->n
->data
,vi
+2)
192 && t
->x
== AFLOAT(m
->t
->data
,ti
)
193 && t
->y
== AFLOAT(m
->t
->data
,ti
+1)
195 array_push_int(m
->i
,i
);
199 array_push_int(m
->i
,i
);
200 array_push_v3t(m
->v
,v
);
201 array_push_v3t(m
->n
,n
);
202 array_push_v2t(m
->t
,t
);
207 /* push a poly onto a mesh */
208 void mesh_push_poly(mesh_t
*m
, v3_t
*v1
, v3_t
*v2
, v3_t
*v3
)
210 if (mesh_push_point(m
,v1
)) {
212 array_push_float(m
->t
,0);
213 array_push_float(m
->t
,0);
216 if (mesh_push_point(m
,v2
)) {
218 array_push_float(m
->t
,0);
219 array_push_float(m
->t
,1);
222 if (mesh_push_point(m
,v3
)) {
224 array_push_float(m
->t
,1);
225 array_push_float(m
->t
,1);
230 /* push a quad onto a mesh */
231 void mesh_push_quad(mesh_t
*m
, v3_t
*v1
, v3_t
*v2
, v3_t
*v3
, v3_t
*v4
)
233 int i
= m
->v
->length
/3;
234 array_push_float(m
->v
,v1
->x
);
235 array_push_float(m
->v
,v1
->y
);
236 array_push_float(m
->v
,v1
->z
);
237 array_push_float(m
->v
,v2
->x
);
238 array_push_float(m
->v
,v2
->y
);
239 array_push_float(m
->v
,v2
->z
);
240 array_push_float(m
->v
,v3
->x
);
241 array_push_float(m
->v
,v3
->y
);
242 array_push_float(m
->v
,v3
->z
);
243 array_push_float(m
->v
,v4
->x
);
244 array_push_float(m
->v
,v4
->y
);
245 array_push_float(m
->v
,v4
->z
);
247 array_push_float(m
->t
,0);
248 array_push_float(m
->t
,0);
249 array_push_float(m
->t
,0);
250 array_push_float(m
->t
,1);
251 array_push_float(m
->t
,1);
252 array_push_float(m
->t
,1);
253 array_push_float(m
->t
,1);
254 array_push_float(m
->t
,0);
256 array_push_int(m
->i
,i
);
257 array_push_int(m
->i
,i
+1);
258 array_push_int(m
->i
,i
+3);
259 array_push_int(m
->i
,i
+1);
260 array_push_int(m
->i
,i
+2);
261 array_push_int(m
->i
,i
+3);
264 /* calculate normals for a mesh */
265 void mesh_calc_normals(mesh_t
*m
)
275 int *con
= alloca(m
->v
->length
*sizeof(int));
276 memset(con
,0,m
->v
->length
*sizeof(int));
281 m
->n
= array_create(ARRAY_TYPE_FLOAT
);
284 if (m
->mat
&& (m
->mat
->options
&MATOPT_UPNORMAL
) == MATOPT_UPNORMAL
) {
285 for (i
=0; i
<m
->v
->length
; i
+=3) {
286 array_push_float(m
->n
,0);
287 array_push_float(m
->n
,1.0);
288 array_push_float(m
->n
,0);
293 for (i
=0; i
<m
->v
->length
; i
++) {
294 array_push_float(m
->n
,0);
297 for (i
=0; i
<m
->i
->length
; i
+=3) {
298 k
[0] = AUINT(m
->i
->data
,i
)*3;
301 k
[3] = AUINT(m
->i
->data
,i
+1)*3;
304 k
[6] = AUINT(m
->i
->data
,i
+2)*3;
307 v1
.x
= AFLOAT(m
->v
->data
,k
[0]);
308 v1
.y
= AFLOAT(m
->v
->data
,k
[1]);
309 v1
.z
= AFLOAT(m
->v
->data
,k
[2]);
310 v2
.x
= AFLOAT(m
->v
->data
,k
[3]);
311 v2
.y
= AFLOAT(m
->v
->data
,k
[4]);
312 v2
.z
= AFLOAT(m
->v
->data
,k
[5]);
313 v3
.x
= AFLOAT(m
->v
->data
,k
[6]);
314 v3
.y
= AFLOAT(m
->v
->data
,k
[7]);
315 v3
.z
= AFLOAT(m
->v
->data
,k
[8]);
325 vect_crossproduct(&b1
,&b2
,&normal
);
326 vect_normalise(&normal
);
332 AFLOAT(m
->n
->data
,k
[0]) += normal
.x
;
333 AFLOAT(m
->n
->data
,k
[1]) += normal
.y
;
334 AFLOAT(m
->n
->data
,k
[2]) += normal
.z
;
335 AFLOAT(m
->n
->data
,k
[3]) += normal
.x
;
336 AFLOAT(m
->n
->data
,k
[4]) += normal
.y
;
337 AFLOAT(m
->n
->data
,k
[5]) += normal
.z
;
338 AFLOAT(m
->n
->data
,k
[6]) += normal
.x
;
339 AFLOAT(m
->n
->data
,k
[7]) += normal
.y
;
340 AFLOAT(m
->n
->data
,k
[8]) += normal
.z
;
343 for (i
=0; i
<m
->n
->length
; i
+=3) {
345 AFLOAT(m
->n
->data
,i
) /= con
[i
];
346 AFLOAT(m
->n
->data
,i
+1) /= con
[i
];
347 AFLOAT(m
->n
->data
,i
+2) /= con
[i
];