aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c418
1 files changed, 418 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c
new file mode 100644
index 0000000..01505b4
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_r4/imp_r4_callbacks.c
@@ -0,0 +1,418 @@
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#include <g3d/iff.h>
23#include <g3d/stream.h>
24#include <g3d/material.h>
25#include <g3d/matrix.h>
26#include <g3d/vector.h>
27
28#include "imp_r4_chunks.h"
29
30#if DEBUG > 0
31static void hexdump(G3DStream *stream, guint32 len, gchar *prefix)
32{
33 guint32 i;
34 guint8 byte;
35
36 for(i = 0; i < len; i ++)
37 {
38 byte = g3d_stream_read_int8(stream);
39 if(((i % 16) == 0) && (i != 0))
40 g_print("\n");
41 if(((i % 16) == 0) && (i != (len - 1)))
42 g_print("%s: %06x: ", (prefix ? prefix : ""), i);
43 g_print("%02x", byte);
44 if((i % 4) == 3)
45 g_print(" ");
46 }
47 g_print("\n");
48}
49#endif
50
51static void dump_remaining(G3DIffGlobal *global, G3DIffLocal *local)
52{
53#if DEBUG > 0
54 gchar *id, *prefix;
55
56 id = g3d_iff_id_to_text(local->id);
57 prefix = g_strdup_printf("R4: %s", id);
58
59 if(local->nb > 0)
60 {
61 printf("R4: %s: %d bytes remaining @ 0x%08x\n", id, local->nb,
62 (guint32)g3d_stream_tell(global->stream));
63 hexdump(global->stream, local->nb, prefix);
64 local->nb = 0;
65 }
66
67 g_free(prefix);
68 g_free(id);
69#endif
70}
71
72#if DEBUG > 0
73static void flagstat_register(guint8 flags, guint32 *flagstats)
74{
75 guint32 i;
76
77 for(i = 0; i < 8; i ++)
78 if(flags & (1 << i))
79 flagstats[i] ++;
80}
81#endif
82
83static gchar *r4_read_string(G3DStream *stream, guint32 *r)
84{
85 gint32 len;
86 gchar *str;
87
88 len = g3d_stream_read_int16_be(stream);
89 str = g_malloc0(len + 1);
90 g3d_stream_read(stream, str, len);
91
92 if(r)
93 *r = len + 2;
94 return str;
95}
96
97/* triangles */
98gboolean r4_cb_DRE2(G3DIffGlobal *global, G3DIffLocal *local)
99{
100 G3DObject *object;
101 G3DFace *face;
102 guint32 ntris, r;
103 gint32 i, n_str;
104 guint8 u, max_u = 0;
105 gchar *name;
106#if DEBUG > 0
107 guint32 flagstats[8];
108#endif
109
110 object = g_new0(G3DObject, 1);
111 object->name = g_strdup("(default)");
112 global->model->objects = g_slist_append(global->model->objects, object);
113 local->object = object;
114
115 /* RGE1 */
116 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
117
118#if DEBUG > 2
119 printf("R4: DRE2 offset after RGE1 chunk: 0x%08x\n",
120 (guint32)g3d_stream_tell(global->stream));
121#endif
122
123 /* read triangles */
124 ntris = g3d_stream_read_int32_be(global->stream);
125#if DEBUG > 0
126 printf("R4: DRE2: %d triangles\n", ntris);
127#endif
128 local->nb -= 4;
129 for(i = 0; i < ntris; i ++)
130 {
131 face = g_new0(G3DFace, 1);
132 face->material = g_slist_nth_data(global->model->materials, 0);
133 face->vertex_count = 3;
134 face->vertex_indices = g_new0(guint32, 3);
135 face->vertex_indices[0] = g3d_stream_read_int32_be(global->stream);
136 face->vertex_indices[1] = g3d_stream_read_int32_be(global->stream);
137 face->vertex_indices[2] = g3d_stream_read_int32_be(global->stream);
138 local->nb -= 12;
139 object->faces = g_slist_append(object->faces, face);
140 }
141
142#if DEBUG > 0
143 /* flags/index of material? */
144 for(i = 0; i < 8; i ++)
145 flagstats[i] = 0;
146#endif
147
148 for(i = 0; i < ntris; i ++)
149 {
150 u = g3d_stream_read_int8(global->stream);
151 local->nb --;
152 if(u > max_u)
153 max_u = u;
154#if DEBUG > 0
155 flagstat_register(u, flagstats);
156#endif
157 }
158
159#if DEBUG > 0
160 for(i = 0; i < 8; i ++)
161 printf("R4: DRE2: flag 2^%d: %u\n", i, flagstats[i]);
162#endif
163
164#if DEBUG > 0
165 printf("R4: DRE2: max. flag: %d\n", max_u);
166#endif
167
168#if 1
169 /* some strings */
170 n_str = g3d_stream_read_int32_be(global->stream);
171 /* may be 0xFFFFFFFF = -1 */
172 local->nb -= 4;
173 g_debug("R4: DRE2: %d string(s) @ 0x%08x:", n_str,
174 (guint32)g3d_stream_tell(global->stream));
175 for(i = 0; i < MIN(n_str, 1); i ++) {
176 name = r4_read_string(global->stream, &r);
177 local->nb -= r;
178#if DEBUG > 0
179 g_debug("R4: DRE2: '%s' (%d)", name, r - 2);
180#endif
181 g_free(name);
182 }
183#endif
184
185 dump_remaining(global, local);
186
187 /* remove transformation if set */
188 if(object->transformation)
189 {
190 g_free(object->transformation);
191 object->transformation = NULL;
192 }
193
194 return TRUE;
195}
196
197/* material: GMAT, GMA0 */
198gboolean r4_cb_GMAx(G3DIffGlobal *global, G3DIffLocal *local)
199{
200 G3DMaterial *material;
201 gpointer object;
202
203 /* ROBJ */
204 object = g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
205
206 if(object)
207 {
208 material = g3d_material_new();
209 material->name = g_convert((gchar *)object, -1,
210 "UTF-8", "ISO-8859-1",
211 NULL, NULL, NULL);
212 g_free(object);
213
214 if(local->object)
215 ((G3DObject *)local->object)->materials = g_slist_append(
216 ((G3DObject *)local->object)->materials, material);
217 else
218 global->model->materials = g_slist_append(global->model->materials,
219 material);
220
221 if(local->id == G3D_IFF_MKID('G','M','A','T'))
222 {
223 material->r = g3d_stream_read_float_be(global->stream);
224 material->g = g3d_stream_read_float_be(global->stream);
225 material->b = g3d_stream_read_float_be(global->stream);
226 local->nb -= 12;
227 }
228 }
229
230 dump_remaining(global, local);
231
232 return TRUE;
233}
234
235/* coordinate system */
236gboolean r4_cb_KSYS(G3DIffGlobal *global, G3DIffLocal *local)
237{
238 G3DFloat x, y, z, f;
239 G3DObject *object;
240 G3DTransformation *transform;
241 gint32 i, j;
242
243 x = g3d_stream_read_float_be(global->stream);
244 y = g3d_stream_read_float_be(global->stream);
245 z = g3d_stream_read_float_be(global->stream);
246 local->nb -= 12;
247
248#if DEBUG > 2
249 printf("R4: KSYS: %f, %f, %f\n", x, y, z);
250#endif
251
252 object = (G3DObject *)local->object;
253 if(object)
254 {
255 transform = g_new0(G3DTransformation, 1);
256 g3d_matrix_identity(transform->matrix);
257 g3d_matrix_translate(x, y, z, transform->matrix);
258
259 object->transformation = transform;
260
261 /* matrix parts */
262 for(j = 0; j < 3; j ++)
263 for(i = 0; i < 3; i ++)
264 transform->matrix[j * 4 + i] = g3d_stream_read_float_be(global->stream);
265 local->nb -= 36;
266
267 /* scale part */
268 f = g3d_stream_read_float_be(global->stream);
269 local->nb -= 4;
270 g3d_matrix_scale(f, f, f, transform->matrix);
271 }
272
273 return TRUE;
274}
275
276/* sphere */
277gboolean r4_cb_KUG1(G3DIffGlobal *global, G3DIffLocal *local)
278{
279 /* RGE1 */
280 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
281
282 dump_remaining(global, local);
283
284 return TRUE;
285}
286
287/* light */
288gboolean r4_cb_LGH3(G3DIffGlobal *global, G3DIffLocal *local)
289{
290 /* RGE1 */
291 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
292
293 return TRUE;
294}
295
296/* points */
297gboolean r4_cb_PKTM(G3DIffGlobal *global, G3DIffLocal *local)
298{
299 gint32 i, j;
300 G3DObject *object;
301
302 object = (G3DObject *)local->object;
303 if(object)
304 {
305 object->vertex_count = g3d_stream_read_int32_be(global->stream);
306 local->nb -= 4;
307 object->vertex_data = g_new0(G3DFloat, object->vertex_count * 3);
308 for(i = 0; i < object->vertex_count; i ++) {
309 for(j = 0; j < 3; j ++)
310 object->vertex_data[i * 3 + j] =
311 g3d_stream_read_float_be(global->stream);
312 local->nb -= 12;
313
314 /* transform vertices */
315 if(object->transformation) {
316 g3d_vector_transform(
317 object->vertex_data + i * 3 + 0,
318 object->vertex_data + i * 3 + 1,
319 object->vertex_data + i * 3 + 2,
320 object->transformation->matrix);
321 }
322 }
323 }
324
325 return TRUE;
326}
327
328/* geometry or something */
329gboolean r4_cb_RGE1(G3DIffGlobal *global, G3DIffLocal *local)
330{
331 gchar *name;
332
333 /* ROBJ */
334 name =
335 (gchar *)g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
336
337 if(name && local->object) {
338 g_free(((G3DObject *)local->object)->name);
339 ((G3DObject *)local->object)->name = g_convert(name, -1,
340 "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
341 }
342
343 /* KSYS */
344 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
345
346 /* PKTM */
347 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
348
349 /* skip remaining bytes */
350 if(local->nb) {
351 g3d_stream_skip(global->stream, local->nb);
352 local->nb = 0;
353 }
354
355 dump_remaining(global, local);
356
357 return TRUE;
358}
359
360/* camera related: RKA2, RKA3 */
361gboolean r4_cb_RKAx(G3DIffGlobal *global, G3DIffLocal *local)
362{
363 /* handle RGE1 chunk */
364 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
365
366 /* more stuff... */
367 /* TODO: */
368
369 return TRUE;
370}
371
372/* object name */
373gboolean r4_cb_ROBJ(G3DIffGlobal *global, G3DIffLocal *local)
374{
375 guint32 len;
376
377 local->level_object = r4_read_string(global->stream, &len);
378 local->nb -= (len + 2);
379
380#if DEBUG > 2
381 g_debug("[R4] ROBJ: %s", (gchar *)local->level_object);
382#endif
383
384 return TRUE;
385}
386
387/* surface: SURF, SUR1 */
388gboolean r4_cb_SURx(G3DIffGlobal *global, G3DIffLocal *local)
389{
390 /* GMAT or GMA1 */
391 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
392
393 dump_remaining(global, local);
394
395 return TRUE;
396}
397
398/* texture material */
399gboolean r4_cb_TXM1(G3DIffGlobal *global, G3DIffLocal *local)
400{
401 /* SURF */
402 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
403
404 dump_remaining(global, local);
405
406 return TRUE;
407}
408
409/* texture object? */
410gboolean r4_cb_TXO1(G3DIffGlobal *global, G3DIffLocal *local)
411{
412 /* RGE1 */
413 g3d_iff_handle_chunk(global, local, r4_chunks, G3D_IFF_PAD1);
414
415 dump_remaining(global, local);
416
417 return TRUE;
418}