aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c446
1 files changed, 446 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c
new file mode 100644
index 0000000..6b2eff6
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ar/imp_ar_dof.c
@@ -0,0 +1,446 @@
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 <g3d/types.h>
24#include <g3d/stream.h>
25#include <g3d/texture.h>
26#include <g3d/material.h>
27#include <g3d/iff.h>
28
29gchar *ar_dof_read_string(G3DStream *stream, gint32 *dlen)
30{
31 gint32 len;
32 gchar *text;
33
34 len = g3d_stream_read_int16_le(stream);
35 *dlen -= 2;
36
37 text = g_new0(gchar, len + 1);
38 g3d_stream_read(stream, text, len);
39 *dlen -= len;
40
41 return text;
42}
43
44G3DMaterial *ar_dof_load_mat(G3DContext *context, G3DModel *model,
45 G3DStream *stream)
46{
47 G3DMaterial *material;
48 gint32 id, len = 0, dlen, i, ntex, trans = 0, blend = 0;
49 gchar *tmp;
50
51 id = g3d_stream_read_int32_be(stream);
52 if(id != G3D_IFF_MKID('M','A','T','0'))
53 return NULL;
54
55 material = g3d_material_new();
56
57 dlen = g3d_stream_read_int32_le(stream);
58 do {
59 id = g3d_stream_read_int32_be(stream);
60 if(id != G3D_IFF_MKID('M','E','N','D'))
61 len = g3d_stream_read_int32_le(stream);
62
63 switch(id) {
64 case G3D_IFF_MKID('M','E','N','D'):
65 break;
66
67 case G3D_IFF_MKID('M','H','D','R'):
68 material->name = ar_dof_read_string(stream, &dlen);
69 tmp = ar_dof_read_string(stream, &dlen);
70 g_free(tmp);
71 break;
72
73 case G3D_IFF_MKID('M','C','O','L'):
74 /* ambient */
75 material->r = g3d_stream_read_float_le(stream);
76 material->g = g3d_stream_read_float_le(stream);
77 material->b = g3d_stream_read_float_le(stream);
78 material->a = g3d_stream_read_float_le(stream);
79 dlen -= 16;
80 /* diffuse */
81 g3d_stream_skip(stream, 16);
82 dlen -= 16;
83 /* specular */
84 material->specular[0] = g3d_stream_read_float_le(stream);
85 material->specular[1] = g3d_stream_read_float_le(stream);
86 material->specular[2] = g3d_stream_read_float_le(stream);
87 material->specular[3] = g3d_stream_read_float_le(stream);
88 dlen -= 16;
89 /* emission */
90 g3d_stream_skip(stream, 16);
91 dlen -= 16;
92 /* shininess */
93 material->shininess = g3d_stream_read_float_le(stream);
94 dlen -= 4;
95 break;
96
97 case G3D_IFF_MKID('M','T','E','X'):
98 ntex = g3d_stream_read_int32_le(stream);
99 dlen -= 4;
100 for(i = 0; i < ntex; i ++) {
101 tmp = ar_dof_read_string(stream, &dlen);
102 if(i == 0) {
103 material->tex_image =
104 g3d_texture_load_cached(context, model, tmp);
105 if(material->tex_image)
106 material->tex_image->tex_id = g_str_hash(tmp);
107 }
108 g_free(tmp);
109 }
110 break;
111
112 case G3D_IFF_MKID('M','T','R','A'):
113 /* transparency */
114 trans = g3d_stream_read_int32_le(stream);
115 /* blend mode */
116 blend = g3d_stream_read_int32_le(stream);
117
118 printf("D: MTRA: %s: trans: 0x%04x, blend: 0x%04x\n",
119 (material->name ? material->name : "unnamed"),
120 trans, blend);
121
122 dlen -= 8;
123 break;
124
125 case G3D_IFF_MKID('M','C','F','L'):
126 /* creation flags */
127 g3d_stream_read_int32_le(stream);
128 dlen -= 4;
129 break;
130
131 case G3D_IFF_MKID('M','U','V','W'):
132 /* u offset */
133 g3d_stream_read_int32_le(stream);
134 /* v offset */
135 g3d_stream_read_int32_le(stream);
136 dlen -= 8;
137
138 /* u tiling */
139 g3d_stream_read_int32_le(stream);
140 /* v tiling */
141 g3d_stream_read_int32_le(stream);
142 dlen -= 8;
143
144 /* angle */
145 g3d_stream_read_float_le(stream);
146 /* blur */
147 g3d_stream_read_float_le(stream);
148 /* blur offset */
149 g3d_stream_read_int32_le(stream);
150 dlen -= 12;
151 break;
152
153 default:
154 g3d_stream_skip(stream, len);
155 dlen -= len;
156 break;
157 }
158 }
159 while((dlen > 0) && (id != G3D_IFF_MKID('M','E','N','D')));
160
161 if(material->tex_image != NULL) {
162 if(blend == 1)
163 material->tex_image->tex_env = G3D_TEXENV_BLEND;
164 else
165 material->tex_image->tex_env = G3D_TEXENV_DECAL;
166 }
167
168 return material;
169}
170
171G3DObject *ar_dof_load_obj(G3DContext *context, G3DModel *model,
172 G3DStream *stream)
173{
174 G3DObject *object, *pobj;
175 G3DFace *face;
176 G3DMaterial *material;
177 GSList *item;
178 gint32 id, len = 0, dlen, nverts, ntver, nnorm, nind, i, j, index;
179 G3DFloat *tex_vertices = NULL, *normals = NULL;
180
181 id = g3d_stream_read_int32_be(stream);
182 dlen = g3d_stream_read_int32_le(stream);
183
184 if(id != G3D_IFF_MKID('G','O','B','1')) {
185 g3d_stream_skip(stream, dlen);
186 return NULL;
187 }
188
189 object = g_new0(G3DObject, 1);
190 object->name = g_strdup_printf("object @ 0x%08x",
191 (guint32)g3d_stream_tell(stream));
192
193 /* parent object for material references */
194 pobj = (G3DObject *)g_slist_nth_data(model->objects, 0);
195
196 /* default material */
197 material = (G3DMaterial *)g_slist_nth_data(model->materials, 0);
198
199 do {
200 id = g3d_stream_read_int32_be(stream);
201 if(id != G3D_IFF_MKID('G','E','N','D'))
202 len = g3d_stream_read_int32_le(stream);
203
204 switch(id) {
205 case G3D_IFF_MKID('G','E','N','D'):
206 /* end of object */
207 break;
208
209 case G3D_IFF_MKID('G','H','D','R'):
210 /* object header */
211 /* flags */
212 i = g3d_stream_read_int32_le(stream);
213 printf("D: GHDR: flags = 0x%04X\n", i);
214 /* paint flags */
215 i = g3d_stream_read_int32_le(stream);
216 printf("D: GHDR: paint flags = 0x%04X\n", i);
217
218 /* material ref */
219 i = g3d_stream_read_int32_le(stream);
220 material = g_slist_nth_data(pobj->materials, i);
221 if(material == NULL)
222 material = (G3DMaterial *)g_slist_nth_data(
223 model->materials, 0);
224
225 dlen -= 12;
226 break;
227
228 case G3D_IFF_MKID('V','E','R','T'):
229 /* vertices */
230 nverts = g3d_stream_read_int32_le(stream);
231
232#if DEBUG > 2
233 printf("D: %d vertices\n", nverts);
234#endif
235
236 dlen -= 4;
237 if(nverts > 0) {
238 object->vertex_count = nverts;
239 object->vertex_data = g_new0(G3DFloat, nverts * 3);
240 for(i = 0; i < nverts; i ++) {
241 for(j = 0; j < 3; j ++)
242 object->vertex_data[i * 3 + j] =
243 g3d_stream_read_float_le(stream);
244 dlen -= 12;
245 }
246 }
247 break;
248
249 case G3D_IFF_MKID('N', 'O','R','M'):
250 /* normals */
251 nnorm = g3d_stream_read_int32_le(stream);
252 normals = g_new0(G3DFloat, nnorm * 3);
253 dlen -= 4;
254 for(i = 0; i < nnorm; i ++) {
255 for(j = 0; j < 3; j ++)
256 normals[i * 3 + j] = g3d_stream_read_float_le(stream);
257 dlen -= 12;
258 }
259 break;
260
261 case G3D_IFF_MKID('T', 'V','E','R'):
262 /* texture vertices */
263 ntver = g3d_stream_read_int32_le(stream);
264 tex_vertices = g_new0(G3DFloat, ntver * 2);
265 dlen -= 4;
266
267#if DEBUG > 2
268 printf("D: %d texture vertices @ 0x%08x\n", ntver,
269 (guint32)g3d_stream_tell(stream) - 12);
270#endif
271
272 for(i = 0; (i < ntver) && (len > 0); i ++) {
273 tex_vertices[i * 2 + 0] = g3d_stream_read_float_le(stream);
274 tex_vertices[i * 2 + 1] =
275 1.0 - g3d_stream_read_float_le(stream);
276 dlen -= 8;
277 }
278 break;
279
280 case G3D_IFF_MKID('B','R','S','T'):
281 /* bursts */
282 i = g3d_stream_read_int32_le(stream);
283 dlen -= 4;
284 g3d_stream_skip(stream, i * 4); /* burstStart */
285 g3d_stream_skip(stream, i * 4); /* burstCount */
286 g3d_stream_skip(stream, i * 4); /* burstMtlID */
287 g3d_stream_skip(stream, i * 4); /* burstVperP */
288 dlen -= (4 * 4 * i);
289 break;
290
291 case G3D_IFF_MKID('V','C','O','L'):
292 /* vertex colors */
293 i = g3d_stream_read_int32_le(stream);
294 dlen -= 4;
295 g3d_stream_skip(stream, i * 4 * 3);
296 dlen -= (i * 4 * 3);
297 break;
298
299 case G3D_IFF_MKID('I','N','D','I'):
300 /* indices */
301 nind = g3d_stream_read_int32_le(stream);
302 dlen -= 4;
303 len -= 4;
304
305#if DEBUG > 2
306 printf("D: %d indices in %d bytes\n", nind, len);
307#endif
308
309 for(i = 0; i < nind; i += 3) {
310 face = g_new0(G3DFace, 1);
311 face->material = material;
312 face->vertex_count = 3;
313 face->vertex_indices = g_new0(guint32, 3);
314
315 for(j = 0; j < 3; j ++)
316 face->vertex_indices[j] =
317 g3d_stream_read_int16_le(stream);
318 dlen -= 6;
319 len -= 6;
320
321 object->faces = g_slist_append(object->faces, face);
322 }
323 break;
324
325 default:
326#if DEBUG > 0
327 printf("D: skipping tag '%c%c%c%c @ 0x%08x'\n",
328 (id << 24) & 0xFF, (id << 16) & 0xFF,
329 (id << 8) & 0xFF, id & 0xFF,
330 (guint32)g3d_stream_tell(stream));
331#endif
332 g3d_stream_skip(stream, len);
333 dlen -= len;
334 break;
335 }
336 } while((dlen > 0) && (id != G3D_IFF_MKID('G','E','N','D')));
337
338 /* fix faces with normals and texture vertices */
339 for(item = object->faces; item != NULL; item = item->next) {
340 face = (G3DFace *)item->data;
341
342 if(tex_vertices != NULL) {
343 face->tex_image = material->tex_image;
344 face->tex_vertex_count = 3;
345 face->tex_vertex_data = g_new0(G3DFloat, 3 * 2);
346 for(j = 0; j < 3; j ++) {
347 index = face->vertex_indices[j];
348 face->tex_vertex_data[j * 2 + 0] = tex_vertices[index * 2 + 0];
349 face->tex_vertex_data[j * 2 + 1] = tex_vertices[index * 2 + 1];
350 }
351 if(face->tex_image != NULL)
352 face->flags |= G3D_FLAG_FAC_TEXMAP;
353 }
354
355 if(normals != NULL) {
356 face->normals = g_new0(G3DFloat, 3 * 3);
357 for(j = 0; j < 3; j ++) {
358 index = face->vertex_indices[j];
359 face->normals[j * 3 + 0] = normals[index * 3 + 0];
360 face->normals[j * 3 + 1] = normals[index * 3 + 1];
361 face->normals[j * 3 + 2] = normals[index * 3 + 2];
362 }
363 face->flags |= G3D_FLAG_FAC_NORMALS;
364 }
365 }
366
367 /* cleanup */
368 if(tex_vertices != NULL)
369 g_free(tex_vertices);
370
371 if(normals != NULL)
372 g_free(normals);
373
374 return object;
375}
376
377G3DObject *ar_dof_load(G3DContext *context, G3DModel *model,
378 G3DStream *stream)
379{
380 gint32 id, dlen, len = 0, nmat, nobj, i;
381 G3DObject *object, *cobj;
382 G3DMaterial *material;
383
384 /* file is little-endian, but read IDs as big-endian to use
385 * G3D_IFF_MKID to compare */
386
387 id = g3d_stream_read_int32_be(stream);
388 if(id != G3D_IFF_MKID('D','O','F','1')) {
389 g_warning("%s is not a DOF1 file\n", stream->uri);
390 return NULL;
391 }
392 dlen = g3d_stream_read_int32_le(stream);
393
394 object = g_new0(G3DObject, 1);
395 object->name = g_strdup(stream->uri);
396 model->objects = g_slist_append(model->objects, object);
397
398 do {
399 id = g3d_stream_read_int32_be(stream);
400 if(id != G3D_IFF_MKID('E','D','O','F'))
401 len = g3d_stream_read_int32_le(stream);
402 dlen -= 8;
403
404 switch(id) {
405 case G3D_IFF_MKID('E','D','O','F'):
406 /* end of DOF */
407 break;
408
409 case G3D_IFF_MKID('M','A','T','S'):
410 nmat = g3d_stream_read_int32_le(stream);
411 for(i = 0; i < nmat; i ++) {
412 material = ar_dof_load_mat(context, model, stream);
413 if(material)
414 object->materials = g_slist_append(object->materials,
415 material);
416 }
417 dlen -= len;
418 break;
419
420 case G3D_IFF_MKID('G','E','O','B'):
421 nobj = g3d_stream_read_int32_le(stream);
422 for(i = 0; i < nobj; i ++) {
423 cobj = ar_dof_load_obj(context, model, stream);
424 if(cobj)
425 object->objects =
426 g_slist_append(object->objects, cobj);
427 }
428 dlen -= len;
429 break;
430
431 default:
432 g_warning("DOF: unknown ID '%c%c%c%c' @ 0x%08x",
433 (id >> 24) & 0xFF, (id >> 16) & 0xFF,
434 (id >> 8) & 0xFF, id & 0xFF,
435 (guint32)g3d_stream_tell(stream) - 8);
436 g3d_stream_skip(stream, len);
437 dlen -= len;
438 break;
439 }
440 } while((dlen > 0) &&
441 (id != G3D_IFF_MKID('E','D','O','F')) &&
442 (!g3d_stream_eof(stream)));
443
444 return object;
445}
446