aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c877
1 files changed, 877 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c
new file mode 100644
index 0000000..d6aea7d
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dae/imp_dae_cb.c
@@ -0,0 +1,877 @@
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 <string.h>
24
25#include <g3d/config.h>
26
27#include <g3d/types.h>
28#include <g3d/material.h>
29#include <g3d/matrix.h>
30#include <g3d/object.h>
31#include <g3d/texture.h>
32#include <g3d/stream.h>
33
34#include "imp_dae_cb.h"
35#include "imp_dae_chunks.h"
36#include "imp_dae_xml.h"
37
38typedef struct {
39 guint32 offset;
40 enum {
41 SEM_UNKNOWN,
42 SEM_VERTEX,
43 SEM_NORMAL,
44 SEM_TEXCOORD
45 } semantic;
46 gchar *source;
47} DaeInput;
48
49/*****************************************************************************/
50
51static G3DMaterial *dae_get_material_by_name(DaeGlobalData *global,
52 const gchar *id, guint32 level)
53{
54 G3DMaterial *material;
55 GSList *mitem;
56 xmlNodePtr matnode;
57
58 /* try to find material */
59 for(mitem = global->model->materials; mitem != NULL; mitem = mitem->next) {
60 material = (G3DMaterial *)mitem->data;
61 if(strcmp(material->name, id) == 0)
62 return material;
63 }
64
65 material = g3d_material_new();
66 material->name = g_strdup(id);
67 global->model->materials = g_slist_append(global->model->materials,
68 material);
69
70 /* find material in library */
71 matnode = dae_library_lookup(global->lib, "symbol", id);
72
73 if(matnode) {
74 dae_xml_parse(global, matnode, dae_chunks_material,
75 level, material);
76 }
77 return material;
78}
79
80static GSList *dae_get_inputs(xmlNodePtr node)
81{
82 xmlNodePtr inode = NULL;
83 gchar *soff, *ssem;
84 DaeInput *input;
85 GSList *inputs = NULL;
86
87 while(dae_xml_next_child_by_tagname(node, &inode, "input")) {
88 input = g_new0(DaeInput, 1);
89 soff = dae_xml_get_attr(inode, "offset");
90 if(soff) {
91 input->offset = atoi(soff);
92 g_free(soff);
93 }
94 ssem = dae_xml_get_attr(inode, "semantic");
95 if(ssem) {
96 if(strcmp(ssem, "VERTEX") == 0)
97 input->semantic = SEM_VERTEX;
98 else if(strcmp(ssem, "NORMAL") == 0)
99 input->semantic = SEM_NORMAL;
100 else if(strcmp(ssem, "TEXCOORD") == 0)
101 input->semantic = SEM_TEXCOORD;
102 else {
103 g_warning("DAE: unknown input semantic '%s'", ssem);
104 input->semantic = SEM_UNKNOWN;
105 }
106 g_free(ssem);
107 }
108 input->source = dae_xml_get_attr(inode, "source");
109 inputs = g_slist_append(inputs, input);
110 }
111 return inputs;
112}
113
114static void dae_inputs_free(GSList *inputs)
115{
116 GSList *item;
117 DaeInput *input;
118
119 for(item = inputs; item != NULL; item = item->next) {
120 input = (DaeInput *)item->data;
121 if(input->source)
122 g_free(input->source);
123 g_free(input);
124 item->data = NULL;
125 }
126 g_slist_free(inputs);
127}
128
129static gboolean dae_load_source(DaeLibrary *lib, gchar *id,
130 G3DFloat **asrc, guint32 *nsrc)
131{
132 xmlNodePtr snode, fnode;
133 gchar *scnt, *next = NULL;
134 gint i;
135
136 snode = dae_library_lookup(lib, "source", id + 1);
137#if DEBUG > 0
138 g_debug("DAE: source '%s': %p", id + 1, (void *)snode);
139#endif
140 if(snode == NULL)
141 return FALSE;
142
143 fnode = dae_xml_get_child_by_tagname(snode, "float_array");
144 if(fnode == NULL)
145 return FALSE;
146
147 scnt = dae_xml_get_attr(fnode, "count");
148#if DEBUG > 0
149 g_debug("DAE: float_array count=\"%s\"", scnt);
150#endif
151 if(scnt == NULL)
152 return FALSE;
153 *nsrc = atoi(scnt);
154 g_free(scnt);
155 if(*nsrc == 0)
156 return FALSE;
157
158 *asrc = g_new0(G3DFloat, *nsrc);
159 for(i = 0; i < *nsrc; i ++)
160#if G3D_FLOAT_IS_DOUBLE
161 if(!dae_xml_next_double(fnode, &next, &((*asrc)[i])))
162#else
163 if(!dae_xml_next_float(fnode, &next, &((*asrc)[i])))
164#endif
165 return FALSE;
166
167 return TRUE;
168}
169
170/*****************************************************************************/
171
172gboolean dae_cb_bind_material(DaeGlobalData *global, DaeLocalData *local)
173{
174 return dae_xml_parse(global, local->node, dae_chunks_bind_material,
175 local->level, local->user_data);
176}
177
178gboolean dae_cb_effect(DaeGlobalData *global, DaeLocalData *local)
179{
180 return dae_xml_parse(global, local->node, dae_chunks_effect,
181 local->level, local->user_data);
182}
183
184gboolean dae_cb_geometry(DaeGlobalData *global, DaeLocalData *local)
185{
186 G3DObject *object;
187 G3DMaterial *material;
188
189 object = (G3DObject *)local->user_data;
190 g_return_val_if_fail(object != NULL, FALSE);
191
192 material = g3d_material_new();
193 material->name = g_strdup("(default material)");
194 object->materials = g_slist_append(object->materials, material);
195
196 if(local->instance) {
197 /* parse original node */
198 dae_xml_parse(global, local->instance,
199 dae_chunks_geometry, local->level, object);
200 }
201
202 /* parse instanced stuff */
203 return dae_xml_parse(global, local->node, dae_chunks_geometry,
204 local->level, object);
205}
206
207gboolean dae_cb_matrix(DaeGlobalData *global, DaeLocalData *local)
208{
209 G3DObject *object = local->user_data;
210 G3DTransformation *transform;
211 gchar *next = NULL;
212 gint i;
213
214 g_return_val_if_fail(object != NULL, FALSE);
215
216 transform = object->transformation;
217 if(transform == NULL) {
218 transform = g_new0(G3DTransformation, 1);
219 g3d_matrix_identity(transform->matrix);
220 object->transformation = transform;
221 }
222
223 for(i = 0; i < 16; i ++)
224#if G3D_FLOAT_IS_DOUBLE
225 dae_xml_next_double(local->node, &next, transform->matrix + i);
226#else
227 dae_xml_next_float(local->node, &next, transform->matrix + i);
228#endif
229 g3d_matrix_transpose(transform->matrix);
230#if DEBUG > 3
231 g_debug("DAE: matrix for '%s':", object->name);
232 g3d_matrix_dump(transform->matrix);
233#endif
234 return TRUE;
235}
236
237gboolean dae_cb_mesh(DaeGlobalData *global, DaeLocalData *local)
238{
239 return dae_xml_parse(global, local->node, dae_chunks_mesh,
240 local->level, local->user_data);
241}
242
243gboolean dae_cb_newparam(DaeGlobalData *global, DaeLocalData *local)
244{
245 G3DMaterial *material = (G3DMaterial *)local->user_data;
246 G3DStream *imgstream = NULL;
247 xmlNodePtr n1, n2;
248 gchar *siid = NULL, *filename, *subfile;
249#ifdef HAVE_LIBGSF
250 gchar *container, *pipe;
251#endif
252
253 g_return_val_if_fail(material != NULL, FALSE);
254
255 n1 = dae_xml_get_child_by_tagname(local->node, "surface");
256 if(n1 != NULL) {
257 n2 = dae_xml_get_child_by_tagname(n1, "init_from");
258 if(n2 != NULL)
259 siid = g_strdup((gchar *)n2->children->content);
260 }
261 if(siid == NULL)
262 return FALSE;
263
264 n1 = dae_library_lookup(global->lib, "image", siid);
265 g_free(siid);
266 if(n1 == NULL)
267 return FALSE;
268
269 n2 = dae_xml_get_child_by_tagname(n1, "init_from");
270 if(n2 == NULL)
271 return FALSE;
272
273 filename = (gchar *)n2->children->content;
274
275 if(strncmp(global->stream->uri, "zip://", 6) == 0) {
276#ifdef HAVE_LIBGSF
277 /* .dae was loaded from .kmz, get texture from .kmz, too */
278 pipe = strchr(global->stream->uri, '|');
279 if(pipe != NULL) {
280 container = g_strndup(global->stream->uri + 6,
281 (pipe - global->stream->uri) - 6);
282 subfile = filename;
283 while(strncmp(subfile, "../", 3) == 0)
284 subfile += 3;
285 g_debug("DAE: loading '%s' from: '%s'", subfile, container);
286 imgstream = g3d_stream_open_zip_from_stream(global->stream->zip_container, subfile);
287 }
288#endif
289 } else {
290 imgstream = g3d_stream_open_file(filename, "rb");
291 if(imgstream == NULL) {
292 /* if opened from unpacked doc.kml, textures are found in
293 * ../images/, so strip leading ../ */
294 subfile = filename;
295 while(strncmp(subfile, "../", 3) == 0)
296 subfile += 3;
297 imgstream = g3d_stream_open_file(subfile, "rb");
298 }
299 }
300
301 if(imgstream != NULL) {
302 material->tex_image = g3d_texture_load_from_stream(global->context,
303 global->model, imgstream);
304 if(material->tex_image) {
305 material->tex_image->tex_env = G3D_TEXENV_DECAL;
306 }
307 g3d_stream_close(imgstream);
308 return TRUE;
309 }
310
311 return FALSE;
312}
313
314gboolean dae_cb_node(DaeGlobalData *global, DaeLocalData *local)
315{
316 G3DObject *object, *pobject;
317 G3DMatrix matrix[16];
318 gchar *name;
319
320 name = dae_xml_get_attr(local->node, "name");
321 if(name == NULL)
322 name = dae_xml_get_attr(local->node, "id");
323 if(name == NULL)
324 return FALSE;
325
326 pobject = (G3DObject *)local->user_data;
327 object = g_new0(G3DObject, 1);
328 object->name = name;
329 if(pobject)
330 pobject->objects = g_slist_append(pobject->objects, object);
331 else
332 global->model->objects = g_slist_append(global->model->objects,
333 object);
334
335 if(dae_xml_parse(global, local->node, dae_chunks_node, local->level,
336 object)) {
337 if(object->transformation) {
338 g3d_object_transform(object, object->transformation->matrix);
339#if DEBUG > 3
340 g_debug("DAE: transforming object '%s'", object->name);
341 g3d_matrix_dump(object->transformation->matrix);
342#endif
343 g_free(object->transformation);
344 object->transformation = NULL;
345 }
346
347 if(!pobject) {
348 g3d_matrix_identity(matrix);
349 g3d_matrix_rotate(-90.0 * G_PI / 180.0, 1.0, 0.0, 0.0, matrix);
350 g3d_object_transform(object, matrix);
351 }
352 return TRUE;
353 }
354 return FALSE;
355}
356
357gboolean dae_cb_phong(DaeGlobalData *global, DaeLocalData *local)
358{
359 G3DMaterial *material = (G3DMaterial *)local->user_data;
360 xmlNodePtr n1, n2;
361 gchar *next;
362
363 g_return_val_if_fail(material != NULL, FALSE);
364
365 /* diffuse */
366 n1 = dae_xml_get_child_by_tagname(local->node, "diffuse");
367 if(n1 != NULL) {
368 n2 = dae_xml_get_child_by_tagname(n1, "color");
369 if(n2 != NULL) {
370 next = NULL;
371#if G3D_FLOAT_IS_DOUBLE
372 dae_xml_next_double(n2, &next, &(material->r));
373 dae_xml_next_double(n2, &next, &(material->g));
374 dae_xml_next_double(n2, &next, &(material->b));
375 dae_xml_next_double(n2, &next, &(material->a));
376#else
377 dae_xml_next_float(n2, &next, &(material->r));
378 dae_xml_next_float(n2, &next, &(material->g));
379 dae_xml_next_float(n2, &next, &(material->b));
380 dae_xml_next_float(n2, &next, &(material->a));
381#endif
382 }
383 }
384
385 /* specular */
386 n1 = dae_xml_get_child_by_tagname(local->node, "specular");
387 if(n1 != NULL) {
388 n2 = dae_xml_get_child_by_tagname(n1, "color");
389 if(n2 != NULL) {
390 next = NULL;
391 /* These are floats either way. */
392 dae_xml_next_float(n2, &next, &(material->specular[0]));
393 dae_xml_next_float(n2, &next, &(material->specular[1]));
394 dae_xml_next_float(n2, &next, &(material->specular[2]));
395 dae_xml_next_float(n2, &next, &(material->specular[3]));
396 }
397 }
398
399 return TRUE;
400}
401
402gboolean dae_cb_polylist(DaeGlobalData *global, DaeLocalData *local)
403{
404 G3DObject *object = local->user_data;
405 G3DFace *face;
406 G3DMaterial *material;
407 xmlNodePtr pnode, vnode;
408 gchar *scnt, *smat, *nextp = NULL, *nextv = NULL;
409 guint32 count, normal_count, tex_count, flags = 0;
410 gint i, j, nv, tmp;
411 GSList *inputs, *item;
412 DaeInput *input;
413 G3DFloat *normal_data = NULL, *tex_data = NULL;
414
415 g_return_val_if_fail(object != NULL, FALSE);
416
417 scnt = dae_xml_get_attr(local->node, "count");
418 g_return_val_if_fail(scnt != NULL, FALSE);
419 count = atoi(scnt);
420 g_free(scnt);
421 g_return_val_if_fail(count != 0, FALSE);
422
423 pnode = dae_xml_get_child_by_tagname(local->node, "p");
424 vnode = dae_xml_get_child_by_tagname(local->node, "vcount");
425 g_return_val_if_fail((pnode != NULL) && (vnode != NULL), FALSE);
426
427 /* material */
428 material = g_slist_nth_data(object->materials, 0);
429 smat = dae_xml_get_attr(local->node, "material");
430 if(smat != NULL) {
431 material = dae_get_material_by_name(global, smat, local->level);
432 g_free(smat);
433 }
434
435 /* get all inputs */
436 inputs = dae_get_inputs(local->node);
437 for(item = inputs; item != NULL; item = item->next) {
438 input = (DaeInput *)item->data;
439 if(input->semantic == SEM_NORMAL)
440 if(dae_load_source(global->lib, input->source,
441 &normal_data, &normal_count))
442 flags |= G3D_FLAG_FAC_NORMALS;
443 if(input->semantic == SEM_TEXCOORD)
444 if(dae_load_source(global->lib, input->source,
445 &tex_data, &tex_count) && (material->tex_image != NULL))
446 flags |= G3D_FLAG_FAC_TEXMAP;
447 }
448
449 for(i = 0; i < count; i ++) {
450 if(dae_xml_next_int(vnode, &nextv, &nv) && (nv > 0)) {
451 face = g_new0(G3DFace, 1);
452 face->vertex_count = nv;
453 face->vertex_indices = g_new0(guint32, nv);
454 face->material = material;
455 face->flags = flags;
456 object->faces = g_slist_append(object->faces, face);
457
458 if(face->flags & G3D_FLAG_FAC_NORMALS) {
459 face->normals = g_new0(G3DFloat, nv * 3);
460 }
461 if(face->flags & G3D_FLAG_FAC_TEXMAP) {
462 face->tex_image = material->tex_image;
463 face->tex_vertex_count = nv;
464 face->tex_vertex_data = g_new0(G3DFloat, nv * 2);
465 }
466
467 for(j = 0; j < nv; j ++) {
468 for(item = inputs; item != NULL; item = item->next) {
469 input = (DaeInput *)item->data;
470 dae_xml_next_int(pnode, &nextp, &tmp);
471 switch(input->semantic) {
472 case SEM_VERTEX:
473 face->vertex_indices[j] = tmp;
474 if(face->vertex_indices[j] >= object->vertex_count)
475 {
476 g_warning("polylist: [%s] face[%d] (%d) >= %d",
477 object->name, j, face->vertex_indices[j],
478 object->vertex_count);
479 face->vertex_indices[j] = 0;
480 }
481 break;
482 case SEM_NORMAL:
483 if(flags & G3D_FLAG_FAC_NORMALS) {
484 face->normals[j * 3 + 0] =
485 normal_data[tmp * 3 + 0];
486 face->normals[j * 3 + 1] =
487 normal_data[tmp * 3 + 1];
488 face->normals[j * 3 + 2] =
489 normal_data[tmp * 3 + 2];
490 }
491 break;
492 case SEM_TEXCOORD:
493 if(flags & G3D_FLAG_FAC_TEXMAP) {
494 face->tex_vertex_data[j * 2 + 0] =
495 tex_data[tmp * 2 + 0];
496 face->tex_vertex_data[j * 2 + 1] = 1.0 -
497 tex_data[tmp * 2 + 1];
498 }
499 break;
500 case SEM_UNKNOWN:
501 break;
502 }
503 } /* inputs */
504 }
505#if DEBUG > 3
506 g_debug("DAE: %-2i, %-2i, %-2i, (%-2i)",
507 face->vertex_indices[0],
508 face->vertex_indices[1],
509 face->vertex_indices[2],
510 ((nv > 3) ? face->vertex_indices[3] : -1));
511#endif
512 }
513 }
514
515 if(tex_data)
516 g_free(tex_data);
517 if(normal_data)
518 g_free(normal_data);
519 dae_inputs_free(inputs);
520
521 return TRUE;
522}
523
524gboolean dae_cb_profile_COMMON(DaeGlobalData *global, DaeLocalData *local)
525{
526 return dae_xml_parse(global, local->node, dae_chunks_profile_COMMON,
527 local->level, local->user_data);
528}
529
530gboolean dae_cb_rotate(DaeGlobalData *global, DaeLocalData *local)
531{
532 G3DObject *object = local->user_data;
533 G3DTransformation *transform;
534 G3DFloat x = 0.0, y = 0.0, z = 0.0, a = 0.0, m[16];
535 gchar *next = NULL;
536
537 g_return_val_if_fail(object != NULL, FALSE);
538
539 transform = object->transformation;
540 if(transform == NULL) {
541 transform = g_new0(G3DTransformation, 1);
542 g3d_matrix_identity(transform->matrix);
543 object->transformation = transform;
544 }
545
546#if G3D_FLOAT_IS_DOUBLE
547 dae_xml_next_double(local->node, &next, &x);
548 dae_xml_next_double(local->node, &next, &y);
549 dae_xml_next_double(local->node, &next, &z);
550 dae_xml_next_double(local->node, &next, &a);
551#else
552 dae_xml_next_float(local->node, &next, &x);
553 dae_xml_next_float(local->node, &next, &y);
554 dae_xml_next_float(local->node, &next, &z);
555 dae_xml_next_float(local->node, &next, &a);
556#endif
557 g_return_val_if_fail((x != 0.0) || (y != 0.0) || (z != 0.0), FALSE);
558 g3d_matrix_rotate(a, x, y, z, m);
559 g3d_matrix_multiply(transform->matrix, m, transform->matrix);
560#if DEBUG > 3
561 g_debug("DAE: rotation for '%s': %.2f, %.2f, %.2f - %.2f", object->name,
562 x, y, z, a);
563 g3d_matrix_dump(transform->matrix);
564#endif
565 return TRUE;
566}
567
568gboolean dae_cb_scale(DaeGlobalData *global, DaeLocalData *local)
569{
570 G3DObject *object = local->user_data;
571 G3DTransformation *transform;
572 G3DFloat x = 0.0, y = 0.0, z = 0.0;
573 gchar *next = NULL;
574
575 g_return_val_if_fail(object != NULL, FALSE);
576
577 transform = object->transformation;
578 if(transform == NULL) {
579 transform = g_new0(G3DTransformation, 1);
580 g3d_matrix_identity(transform->matrix);
581 object->transformation = transform;
582 }
583
584#if G3D_FLOAT_IS_DOUBLE
585 dae_xml_next_double(local->node, &next, &x);
586 dae_xml_next_double(local->node, &next, &y);
587 dae_xml_next_double(local->node, &next, &z);
588#else
589 dae_xml_next_float(local->node, &next, &x);
590 dae_xml_next_float(local->node, &next, &y);
591 dae_xml_next_float(local->node, &next, &z);
592#endif
593 g3d_matrix_scale(x, y, z, transform->matrix);
594#if DEBUG > 3
595 g_debug("DAE: scale for '%s': %.2f, %.2f, %.2f", object->name,
596 x, y, z);
597 g3d_matrix_dump(transform->matrix);
598#endif
599 return TRUE;
600}
601
602gboolean dae_cb_source(DaeGlobalData *global, DaeLocalData *local)
603{
604 gchar *id;
605
606 id = dae_xml_get_attr(local->node, "id");
607 if(id) {
608 dae_library_add(global->lib, "source", id, local->node);
609 g_free(id);
610 return TRUE;
611 }
612 return FALSE;
613}
614
615gboolean dae_cb_technique(DaeGlobalData *global, DaeLocalData *local)
616{
617 return dae_xml_parse(global, local->node, dae_chunks_technique,
618 local->level, local->user_data);
619}
620
621/* instance_geometry::bind_material::technique_common */
622gboolean dae_cb_technique_common(DaeGlobalData *global, DaeLocalData *local)
623{
624 xmlNodePtr node = NULL, tnode;
625 gchar *symbol, *target;
626
627 while(dae_xml_next_child_by_tagname(local->node, &node,
628 "instance_material")) {
629 symbol = dae_xml_get_attr(node, "symbol");
630 if(symbol == NULL)
631 continue;
632 target = dae_xml_get_attr(node, "target");
633 if(target == NULL) {
634 g_free(symbol);
635 continue;
636 }
637 tnode = dae_library_lookup(global->lib, "material", target + 1);
638 if(tnode)
639 dae_library_add(global->lib, "symbol", symbol, tnode);
640 g_free(symbol);
641 g_free(target);
642 }
643 return TRUE;
644}
645
646gboolean dae_cb_translate(DaeGlobalData *global, DaeLocalData *local)
647{
648 G3DObject *object = local->user_data;
649 G3DTransformation *transform;
650 G3DFloat x = 0.0, y = 0.0, z = 0.0;
651 gchar *next = NULL;
652
653 g_return_val_if_fail(object != NULL, FALSE);
654
655 transform = object->transformation;
656 if(transform == NULL) {
657 transform = g_new0(G3DTransformation, 1);
658 g3d_matrix_identity(transform->matrix);
659 object->transformation = transform;
660 }
661
662#if G3D_FLOAT_IS_DOUBLE
663 dae_xml_next_double(local->node, &next, &x);
664 dae_xml_next_double(local->node, &next, &y);
665 dae_xml_next_double(local->node, &next, &z);
666#else
667 dae_xml_next_float(local->node, &next, &x);
668 dae_xml_next_float(local->node, &next, &y);
669 dae_xml_next_float(local->node, &next, &z);
670#endif
671 g3d_matrix_translate(x, y, z, transform->matrix);
672#if DEBUG > 3
673 g_debug("DAE: translation for '%s': %.2f, %.2f, %.2f", object->name,
674 x, y, z);
675 g3d_matrix_dump(transform->matrix);
676#endif
677 return TRUE;
678}
679
680gboolean dae_cb_triangles(DaeGlobalData *global, DaeLocalData *local)
681{
682 G3DObject *object = local->user_data;
683 G3DFace *face;
684 G3DMaterial *material;
685 xmlNodePtr pnode;
686 gchar *scnt, *smat, *nextp = NULL;
687 guint32 count, normal_count, tex_count, flags = 0;
688 G3DFloat *normal_data = NULL, *tex_data = NULL;
689 gint i, j, tmp;
690 GSList *inputs, *item;
691 DaeInput *input;
692
693 g_return_val_if_fail(object != NULL, FALSE);
694
695 scnt = dae_xml_get_attr(local->node, "count");
696 g_return_val_if_fail(scnt != NULL, FALSE);
697 count = atoi(scnt);
698 g_return_val_if_fail(count != 0, FALSE);
699 g_free(scnt);
700
701 pnode = dae_xml_get_child_by_tagname(local->node, "p");
702 g_return_val_if_fail(pnode != NULL, FALSE);
703
704 /* material */
705 material = g_slist_nth_data(object->materials, 0);
706 smat = dae_xml_get_attr(local->node, "material");
707 if(smat != NULL) {
708 material = dae_get_material_by_name(global, smat, local->level);
709 g_free(smat);
710 }
711
712 /* get all inputs */
713 inputs = dae_get_inputs(local->node);
714 for(item = inputs; item != NULL; item = item->next) {
715 input = (DaeInput *)item->data;
716 if(input->semantic == SEM_NORMAL)
717 if(dae_load_source(global->lib, input->source,
718 &normal_data, &normal_count)) {
719 flags |= G3D_FLAG_FAC_NORMALS;
720 }
721 if(input->semantic == SEM_TEXCOORD)
722 if(dae_load_source(global->lib, input->source,
723 &tex_data, &tex_count) && (material->tex_image != NULL)) {
724 flags |= G3D_FLAG_FAC_TEXMAP;
725 }
726 }
727
728 for(i = 0; i < count; i ++) {
729 face = g_new0(G3DFace, 1);
730 face->vertex_count = 3;
731 face->vertex_indices = g_new0(guint32, 3);
732 face->material = material;
733 face->flags = flags;
734 object->faces = g_slist_append(object->faces, face);
735
736 if(face->flags & G3D_FLAG_FAC_NORMALS) {
737 face->normals = g_new0(G3DFloat, 3 * 3);
738 }
739 if(face->flags & G3D_FLAG_FAC_TEXMAP) {
740 face->tex_image = material->tex_image;
741 face->tex_vertex_count = 3;
742 face->tex_vertex_data = g_new0(G3DFloat, 3 * 2);
743 }
744
745 for(j = 0; j < 3; j ++) {
746 for(item = inputs; item != NULL; item = item->next) {
747 input = (DaeInput *)item->data;
748 dae_xml_next_int(pnode, &nextp, &tmp);
749 switch(input->semantic) {
750 case SEM_VERTEX:
751 face->vertex_indices[j] = tmp;
752 if(face->vertex_indices[j] >= object->vertex_count) {
753 g_warning("triangles: [%s] face[%d] (%d) >= %d",
754 object->name, j, face->vertex_indices[j],
755 object->vertex_count);
756 face->vertex_indices[j] = 0;
757 }
758 break;
759 case SEM_NORMAL:
760 if(flags & G3D_FLAG_FAC_NORMALS) {
761 face->normals[j * 3 + 0] =
762 normal_data[tmp * 3 + 0];
763 face->normals[j * 3 + 1] =
764 normal_data[tmp * 3 + 1];
765 face->normals[j * 3 + 2] =
766 normal_data[tmp * 3 + 2];
767 }
768 break;
769 case SEM_TEXCOORD:
770 if(flags & G3D_FLAG_FAC_TEXMAP) {
771 face->tex_vertex_data[j * 2 + 0] =
772 tex_data[tmp * 2 + 0];
773 face->tex_vertex_data[j * 2 + 1] = 1.0 -
774 tex_data[tmp * 2 + 1];
775 }
776 break;
777 case SEM_UNKNOWN:
778 break;
779 }
780 } /* inputs */
781#if DEBUG > 3
782 g_debug("DAE: %-2i, %-2i, %-2i",
783 face->vertex_indices[0],
784 face->vertex_indices[1],
785 face->vertex_indices[2]);
786#endif
787 }
788 }
789 if(tex_data)
790 g_free(tex_data);
791 if(normal_data)
792 g_free(normal_data);
793 dae_inputs_free(inputs);
794
795 return TRUE;
796}
797
798gboolean dae_cb_vertices(DaeGlobalData *global, DaeLocalData *local)
799{
800 return dae_xml_parse(global, local->node, dae_chunks_vertices,
801 local->level, local->user_data);
802}
803
804gboolean dae_cb_vertices__input(DaeGlobalData *global, DaeLocalData *local)
805{
806 G3DObject *object = (G3DObject *)(local->user_data);
807 gchar *sid, *sem, *cnt, *next = NULL;
808 gboolean skip = FALSE;
809 xmlNodePtr snode, fanode;
810 gint i, j;
811
812 g_return_val_if_fail(object != NULL, FALSE);
813
814 sem = dae_xml_get_attr(local->node, "semantic");
815 sid = dae_xml_get_attr(local->node, "source");
816 g_return_val_if_fail((sem != NULL) && (sid != NULL), FALSE);
817
818 /* get 'source' node, skip leading '#' from 'source' attribute */
819 snode = dae_library_lookup(global->lib, "source", sid + 1);
820#if DEBUG > 0
821 g_debug("DAE: looking up source '%s' from library: %p", sid + 1,
822 (void *)snode);
823#endif
824 g_return_val_if_fail(snode != NULL, FALSE);
825
826 if(sem)
827 g_free(sem);
828 if(sid)
829 g_free(sid);
830
831 /* TODO: check technique_common/accessor */
832
833 fanode = dae_xml_get_child_by_tagname(snode, "float_array");
834 if(fanode) {
835 cnt = dae_xml_get_attr(fanode, "count");
836#if DEBUG > 0
837 g_debug("DAE: float_array count=\"%s\"", cnt);
838#endif
839 g_return_val_if_fail(cnt != NULL, FALSE);
840
841 object->vertex_count = atoi(cnt);
842 g_return_val_if_fail(object->vertex_count != 0, FALSE);
843
844 object->vertex_data = g_new0(G3DFloat, 3 * object->vertex_count);
845 for(i = 0; i < object->vertex_count / 3; i ++)
846 {
847 for(j = 0; j < 3; j ++)
848 {
849#if G3D_FLOAT_IS_DOUBLE
850 if(!dae_xml_next_double(fanode, &next, &(object->vertex_data[i * 3 + j])))
851#else
852 if(!dae_xml_next_float(fanode, &next, &(object->vertex_data[i * 3 + j])))
853#endif
854 {
855 skip = TRUE;
856 break;
857 }
858 }
859#if DEBUG > 3
860 g_debug("DAE: %-3.2f, %-3.2f, %-3.2f",
861 object->vertex_data[i * 3 + 0],
862 object->vertex_data[i * 3 + 1],
863 object->vertex_data[i * 3 + 2]);
864#endif
865 if(skip)
866 break;
867 }
868 }
869
870 return TRUE;
871}
872
873gboolean dae_cb_visual_scene(DaeGlobalData *global, DaeLocalData *local)
874{
875 return dae_xml_parse(global, local->node, dae_chunks_visual_scene,
876 local->level, NULL);
877}