diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dmf/imp_3dmf.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dmf/imp_3dmf.c | 646 |
1 files changed, 646 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dmf/imp_3dmf.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dmf/imp_3dmf.c new file mode 100644 index 0000000..82a46d3 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dmf/imp_3dmf.c | |||
@@ -0,0 +1,646 @@ | |||
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/types.h> | ||
26 | #include <g3d/context.h> | ||
27 | #include <g3d/stream.h> | ||
28 | #include <g3d/object.h> | ||
29 | #include <g3d/vector.h> | ||
30 | #include <g3d/matrix.h> | ||
31 | #include <g3d/material.h> | ||
32 | #include <g3d/iff.h> | ||
33 | #include <g3d/debug.h> | ||
34 | |||
35 | #include "imp_3dmf_chunks.h" | ||
36 | |||
37 | #define X3DMF_CHUNK_CHAR(id, shift) \ | ||
38 | ((((id) >> (shift)) & 0xFF) == 0) ? \ | ||
39 | ' ' : ((id) >> (shift)) & 0xFF | ||
40 | |||
41 | typedef struct { | ||
42 | guint32 id; | ||
43 | guint32 offset; | ||
44 | guint32 type; | ||
45 | } | ||
46 | X3dmfTocEntry; | ||
47 | |||
48 | typedef struct { | ||
49 | guint32 num_entries; | ||
50 | X3dmfTocEntry *entries; | ||
51 | } | ||
52 | X3dmfToc; | ||
53 | |||
54 | |||
55 | static gboolean x3dmf_read_container(G3DStream *stream, guint32 length, | ||
56 | G3DModel *model, G3DObject *object, guint32 level, X3dmfToc *toc, | ||
57 | G3DContext *context); | ||
58 | static X3dmfToc *x3dmf_read_toc(G3DStream *stream, X3dmfToc *prev_toc, | ||
59 | G3DContext *context); | ||
60 | |||
61 | EAPI | ||
62 | gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream, | ||
63 | G3DModel *model, gpointer user_data) | ||
64 | { | ||
65 | guint32 id, flags, tocloc, pos; | ||
66 | gsize len; | ||
67 | guint16 ver_min, ver_maj; | ||
68 | gchar txthead[10]; | ||
69 | X3dmfToc *toc = NULL; | ||
70 | |||
71 | g3d_iff_read_chunk(stream, &id, &len, 0); | ||
72 | if((id != G3D_IFF_MKID('3', 'D', 'M', 'F')) || (len != 16)) { | ||
73 | g3d_stream_seek(stream, 0, G_SEEK_SET); | ||
74 | g3d_stream_read(stream, txthead, 10); | ||
75 | if(strncmp(txthead, "3DMetafile", 10) == 0) { | ||
76 | g_warning("file %s is an ASCII 3D Metafile (unhandled)\n", | ||
77 | stream->uri); | ||
78 | } else { | ||
79 | g_warning("file %s is not a 3D Metafile\n", stream->uri); | ||
80 | } | ||
81 | return FALSE; | ||
82 | } | ||
83 | |||
84 | ver_maj = g3d_stream_read_int16_be(stream); | ||
85 | ver_min = g3d_stream_read_int16_be(stream); | ||
86 | |||
87 | flags = g3d_stream_read_int32_be(stream); | ||
88 | |||
89 | g3d_stream_skip(stream, 4); /* FIXME: 64bit file offsets */ | ||
90 | tocloc = g3d_stream_read_int32_be(stream); | ||
91 | |||
92 | /* read TOC if available */ | ||
93 | if(tocloc > 0) { | ||
94 | pos = g3d_stream_tell(stream); | ||
95 | g3d_stream_seek(stream, tocloc, G_SEEK_SET); | ||
96 | toc = x3dmf_read_toc(stream, NULL, context); | ||
97 | g3d_stream_seek(stream, pos, G_SEEK_SET); | ||
98 | } | ||
99 | |||
100 | #if DEBUG > 0 | ||
101 | g_debug("3DMF: version %d.%d (0x%08x) TOC @ 0x%08x", | ||
102 | ver_maj, ver_min, flags, tocloc); | ||
103 | #endif | ||
104 | |||
105 | x3dmf_read_container(stream, (guint32) -1, model, NULL, 0, toc, context); | ||
106 | |||
107 | return TRUE; | ||
108 | } | ||
109 | |||
110 | EAPI | ||
111 | gchar *plugin_description(void) | ||
112 | { | ||
113 | return g_strdup("3D Metafiles."); | ||
114 | } | ||
115 | |||
116 | EAPI | ||
117 | gchar **plugin_extensions(void) | ||
118 | { | ||
119 | return g_strsplit("b3d:3mf:3dmf", ":", 0); | ||
120 | } | ||
121 | |||
122 | /****************************************************************************** | ||
123 | * 3DMF specific | ||
124 | */ | ||
125 | |||
126 | static X3dmfChunkDesc *x3dmf_get_chunk_info(guint32 id) | ||
127 | { | ||
128 | gint32 i; | ||
129 | |||
130 | for(i = 0; x3dmf_chunks[i].id != 0; i ++) | ||
131 | if(x3dmf_chunks[i].id == id) | ||
132 | return &(x3dmf_chunks[i]); | ||
133 | return NULL; | ||
134 | } | ||
135 | |||
136 | static X3dmfToc *x3dmf_read_toc(G3DStream *stream, X3dmfToc *prev_toc, | ||
137 | G3DContext *context) | ||
138 | { | ||
139 | X3dmfToc *toc; | ||
140 | guint32 off_next_toc, typeseed, refseed, entrytype, entrysize, nentries; | ||
141 | guint32 noff, i; | ||
142 | |||
143 | if(prev_toc) | ||
144 | toc = prev_toc; | ||
145 | else | ||
146 | toc = g_new0(X3dmfToc, 1); | ||
147 | |||
148 | /* skip tag and size (FIXME) */ | ||
149 | g3d_stream_skip(stream, 8); | ||
150 | |||
151 | g3d_stream_skip(stream, 4); /* FIXME: 64bit file offsets */ | ||
152 | off_next_toc = g3d_stream_read_int32_be(stream); | ||
153 | typeseed = g3d_stream_read_int32_be(stream); | ||
154 | refseed = g3d_stream_read_int32_be(stream); | ||
155 | entrytype = g3d_stream_read_int32_be(stream); | ||
156 | entrysize = g3d_stream_read_int32_be(stream); | ||
157 | nentries = g3d_stream_read_int32_be(stream); | ||
158 | |||
159 | /* resize entry array */ | ||
160 | noff = toc->num_entries; | ||
161 | toc->num_entries += nentries; | ||
162 | toc->entries = (X3dmfTocEntry *)g_realloc(toc->entries, | ||
163 | toc->num_entries * sizeof(X3dmfTocEntry)); | ||
164 | |||
165 | /* read TOC entries */ | ||
166 | for(i = 0; i < nentries; i ++) { | ||
167 | toc->entries[noff + i].id = g3d_stream_read_int32_be(stream); | ||
168 | g3d_stream_skip(stream, 4); /* FIXME: 64bit file offsets */ | ||
169 | toc->entries[noff + i].offset = g3d_stream_read_int32_be(stream); | ||
170 | |||
171 | if((entrytype == 1) && (entrysize == 16)) { | ||
172 | toc->entries[noff + i].type = g3d_stream_read_int32_be(stream); | ||
173 | } | ||
174 | #if DEBUG > 0 | ||
175 | g_debug("3DMF: TOC: %06d @ 0x%08x", | ||
176 | toc->entries[noff + i].id, | ||
177 | toc->entries[noff + i].offset); | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | /* read next toc */ | ||
182 | if(off_next_toc > 0) { | ||
183 | g3d_stream_seek(stream, off_next_toc, SEEK_SET); | ||
184 | toc = x3dmf_read_toc(stream, toc, context); | ||
185 | } | ||
186 | |||
187 | return toc; | ||
188 | } | ||
189 | |||
190 | static guint32 x3dmf_read_mesh(G3DStream *stream, G3DObject *object, | ||
191 | G3DContext *context) | ||
192 | { | ||
193 | guint32 i, j, nconts, nfaces, nbytes = 0, ncverts, offv; | ||
194 | G3DFace *face; | ||
195 | |||
196 | g_return_val_if_fail(object != NULL, FALSE); | ||
197 | |||
198 | offv = object->vertex_count; | ||
199 | object->vertex_count += g3d_stream_read_int32_be(stream); | ||
200 | object->vertex_data = g_realloc(object->vertex_data, | ||
201 | object->vertex_count * 3 * sizeof(G3DFloat)); | ||
202 | nbytes += 4; | ||
203 | |||
204 | for(i = offv; i < object->vertex_count; i ++) { | ||
205 | for(j = 0; j < 3; j ++) | ||
206 | object->vertex_data[i * 3 + j] = g3d_stream_read_float_be(stream); | ||
207 | nbytes += 12; | ||
208 | |||
209 | g3d_context_update_interface(context); | ||
210 | } | ||
211 | |||
212 | nfaces = g3d_stream_read_int32_be(stream); | ||
213 | nconts = g3d_stream_read_int32_be(stream); | ||
214 | nbytes += 8; | ||
215 | |||
216 | #if DEBUG > 0 | ||
217 | g_debug("|%u verts, %u faces, %u conts", object->vertex_count, | ||
218 | nfaces, nconts); | ||
219 | #endif | ||
220 | |||
221 | for(i = 0; i < nfaces; i ++) { | ||
222 | face = g_new0(G3DFace, 1); | ||
223 | |||
224 | face->vertex_count = g3d_stream_read_int32_be(stream); | ||
225 | nbytes += 4; | ||
226 | face->vertex_indices = g_new0(guint32, face->vertex_count); | ||
227 | |||
228 | for(j = 0; j < face->vertex_count; j ++) { | ||
229 | face->vertex_indices[j] = offv + g3d_stream_read_int32_be(stream); | ||
230 | nbytes += 4; | ||
231 | if(face->vertex_indices[j] >= object->vertex_count) { | ||
232 | g_warning("face index wrong: %u >= %u", | ||
233 | face->vertex_indices[j], object->vertex_count); | ||
234 | face->vertex_indices[j] = 0; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | #if DEBUG > 3 | ||
239 | g_debug("|face %u: %u %u %u", i, face->vertex_indices[0], | ||
240 | face->vertex_indices[1], face->vertex_indices[2]); | ||
241 | #endif | ||
242 | |||
243 | face->material = g_slist_nth_data(object->materials, 0); | ||
244 | object->faces = g_slist_prepend(object->faces, face); | ||
245 | |||
246 | g3d_context_update_interface(context); | ||
247 | } | ||
248 | |||
249 | /* contours */ | ||
250 | for(i = 0; i < nconts; i ++) { | ||
251 | ncverts = g3d_stream_read_int32_be(stream); | ||
252 | nbytes += 4; | ||
253 | for(j = 0; j < ncverts; j ++) { | ||
254 | g3d_stream_read_int32_be(stream); | ||
255 | nbytes += 4; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return nbytes; | ||
260 | } | ||
261 | |||
262 | static G3DObject *x3dmf_object_new(G3DStream *stream, G3DModel *model) | ||
263 | { | ||
264 | G3DObject *object; | ||
265 | G3DMaterial *material; | ||
266 | |||
267 | object = g_new0(G3DObject, 1); | ||
268 | material = g3d_material_new(); | ||
269 | |||
270 | object->name = g_strdup_printf("container @ 0x%08x", | ||
271 | (guint32)g3d_stream_tell(stream) - 8); | ||
272 | model->objects = g_slist_append(model->objects, object); | ||
273 | object->materials = g_slist_append(object->materials, material); | ||
274 | |||
275 | return object; | ||
276 | } | ||
277 | |||
278 | static guint32 x3dmf_read_packed(G3DStream *stream, guint32 maxx, | ||
279 | guint32 *nread) | ||
280 | { | ||
281 | if(maxx > 0xFFFE) { | ||
282 | if(nread) | ||
283 | (*nread) += 4; | ||
284 | return g3d_stream_read_int32_be(stream); | ||
285 | } else if(maxx > 0xFE) { | ||
286 | if(nread) | ||
287 | (*nread) += 2; | ||
288 | return g3d_stream_read_int16_be(stream); | ||
289 | } else { | ||
290 | if(nread) | ||
291 | (*nread) += 1; | ||
292 | return g3d_stream_read_int8(stream); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | [tmsh] - TriMesh | ||
298 | http://developer.apple.com/documentation/QuickTime/QD3D/qd3dmetafile.33.htm | ||
299 | |||
300 | Uns32 numTriangles | ||
301 | Uns32 numTriangleAttributeTypes | ||
302 | Uns32 numEdges | ||
303 | Uns32 numEdgeAttributeTypes | ||
304 | Uns32 numPoints | ||
305 | Uns32 numVertexAttributeTypes | ||
306 | TriMeshTriangleData triangles[numTriangles] | ||
307 | TriMeshEdgeData edges[numEdges] | ||
308 | Point3D points[numPoints] | ||
309 | BoundingBox bBox | ||
310 | */ | ||
311 | |||
312 | static guint32 x3dmf_read_tmsh(G3DStream *stream, G3DObject *object, | ||
313 | G3DContext *context) | ||
314 | { | ||
315 | G3DFace *face; | ||
316 | guint32 nread = 0, nfaces, nverts, nedges; | ||
317 | gint32 i, j; | ||
318 | |||
319 | nfaces = g3d_stream_read_int32_be(stream); /* numTriangles */ | ||
320 | nread += 4; | ||
321 | |||
322 | g3d_stream_read_int32_be(stream); /* numTriangleAttributeTypes */ | ||
323 | nread += 4; | ||
324 | |||
325 | nedges = g3d_stream_read_int32_be(stream); /* numEdges */ | ||
326 | nread += 4; | ||
327 | |||
328 | g3d_stream_read_int32_be(stream); /* numEdgeAttributeTypes */ | ||
329 | nread += 4; | ||
330 | |||
331 | nverts = g3d_stream_read_int32_be(stream); /* numPoints */ | ||
332 | nread += 4; | ||
333 | |||
334 | g3d_stream_read_int32_be(stream); /* numVertexAttributeTypes */ | ||
335 | nread += 4; | ||
336 | |||
337 | #if DEBUG > 3 | ||
338 | g_debug("3DMF: [tmsh] %d faces, %d edges, %d vertices", | ||
339 | nfaces, nedges, nverts); | ||
340 | #endif | ||
341 | |||
342 | /* triangles */ | ||
343 | for(i = 0; i < nfaces; i ++) { | ||
344 | face = g_new0(G3DFace, 1); | ||
345 | |||
346 | face->vertex_count = 3; | ||
347 | face->vertex_indices = g_new0(guint32, 3); | ||
348 | for(j = 0; j < 3; j ++) { | ||
349 | face->vertex_indices[j] = | ||
350 | x3dmf_read_packed(stream, nfaces, &nread); | ||
351 | if(face->vertex_indices[j] >= nverts) { | ||
352 | g_warning("face index error: %u >= %u", | ||
353 | face->vertex_indices[j], nverts); | ||
354 | face->vertex_indices[j] = 0; | ||
355 | } | ||
356 | } | ||
357 | |||
358 | #if DEBUG > 3 | ||
359 | g_debug("face %u (packed): %u %u %u", i, face->vertex_indices[0], | ||
360 | face->vertex_indices[1], face->vertex_indices[2]); | ||
361 | #endif | ||
362 | |||
363 | face->material = g_slist_nth_data(object->materials, 0); | ||
364 | object->faces = g_slist_prepend(object->faces, face); | ||
365 | } | ||
366 | |||
367 | /* edges */ | ||
368 | for(i = 0; i < nedges; i ++) { | ||
369 | /* pointIndices */ | ||
370 | x3dmf_read_packed(stream, nedges, &nread); | ||
371 | x3dmf_read_packed(stream, nedges, &nread); | ||
372 | /* triangleIndices */ | ||
373 | x3dmf_read_packed(stream, nedges, &nread); | ||
374 | x3dmf_read_packed(stream, nedges, &nread); | ||
375 | } | ||
376 | |||
377 | /* points */ | ||
378 | object->vertex_count = nverts; | ||
379 | object->vertex_data = g_new0(G3DFloat, 3 * nverts); | ||
380 | for(i = 0; i < nverts; i ++) { | ||
381 | object->vertex_data[i * 3 + 0] = g3d_stream_read_float_be(stream); | ||
382 | object->vertex_data[i * 3 + 1] = g3d_stream_read_float_be(stream); | ||
383 | object->vertex_data[i * 3 + 2] = g3d_stream_read_float_be(stream); | ||
384 | nread += 12; | ||
385 | } | ||
386 | |||
387 | /* bBox */ | ||
388 | /* Point3D min */ | ||
389 | g3d_stream_read_float_be(stream); | ||
390 | g3d_stream_read_float_be(stream); | ||
391 | g3d_stream_read_float_be(stream); | ||
392 | nread += 12; | ||
393 | /* Point3D max */ | ||
394 | g3d_stream_read_float_be(stream); | ||
395 | g3d_stream_read_float_be(stream); | ||
396 | g3d_stream_read_float_be(stream); | ||
397 | nread += 12; | ||
398 | /* boolean isEmpty */ | ||
399 | g3d_stream_read_int32_be(stream); | ||
400 | nread += 4; | ||
401 | |||
402 | return nread; | ||
403 | } | ||
404 | |||
405 | static gboolean x3dmf_read_rfrn(G3DStream *stream, G3DModel *model, | ||
406 | X3dmfToc *toc, G3DContext *context) | ||
407 | { | ||
408 | G3DObject *object; | ||
409 | guint32 id, i, refid, savedoffset; | ||
410 | gsize len; | ||
411 | X3dmfTocEntry *tocentry = NULL; | ||
412 | |||
413 | refid = g3d_stream_read_int32_be(stream); | ||
414 | if(refid == 0) { | ||
415 | /* FIXME */ | ||
416 | return FALSE; | ||
417 | } | ||
418 | |||
419 | if(toc == NULL) { | ||
420 | return FALSE; | ||
421 | } | ||
422 | |||
423 | /* find reference object */ | ||
424 | for(i = 0; i < toc->num_entries; i ++) | ||
425 | if(toc->entries[i].id == refid) | ||
426 | tocentry = &(toc->entries[i]); | ||
427 | |||
428 | g_return_val_if_fail(tocentry != NULL, FALSE); | ||
429 | |||
430 | savedoffset = g3d_stream_tell(stream); | ||
431 | g3d_stream_seek(stream, tocentry->offset, G_SEEK_SET); | ||
432 | |||
433 | object = x3dmf_object_new(stream, model); | ||
434 | |||
435 | g3d_iff_read_chunk(stream, &id, &len, 0); | ||
436 | switch(id) { | ||
437 | case G3D_IFF_MKID('c', 't', 'n', 'r'): | ||
438 | x3dmf_read_container(stream, len, model, NULL, 0xFF, toc, context); | ||
439 | break; | ||
440 | |||
441 | default: | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | g3d_stream_seek(stream, savedoffset, G_SEEK_SET); | ||
446 | |||
447 | return TRUE; | ||
448 | } | ||
449 | |||
450 | static gboolean x3dmf_read_container(G3DStream *stream, guint32 length, | ||
451 | G3DModel *model, G3DObject *object, guint32 level, X3dmfToc *toc, | ||
452 | G3DContext *context) | ||
453 | { | ||
454 | G3DMaterial *material = NULL; | ||
455 | X3dmfChunkDesc *chunkdesc; | ||
456 | guint32 id, chk, i; | ||
457 | gsize len; | ||
458 | G3DFloat matrix[16]; | ||
459 | |||
460 | g3d_matrix_identity(matrix); | ||
461 | |||
462 | while(length > 0) { | ||
463 | if(g3d_stream_eof(stream)) | ||
464 | break; | ||
465 | |||
466 | g3d_iff_read_chunk(stream, &id, &len, 0); | ||
467 | length -= 8; | ||
468 | |||
469 | if(id == 0) | ||
470 | return FALSE; | ||
471 | |||
472 | chunkdesc = x3dmf_get_chunk_info(id); | ||
473 | |||
474 | #if DEBUG > 0 | ||
475 | g_debug("\\%s[%c%c%c%c]: %s (%d bytes)", debug_pad(level), | ||
476 | X3DMF_CHUNK_CHAR(id, 24), X3DMF_CHUNK_CHAR(id, 16), | ||
477 | X3DMF_CHUNK_CHAR(id, 8), X3DMF_CHUNK_CHAR(id, 0), | ||
478 | chunkdesc ? chunkdesc->description : "unknown chunk", | ||
479 | len); | ||
480 | #endif | ||
481 | length -= len; | ||
482 | |||
483 | switch(id) { | ||
484 | case G3D_IFF_MKID('c', 'n', 't', 'r'): | ||
485 | /* container */ | ||
486 | #if DEBUG > 0 | ||
487 | g_debug("|%snew container @ 0x%x (%d bytes)", | ||
488 | debug_pad(level - 1), | ||
489 | (guint32)g3d_stream_tell(stream) - 8, len); | ||
490 | #endif | ||
491 | x3dmf_read_container(stream, len, model, object, level + 1, | ||
492 | toc, context); | ||
493 | break; | ||
494 | |||
495 | case G3D_IFF_MKID('k', 'd', 'i', 'f'): | ||
496 | /* diffuse color */ | ||
497 | if(object) { | ||
498 | #if DEBUG > 2 | ||
499 | g_debug("3DMF: kdif: got object"); | ||
500 | #endif | ||
501 | material = g_slist_nth_data(object->materials, 0); | ||
502 | material->r = g3d_stream_read_float_be(stream); | ||
503 | material->g = g3d_stream_read_float_be(stream); | ||
504 | material->b = g3d_stream_read_float_be(stream); | ||
505 | } else { | ||
506 | g3d_stream_skip(stream, len); | ||
507 | } | ||
508 | break; | ||
509 | |||
510 | case G3D_IFF_MKID('k', 's', 'p', 'c'): | ||
511 | /* specular color */ | ||
512 | if(object) { | ||
513 | #if DEBUG > 2 | ||
514 | g_debug("3DMF: kspc: got object"); | ||
515 | #endif | ||
516 | material = g_slist_nth_data(object->materials, 0); | ||
517 | material->specular[0] = g3d_stream_read_float_be(stream); | ||
518 | material->specular[1] = g3d_stream_read_float_be(stream); | ||
519 | material->specular[2] = g3d_stream_read_float_be(stream); | ||
520 | } else { | ||
521 | g3d_stream_skip(stream, len); | ||
522 | } | ||
523 | break; | ||
524 | |||
525 | case G3D_IFF_MKID('k', 'x', 'p', 'r'): | ||
526 | /* transparency color */ | ||
527 | if(object) { | ||
528 | /* use average as alpha */ | ||
529 | material = g_slist_nth_data(object->materials, 0); | ||
530 | material->a = 1.0 - | ||
531 | (g3d_stream_read_float_be(stream) + | ||
532 | g3d_stream_read_float_be(stream) + | ||
533 | g3d_stream_read_float_be(stream)) / 3.0; | ||
534 | |||
535 | if(material->a < 0.1) | ||
536 | material->a = 0.1; | ||
537 | } else { | ||
538 | g3d_stream_skip(stream, len); | ||
539 | } | ||
540 | break; | ||
541 | |||
542 | case G3D_IFF_MKID('m', 'e', 's', 'h'): | ||
543 | /* mesh */ | ||
544 | if(object == NULL) | ||
545 | object = x3dmf_object_new(stream, model); | ||
546 | material = g_slist_nth_data(object->materials, 0); | ||
547 | |||
548 | chk = x3dmf_read_mesh(stream, object, context); | ||
549 | g3d_object_transform(object, matrix); | ||
550 | if(chk != len) { | ||
551 | g_warning("3DMF: mesh: wrong length (%u != %u)\n", | ||
552 | chk, (unsigned int) len); | ||
553 | return FALSE; | ||
554 | } | ||
555 | break; | ||
556 | |||
557 | case G3D_IFF_MKID('m', 't', 'r', 'x'): | ||
558 | /* matrix */ | ||
559 | for(i = 0; i < 16; i ++) | ||
560 | matrix[i] = g3d_stream_read_float_be(stream); | ||
561 | if(object) { | ||
562 | #if DEBUG > 2 | ||
563 | g_debug("3DMF: mtrx: object is set"); | ||
564 | #endif | ||
565 | g3d_object_transform(object, matrix); | ||
566 | } | ||
567 | #if DEBUG > 3 | ||
568 | for(i = 0; i < 4; i ++) | ||
569 | g_debug("3DMF: mtrx: %+1.2f %+1.2f %+1.2f %+1.2f", | ||
570 | matrix[i * 4 + 0], matrix[i * 4 + 1], | ||
571 | matrix[i * 4 + 2], matrix[i * 4 + 3]); | ||
572 | #endif | ||
573 | break; | ||
574 | |||
575 | case G3D_IFF_MKID('r', 'f', 'r', 'n'): | ||
576 | /* reference */ | ||
577 | x3dmf_read_rfrn(stream, model, toc, context); | ||
578 | break; | ||
579 | |||
580 | case G3D_IFF_MKID('s', 'e', 't', ' '): | ||
581 | /* ??: skip this cntr chunk */ | ||
582 | g3d_stream_skip(stream, length); | ||
583 | length = 0; | ||
584 | break; | ||
585 | |||
586 | case G3D_IFF_MKID('t', 'm', 's', 'h'): | ||
587 | /* triangle mesh */ | ||
588 | if(object == NULL) | ||
589 | object = x3dmf_object_new(stream, model); | ||
590 | material = g_slist_nth_data(object->materials, 0); | ||
591 | |||
592 | chk = x3dmf_read_tmsh(stream, object, context); | ||
593 | g3d_object_transform(object, matrix); | ||
594 | if(chk != len) { | ||
595 | #if DEBUG > 0 | ||
596 | g_debug("3DMF: tmsh: offset %d bytes", len - chk); | ||
597 | #endif | ||
598 | g3d_stream_skip(stream, len - chk); | ||
599 | } | ||
600 | break; | ||
601 | |||
602 | case G3D_IFF_MKID('t', 'r', 'n', 's'): | ||
603 | /* translate */ | ||
604 | if(object) { | ||
605 | G3DFloat x,y,z; | ||
606 | G3DFloat matrix[16]; | ||
607 | |||
608 | x = g3d_stream_read_float_be(stream); | ||
609 | y = g3d_stream_read_float_be(stream); | ||
610 | z = g3d_stream_read_float_be(stream); | ||
611 | |||
612 | g3d_matrix_identity(matrix); | ||
613 | g3d_matrix_translate(x, y, z, matrix); | ||
614 | |||
615 | g3d_object_transform(object, matrix); | ||
616 | } else { | ||
617 | #if DEBUG > 0 | ||
618 | g_warning("3DMF: [trns] no object"); | ||
619 | #endif | ||
620 | g3d_stream_skip(stream, 12); | ||
621 | } | ||
622 | break; | ||
623 | |||
624 | default: | ||
625 | if(chunkdesc) { | ||
626 | g3d_stream_skip(stream, len); | ||
627 | } else { | ||
628 | #if DEBUG > 0 | ||
629 | g_warning("3DMF: Container: unknown chunk '%c%c%c%c'/" | ||
630 | "0x%02X%02X%02X%02X @ 0x%08x " | ||
631 | "(%d bytes)", | ||
632 | X3DMF_CHUNK_CHAR(id, 24), X3DMF_CHUNK_CHAR(id, 16), | ||
633 | X3DMF_CHUNK_CHAR(id, 8), X3DMF_CHUNK_CHAR(id, 0), | ||
634 | X3DMF_CHUNK_CHAR(id, 24), X3DMF_CHUNK_CHAR(id, 16), | ||
635 | X3DMF_CHUNK_CHAR(id, 8), X3DMF_CHUNK_CHAR(id, 0), | ||
636 | (guint32)g3d_stream_tell(stream) - 8, len); | ||
637 | #endif | ||
638 | g3d_stream_skip(stream, len); | ||
639 | } | ||
640 | break; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | return TRUE; | ||
645 | } | ||
646 | |||