aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/src/primitive.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/src/primitive.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/src/primitive.c743
1 files changed, 743 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/src/primitive.c b/src/others/mimesh/libg3d-0.0.8/src/primitive.c
new file mode 100644
index 0000000..53b9c5b
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/src/primitive.c
@@ -0,0 +1,743 @@
1/* $Id$ */
2
3/*
4 libg3d - 3D object loading library
5
6 Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library 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 GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22
23#include <math.h>
24#include <string.h>
25
26#ifndef M_PI
27# define M_PI 3.14159265358979323846
28#endif
29
30#include <g3d/types.h>
31#include <g3d/vector.h>
32#include <g3d/primitive.h>
33#include <g3d/face.h>
34
35EAPI
36G3DObject *g3d_primitive_cube(G3DFloat width, G3DFloat height, G3DFloat depth,
37 G3DMaterial *material)
38{
39 g_warning("g3d_primitive_cube is deprecated - please update your "
40 "sources to use g3d_primitive_box instead");
41 return g3d_primitive_box(width, height, depth, material);
42}
43
44EAPI
45G3DObject *g3d_primitive_box(G3DFloat width, G3DFloat height, G3DFloat depth,
46 G3DMaterial *material)
47{
48 G3DObject *object;
49 G3DFace *face;
50 G3DVector nx, ny, nz;
51 gint32 faces[6][4] = {
52 { 0, 1, 2, 3 },
53 { 4, 5, 6, 7 },
54 { 0, 1, 5, 4 },
55 { 2, 3, 7, 6 },
56 { 1, 2, 6, 5 },
57 { 0, 4, 7, 3 }};
58 gint32 i, j;
59
60 object = g_new0(G3DObject, 1);
61
62 object->vertex_count = 8;
63 object->vertex_data = g3d_vector_new(3, object->vertex_count);
64
65 object->vertex_data[0 * 3 + 0] = -(width / 2);
66 object->vertex_data[0 * 3 + 1] = -(height / 2);
67 object->vertex_data[0 * 3 + 2] = -(depth / 2);
68
69 object->vertex_data[1 * 3 + 0] = -(width / 2);
70 object->vertex_data[1 * 3 + 1] = -(height / 2);
71 object->vertex_data[1 * 3 + 2] = (depth / 2);
72
73 object->vertex_data[2 * 3 + 0] = (width / 2);
74 object->vertex_data[2 * 3 + 1] = -(height / 2);
75 object->vertex_data[2 * 3 + 2] = (depth / 2);
76
77 object->vertex_data[3 * 3 + 0] = (width / 2);
78 object->vertex_data[3 * 3 + 1] = -(height / 2);
79 object->vertex_data[3 * 3 + 2] = -(depth / 2);
80
81 object->vertex_data[4 * 3 + 0] = -(width / 2);
82 object->vertex_data[4 * 3 + 1] = (height / 2);
83 object->vertex_data[4 * 3 + 2] = -(depth / 2);
84
85 object->vertex_data[5 * 3 + 0] = -(width / 2);
86 object->vertex_data[5 * 3 + 1] = (height / 2);
87 object->vertex_data[5 * 3 + 2] = (depth / 2);
88
89 object->vertex_data[6 * 3 + 0] = (width / 2);
90 object->vertex_data[6 * 3 + 1] = (height / 2);
91 object->vertex_data[6 * 3 + 2] = (depth / 2);
92
93 object->vertex_data[7 * 3 + 0] = (width / 2);
94 object->vertex_data[7 * 3 + 1] = (height / 2);
95 object->vertex_data[7 * 3 + 2] = -(depth / 2);
96
97 for(i = 0; i < 6; i ++) {
98 face = g_new0(G3DFace, 1);
99 face->vertex_count = 4;
100 face->vertex_indices = g_new0(guint32, 4);
101 face->normals = g3d_vector_new(3, 4);
102 face->tex_vertex_count = 4;
103 face->tex_vertex_data = g3d_vector_new(2, 4);
104 for(j = 0; j < 4; j ++) {
105 face->vertex_indices[j] = faces[i][j];
106 }
107
108 /* add normals */
109 g3d_face_get_normal(face, object, &nx, &ny, &nz);
110 for(j = 0; j < 4; j ++) {
111 face->normals[j * 3 + 0] = nx;
112 face->normals[j * 3 + 1] = ny;
113 face->normals[j * 3 + 2] = nz;
114 }
115
116 face->flags |= G3D_FLAG_FAC_NORMALS;
117
118 /* add default texture coordinates */
119 face->tex_vertex_data[0 * 2 + 0] = 0;
120 face->tex_vertex_data[0 * 2 + 1] = 0;
121 face->tex_vertex_data[1 * 2 + 0] = 1;
122 face->tex_vertex_data[1 * 2 + 1] = 0;
123 face->tex_vertex_data[2 * 2 + 0] = 1;
124 face->tex_vertex_data[2 * 2 + 1] = 1;
125 face->tex_vertex_data[3 * 2 + 0] = 0;
126 face->tex_vertex_data[3 * 2 + 1] = 1;
127
128 face->material = material;
129 object->faces = g_slist_append(object->faces, face);
130 }
131
132 return object;
133}
134
135EAPI
136G3DObject *g3d_primitive_cylinder(G3DFloat radius, G3DFloat height,
137 guint32 sides, gboolean top, gboolean bottom, G3DMaterial *material)
138{
139 G3DObject *object;
140 G3DFace *face;
141 guint32 i;
142
143 if(sides < 3)
144 return NULL;
145
146 object = g_new0(G3DObject, 1);
147
148 /* vertices */
149 object->vertex_count = sides * 2 + 2;
150 object->vertex_data = g3d_vector_new(3, object->vertex_count);
151
152 /* 2 rings */
153 for(i = 0; i < sides; i ++)
154 {
155 object->vertex_data[i * 3 + 0] =
156 object->vertex_data[(sides + i) * 3 + 0] =
157 radius * cos(M_PI * 2 * i / sides);
158 object->vertex_data[i * 3 + 1] =
159 object->vertex_data[(sides + i) * 3 + 1] =
160 radius * sin(M_PI * 2 * i / sides);
161
162 object->vertex_data[i * 3 + 2] = 0.0;
163 object->vertex_data[(sides + i) * 3 + 2] = height;
164 }
165
166 /* center top & bottom */
167 object->vertex_data[sides * 2 * 3 + 0] = 0.0;
168 object->vertex_data[sides * 2 * 3 + 1] = 0.0;
169 object->vertex_data[sides * 2 * 3 + 2] = 0.0;
170
171 object->vertex_data[sides * 2 * 3 + 3] = 0.0;
172 object->vertex_data[sides * 2 * 3 + 4] = 0.0;
173 object->vertex_data[sides * 2 * 3 + 5] = height;
174
175 /* ring faces */
176 for(i = 0; i < sides; i ++)
177 {
178 face = g_new0(G3DFace, 1);
179 face->material = material;
180 face->vertex_count = 4;
181 face->vertex_indices = g_new0(guint32, 4);
182
183 face->vertex_indices[0] = i;
184 face->vertex_indices[1] = i + sides;
185
186 if(i == (sides - 1))
187 {
188 face->vertex_indices[2] = sides;
189 face->vertex_indices[3] = 0;
190 }
191 else
192 {
193 face->vertex_indices[2] = i + sides + 1;
194 face->vertex_indices[3] = i + 1;
195 }
196
197 /* normals */
198 face->flags |= G3D_FLAG_FAC_NORMALS;
199 face->normals = g3d_vector_new(3, 4);
200
201 face->normals[0 * 3 + 0] =
202 face->normals[1 * 3 + 0] =
203 object->vertex_data[i * 3 + 0];
204 face->normals[0 * 3 + 1] =
205 face->normals[1 * 3 + 1] =
206 object->vertex_data[i * 3 + 1];
207 face->normals[0 * 3 + 2] = 0.0;
208 face->normals[1 * 3 + 2] = 0.0;
209
210 g3d_vector_unify(
211 &(face->normals[0 * 3 + 0]),
212 &(face->normals[0 * 3 + 1]),
213 &(face->normals[0 * 3 + 2]));
214 g3d_vector_unify(
215 &(face->normals[1 * 3 + 0]),
216 &(face->normals[1 * 3 + 1]),
217 &(face->normals[1 * 3 + 2]));
218
219 face->normals[2 * 3 + 0] =
220 face->normals[3 * 3 + 0] =
221 object->vertex_data[face->vertex_indices[2] * 3 + 0];
222 face->normals[2 * 3 + 1] =
223 face->normals[3 * 3 + 1] =
224 object->vertex_data[face->vertex_indices[2] * 3 + 1];
225 face->normals[2 * 3 + 2] = 0.0;
226 face->normals[3 * 3 + 2] = 0.0;
227
228 g3d_vector_unify(
229 &(face->normals[2 * 3 + 0]),
230 &(face->normals[2 * 3 + 1]),
231 &(face->normals[2 * 3 + 2]));
232 g3d_vector_unify(
233 &(face->normals[3 * 3 + 0]),
234 &(face->normals[3 * 3 + 1]),
235 &(face->normals[3 * 3 + 2]));
236
237 object->faces = g_slist_append(object->faces, face);
238 }
239
240 if(top)
241 {
242 for(i = 0; i < sides; i ++)
243 {
244 face = g_new0(G3DFace, 1);
245 face->material = material;
246 face->vertex_count = 3;
247 face->vertex_indices = g_new0(guint32, 3);
248
249 face->vertex_indices[0] = sides + i;
250 face->vertex_indices[1] = sides * 2 + 1; /* top center */
251 if(i == (sides - 1))
252 face->vertex_indices[2] = sides;
253 else
254 face->vertex_indices[2] = sides + i + 1;
255
256 object->faces = g_slist_append(object->faces, face);
257 }
258 }
259
260 if(bottom)
261 {
262 for(i = 0; i < sides; i ++)
263 {
264 face = g_new0(G3DFace, 1);
265 face->material = material;
266 face->vertex_count = 3;
267 face->vertex_indices = g_new0(guint32, 3);
268
269 face->vertex_indices[0] = i;
270 face->vertex_indices[1] = sides * 2; /* bottom center */
271 if(i == (sides - 1))
272 face->vertex_indices[2] = 0;
273 else
274 face->vertex_indices[2] = i + 1;
275
276 object->faces = g_slist_append(object->faces, face);
277 }
278 }
279
280 return object;
281}
282
283EAPI
284G3DObject *g3d_primitive_tube(G3DFloat r_in, G3DFloat r_out, G3DFloat height,
285 guint32 sides, gboolean top, gboolean bottom, G3DMaterial *material)
286{
287 G3DObject *object;
288 G3DFace *face;
289 guint32 i, j;
290
291 if(sides < 3)
292 return NULL;
293
294 object = g_new0(G3DObject, 1);
295
296 /* vertices */
297 object->vertex_count = sides * 4;
298 object->vertex_data = g3d_vector_new(3, object->vertex_count);
299
300 /*
301 * outer lower 0
302 * outer upper sides
303 * inner lower sides * 2
304 * inner upper sides * 3
305 */
306
307 /* 4 rings */
308 for(i = 0; i < sides; i ++)
309 {
310 /* outer rings */
311 object->vertex_data[i * 3 + 0] =
312 object->vertex_data[(sides + i) * 3 + 0] =
313 r_out * cos(M_PI * 2 * i / sides);
314 object->vertex_data[i * 3 + 1] =
315 object->vertex_data[(sides + i) * 3 + 1] =
316 r_out * sin(M_PI * 2 * i / sides);
317
318 object->vertex_data[i * 3 + 2] = 0.0;
319 object->vertex_data[(sides + i) * 3 + 2] = height;
320
321 /* inner rings */
322 object->vertex_data[(sides * 2 + i) * 3 + 0] =
323 object->vertex_data[(sides * 3 + i) * 3 + 0] =
324 r_in * cos(M_PI * 2 * i / sides);
325 object->vertex_data[(sides * 2 + i) * 3 + 1] =
326 object->vertex_data[(sides * 3 + i) * 3 + 1] =
327 r_in * sin(M_PI * 2 * i / sides);
328
329 object->vertex_data[(sides * 2 + i) * 3 + 2] = 0.0;
330 object->vertex_data[(sides * 3 + i) * 3 + 2] = height;
331 }
332
333 /* ring faces */
334 for(i = 0; i < sides; i ++)
335 {
336 /* outer and inner faces */
337 for(j = 0; j < 2; j ++)
338 {
339 face = g_new0(G3DFace, 1);
340 face->material = material;
341 face->vertex_count = 4;
342 face->vertex_indices = g_new0(guint32, 4);
343
344 face->vertex_indices[0] = i + sides * (j * 2 + 0);
345 face->vertex_indices[1] = i + sides * (j * 2 + 1);
346
347 if(i == (sides - 1))
348 {
349 face->vertex_indices[2] = sides * (j * 2 + 1);
350 face->vertex_indices[3] = sides * (j * 2 + 0);
351 }
352 else
353 {
354 face->vertex_indices[2] = i + sides * (j * 2 + 1) + 1;
355 face->vertex_indices[3] = i + sides * (j * 2 + 0) + 1;
356 }
357
358 /* normals */
359 face->flags |= G3D_FLAG_FAC_NORMALS;
360 face->normals = g3d_vector_new(3, 4);
361
362 face->normals[0 * 3 + 0] =
363 face->normals[1 * 3 + 0] =
364 object->vertex_data[face->vertex_indices[0] * 3 + 0] *
365 (j ? -1 : 1);
366 face->normals[0 * 3 + 1] =
367 face->normals[1 * 3 + 1] =
368 object->vertex_data[face->vertex_indices[0] * 3 + 1] *
369 (j ? -1 : 1);
370 face->normals[0 * 3 + 2] = 0.0;
371 face->normals[1 * 3 + 2] = 0.0;
372
373 g3d_vector_unify(
374 &(face->normals[0 * 3 + 0]),
375 &(face->normals[0 * 3 + 1]),
376 &(face->normals[0 * 3 + 2]));
377 g3d_vector_unify(
378 &(face->normals[1 * 3 + 0]),
379 &(face->normals[1 * 3 + 1]),
380 &(face->normals[1 * 3 + 2]));
381
382 face->normals[2 * 3 + 0] =
383 face->normals[3 * 3 + 0] =
384 object->vertex_data[face->vertex_indices[2] * 3 + 0] *
385 (j ? -1 : 1);
386 face->normals[2 * 3 + 1] =
387 face->normals[3 * 3 + 1] =
388 object->vertex_data[face->vertex_indices[2] * 3 + 1] *
389 (j ? -1 : 1);
390 face->normals[2 * 3 + 2] = 0.0;
391 face->normals[3 * 3 + 2] = 0.0;
392
393 g3d_vector_unify(
394 &(face->normals[2 * 3 + 0]),
395 &(face->normals[2 * 3 + 1]),
396 &(face->normals[2 * 3 + 2]));
397 g3d_vector_unify(
398 &(face->normals[3 * 3 + 0]),
399 &(face->normals[3 * 3 + 1]),
400 &(face->normals[3 * 3 + 2]));
401
402 object->faces = g_slist_append(object->faces, face);
403 }
404 }
405
406 /* top/bottom faces if requested */
407 for(i = 0; i < sides; i ++)
408 {
409 for(j = (bottom ? 0 : 1); j < (top ? 2 : 1); j ++)
410 {
411 face = g_new0(G3DFace, 1);
412 face->material = material;
413 face->vertex_count = 4;
414 face->vertex_indices = g_new0(guint32, 4);
415
416 face->vertex_indices[0] = sides * (2 + j) + i; /* inner */
417 face->vertex_indices[1] = sides * (0 + j) + i; /* outer */
418
419 if(i == (sides - 1))
420 {
421 face->vertex_indices[2] = sides * (0 + j); /* outer first */
422 face->vertex_indices[3] = sides * (2 + j); /* inner first */
423 }
424 else
425 {
426 face->vertex_indices[2] = sides * (0 + j) + i + 1;
427 face->vertex_indices[3] = sides * (2 + j) + i + 1;
428 }
429
430 object->faces = g_slist_append(object->faces, face);
431 }
432 }
433
434 return object;
435}
436
437EAPI
438G3DObject *g3d_primitive_sphere(G3DFloat radius, guint32 vseg, guint32 hseg,
439 G3DMaterial *material)
440{
441 G3DObject *object;
442 G3DFace *face;
443 GSList *flist;
444 gint32 sh, sv, i;
445 gdouble x, y, z, u;
446
447 g_return_val_if_fail(vseg >= 2, NULL);
448 g_return_val_if_fail(hseg >= 3, NULL);
449
450 object = g_new0(G3DObject, 1);
451 object->vertex_count = (vseg - 1) * hseg + 2;
452 object->vertex_data = g3d_vector_new(3, object->vertex_count);
453
454 for(sv = 1; sv < vseg; sv ++)
455 {
456 y = radius * cos(M_PI * sv / vseg);
457 u = radius * sin(M_PI * sv / vseg);
458 for(sh = 0; sh < hseg; sh ++)
459 {
460 x = radius * cos(M_PI * 2 * sh / hseg) * u;
461 z = radius * sin(M_PI * 2 * sh / hseg) * u;
462
463 object->vertex_data[((sv - 1) * hseg + sh) * 3 + 0] = x;
464 object->vertex_data[((sv - 1) * hseg + sh) * 3 + 1] = y;
465 object->vertex_data[((sv - 1) * hseg + sh) * 3 + 2] = z;
466
467 if(sv > 1)
468 {
469 /* first triangle */
470 face = g_new0(G3DFace, 1);
471 face->material = material;
472 face->vertex_count = 3;
473 face->vertex_indices = g_new0(guint32, 3);
474 face->vertex_indices[0] = (sv - 1) * hseg + sh;
475 face->vertex_indices[1] = (sh == (hseg - 1)) ?
476 (sv - 1) * hseg :
477 (sv - 1) * hseg + sh + 1;
478 face->vertex_indices[2] = (sv - 2) * hseg + sh;
479 object->faces = g_slist_append(object->faces, face);
480
481 /* second triangle */
482 face = g_new0(G3DFace, 1);
483 face->material = material;
484 face->vertex_count = 3;
485 face->vertex_indices = g_new0(guint32, 3);
486 face->vertex_indices[0] = (sv - 2) * hseg + sh;
487 face->vertex_indices[1] = (sh == (hseg - 1)) ?
488 (sv - 1) * hseg :
489 (sv - 1) * hseg + sh + 1;
490 face->vertex_indices[2] = (sh == (hseg - 1)) ?
491 (sv - 2) * hseg :
492 (sv - 2) * hseg + sh + 1;
493 object->faces = g_slist_append(object->faces, face);
494 } /* sv > 1 */
495 } /* hseg */
496 } /* vseg */
497
498 object->vertex_data[(object->vertex_count - 1) * 3 + 0] = 0;
499 object->vertex_data[(object->vertex_count - 1) * 3 + 1] = radius;
500 object->vertex_data[(object->vertex_count - 1) * 3 + 2] = 0;
501
502 object->vertex_data[(object->vertex_count - 2) * 3 + 0] = 0;
503 object->vertex_data[(object->vertex_count - 2) * 3 + 1] = -radius;
504 object->vertex_data[(object->vertex_count - 2) * 3 + 2] = 0;
505
506 for(sh = 0; sh < hseg; sh ++)
507 {
508 /* top */
509 face = g_new0(G3DFace, 1);
510 face->material = material;
511 face->vertex_count = 3;
512 face->vertex_indices = g_new0(guint32, 3);
513
514 face->vertex_indices[0] = object->vertex_count - 1;
515 face->vertex_indices[1] = sh;
516 face->vertex_indices[2] = (sh == (hseg - 1)) ? 0 : sh + 1;
517
518 object->faces = g_slist_append(object->faces, face);
519
520 /* bottom */
521 face = g_new0(G3DFace, 1);
522 face->material = material;
523 face->vertex_count = 3;
524 face->vertex_indices = g_new0(guint32, 3);
525
526 face->vertex_indices[2] = object->vertex_count - 2;
527 face->vertex_indices[1] = (vseg - 2) * hseg + sh;
528 face->vertex_indices[0] = (sh == (hseg - 1)) ?
529 (vseg - 2) * hseg :
530 (vseg - 2) * hseg + sh + 1;
531
532 object->faces = g_slist_append(object->faces, face);
533 }
534
535 /* generate normals */
536 flist = object->faces;
537 while(flist)
538 {
539 face = (G3DFace *)flist->data;
540 face->flags |= G3D_FLAG_FAC_NORMALS;
541 face->normals = g3d_vector_new(3, face->vertex_count);
542 for(i = 0; i < face->vertex_count; i ++)
543 {
544 face->normals[i * 3 + 0] =
545 - object->vertex_data[face->vertex_indices[i] * 3 + 0];
546 face->normals[i * 3 + 1] =
547 - object->vertex_data[face->vertex_indices[i] * 3 + 1];
548 face->normals[i * 3 + 2] =
549 - object->vertex_data[face->vertex_indices[i] * 3 + 2];
550
551 g3d_vector_unify(
552 &(face->normals[i * 3 + 0]),
553 &(face->normals[i * 3 + 1]),
554 &(face->normals[i * 3 + 2]));
555 }
556
557 flist = flist->next;
558 }
559
560 return object;
561}
562
563/* vdata: 2-dimensional coordinates: vcnt * 2 * gdouble */
564EAPI
565G3DObject *g3d_primitive_box_strip_2d(guint32 vcnt, gdouble *vdata,
566 gdouble height, gdouble width, G3DMaterial *material)
567{
568 G3DObject *object;
569 G3DFace *face;
570 gint32 i, index;
571 G3DVector *normals, normal[3];
572 G3DFloat r;
573
574 /* create object & helpers */
575 object = g_new0(G3DObject, 1);
576 normals = g3d_vector_new(3, vcnt);
577 object->vertex_count = vcnt * 4;
578 object->vertex_data = g3d_vector_new(3, object->vertex_count);
579
580 /* generate normals */
581 for(i = 0; i < vcnt; i ++) {
582 /* normal data */
583 g3d_vector_normal(
584 /* vector 1 */
585 vdata[(i + 1) * 2 + 0] - vdata[i * 2 + 0],
586 0.0,
587 vdata[(i + 1) * 2 + 1] - vdata[i * 2 + 1],
588 /* vector 2 */
589 0.0, 1.0, 0.0,
590 /* resulting vector */
591 &(normals[i * 3 + 0]),
592 &(normals[i * 3 + 1]),
593 &(normals[i * 3 + 2]));
594 g3d_vector_unify(
595 &(normals[i * 3 + 0]),
596 &(normals[i * 3 + 1]),
597 &(normals[i * 3 + 2]));
598 }
599
600 /* radius */
601 r = width / 2.0;
602
603 /* generate vertices */
604 for(i = 0; i < vcnt; i ++) {
605 /* average normal for vertex */
606 if(i == 0) {
607 normal[0] = normals[i * 3 + 0];
608 normal[1] = normals[i * 3 + 1];
609 normal[2] = normals[i * 3 + 2];
610 } else {
611 normal[0] = (normals[i * 3 + 0] + normals[(i - 1) * 3 + 0]) / 2.0;
612 normal[1] = (normals[i * 3 + 1] + normals[(i - 1) * 3 + 1]) / 2.0;
613 normal[2] = (normals[i * 3 + 2] + normals[(i - 1) * 3 + 2]) / 2.0;
614 g3d_vector_unify(&(normals[0]), &(normals[1]), &(normals[2]));
615 }
616
617 /* vertex data */
618 /* v0 */
619 index = i * 4;
620 object->vertex_data[index * 3 + 0] = vdata[i * 2 + 0] + normals[0] * r;
621 object->vertex_data[index * 3 + 1] = height;
622 object->vertex_data[index * 3 + 2] = vdata[i * 2 + 1] + normals[2] * r;
623 /* v1 */
624 index ++;
625 object->vertex_data[index * 3 + 0] = vdata[i * 2 + 0] - normals[0] * r;
626 object->vertex_data[index * 3 + 1] = height;
627 object->vertex_data[index * 3 + 2] = vdata[i * 2 + 1] - normals[2] * r;
628 /* v2 */
629 index ++;
630 object->vertex_data[index * 3 + 0] = vdata[i * 2 + 0] - normals[0] * r;
631 object->vertex_data[index * 3 + 1] = 0.0;
632 object->vertex_data[index * 3 + 2] = vdata[i * 2 + 1] - normals[2] * r;
633 /* v3 */
634 index ++;
635 object->vertex_data[index * 3 + 0] = vdata[i * 2 + 0] + normals[0] * r;
636 object->vertex_data[index * 3 + 1] = 0.0;
637 object->vertex_data[index * 3 + 2] = vdata[i * 2 + 1] + normals[2] * r;
638
639 if(i > 0) {
640 /* generate faces */
641 /* upper face */
642 face = g_new0(G3DFace, 1);
643 face->material = material;
644 face->vertex_count = 4;
645 face->vertex_indices = g_new0(guint32, 4);
646 face->vertex_indices[0] = (i * 4) + 0;
647 face->vertex_indices[1] = (i * 4) + 1;
648 face->vertex_indices[2] = (i * 4) - 3;
649 face->vertex_indices[3] = (i * 4) - 4;
650 object->faces = g_slist_prepend(object->faces, face);
651 /* lower face */
652 face = g_new0(G3DFace, 1);
653 face->material = material;
654 face->vertex_count = 4;
655 face->vertex_indices = g_new0(guint32, 4);
656 face->vertex_indices[0] = (i * 4) + 3;
657 face->vertex_indices[1] = (i * 4) - 1;
658 face->vertex_indices[2] = (i * 4) - 2;
659 face->vertex_indices[3] = (i * 4) + 2;
660 object->faces = g_slist_prepend(object->faces, face);
661 /* "front" face */
662 face = g_new0(G3DFace, 1);
663 face->material = material;
664 face->vertex_count = 4;
665 face->vertex_indices = g_new0(guint32, 4);
666 face->vertex_indices[0] = (i * 4) + 1;
667 face->vertex_indices[1] = (i * 4) + 2;
668 face->vertex_indices[2] = (i * 4) - 2;
669 face->vertex_indices[3] = (i * 4) - 3;
670 object->faces = g_slist_prepend(object->faces, face);
671 /* "back" face */
672 face = g_new0(G3DFace, 1);
673 face->material = material;
674 face->vertex_count = 4;
675 face->vertex_indices = g_new0(guint32, 4);
676 face->vertex_indices[0] = (i * 4) - 4;
677 face->vertex_indices[1] = (i * 4) - 1;
678 face->vertex_indices[2] = (i * 4) + 3;
679 face->vertex_indices[3] = (i * 4) + 0;
680 object->faces = g_slist_prepend(object->faces, face);
681 }
682 }
683 /* clean up */
684 g_free(normals);
685
686 return object;
687}
688
689EAPI
690G3DObject *g3d_primitive_mesh(guint32 m, guint32 n, gboolean wrap_m,
691 gboolean wrap_n, G3DMaterial *material)
692{
693 G3DObject *object;
694 G3DFace *face;
695 gint32 x, y;
696
697 object = g_new0(G3DObject, 1);
698 object->vertex_count = m * n;
699 object->vertex_data = g3d_vector_new(3, object->vertex_count);
700
701 for(y = 0; y < (n - 1); y ++) {
702 for(x = 0; x < (m - 1); x ++) {
703 face = g3d_face_new_tri(material,
704 y * m + x, y * m + x + 1, (y + 1) * m + x);
705 object->faces = g_slist_prepend(object->faces, face);
706
707 face = g3d_face_new_tri(material,
708 (y + 1) * m + x, y * m + x + 1, (y + 1) * m + x + 1);
709 object->faces = g_slist_prepend(object->faces, face);
710 }
711 if(wrap_n) {
712 face = g3d_face_new_tri(material,
713 (y + 1) * m - 1, y * m, (y + 2) * m - 1);
714 object->faces = g_slist_prepend(object->faces, face);
715
716 face = g3d_face_new_tri(material,
717 (y + 2) * m - 1, y * m, (y + 1) * m);
718 object->faces = g_slist_prepend(object->faces, face);
719 }
720 }
721 if(wrap_m) {
722 for(x = 0; x < (m - 1); x ++) {
723 face = g3d_face_new_tri(material,
724 (n - 1) * m + x, (n - 1) * m + x + 1, x);
725 object->faces = g_slist_prepend(object->faces, face);
726
727 face = g3d_face_new_tri(material,
728 x, (n - 1) * m + x + 1, x + 1);
729 object->faces = g_slist_prepend(object->faces, face);
730 }
731 if(wrap_n) {
732 face = g3d_face_new_tri(material,
733 n * m - 1, (n - 1) * m, m - 1);
734 object->faces = g_slist_prepend(object->faces, face);
735
736 face = g3d_face_new_tri(material,
737 m - 1, (n - 1) * m, 0);
738 object->faces = g_slist_prepend(object->faces, face);
739 }
740 }
741 return object;
742}
743