aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c584
1 files changed, 584 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c
new file mode 100644
index 0000000..165c3aa
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_lwo/imp_lwo_callbacks.c
@@ -0,0 +1,584 @@
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 <glib.h>
26
27#include <g3d/context.h>
28#include <g3d/stream.h>
29#include <g3d/material.h>
30#include <g3d/texture.h>
31#include <g3d/iff.h>
32#include <g3d/debug.h>
33
34#include "imp_lwo.h"
35
36gboolean lwo_cb_CLIP(G3DIffGlobal *global, G3DIffLocal *local)
37{
38 LwoObject *obj;
39 guint32 index;
40
41 obj = (LwoObject *)global->user_data;
42 g_return_val_if_fail(obj != NULL, FALSE);
43
44 if(!local->finalize)
45 {
46 index = g3d_stream_read_int32_be(global->stream);
47 local->nb -= 4;
48
49 obj->nclips ++;
50 obj->clips = g_realloc(obj->clips, obj->nclips * sizeof(guint32));
51 obj->clipfiles = g_realloc(obj->clipfiles,
52 (obj->nclips + 1) * sizeof(gchar *));
53
54 obj->clips[obj->nclips - 1] = index;
55 obj->clipfiles[obj->nclips - 1] = g_strdup("undef");
56 obj->clipfiles[obj->nclips] = NULL;
57 }
58
59 return TRUE;
60}
61
62gboolean lwo_cb_COLR(G3DIffGlobal *global, G3DIffLocal *local)
63{
64 G3DMaterial *material;
65
66 material = (G3DMaterial *)local->object;
67 g_return_val_if_fail(material != NULL, FALSE);
68
69 if(global->flags & LWO_FLAG_LWO2)
70 {
71 material->r = g3d_stream_read_float_be(global->stream);
72 material->g = g3d_stream_read_float_be(global->stream);
73 material->b = g3d_stream_read_float_be(global->stream);
74 local->nb -= 12;
75 g3d_stream_read_int16_be(global->stream);
76 local->nb -= 2;
77 }
78 else
79 {
80 material->r = g3d_stream_read_int8(global->stream) / 255.0;
81 material->g = g3d_stream_read_int8(global->stream) / 255.0;
82 material->b = g3d_stream_read_int8(global->stream) / 255.0;
83 g3d_stream_read_int8(global->stream);
84 local->nb -= 4;
85 }
86
87 return TRUE;
88}
89
90/* image index */
91gboolean lwo_cb_IMAG(G3DIffGlobal *global, G3DIffLocal *local)
92{
93 LwoObject *obj;
94 G3DMaterial *material;
95 guint32 index, i;
96
97 obj = (LwoObject *)global->user_data;
98 g_return_val_if_fail(obj != NULL, FALSE);
99
100 material = (G3DMaterial *)local->object;
101 g_return_val_if_fail(material != NULL, FALSE);
102
103 local->nb -= lwo_read_vx(global->stream, &index);
104
105 for(i = 0; i < obj->nclips; i ++)
106 {
107 if(obj->clips[i] == index)
108 break;
109 }
110
111 if((i < obj->nclips) && (obj->clips[i] == index))
112 {
113 material->tex_image = g3d_texture_load_cached(
114 global->context, global->model, obj->clipfiles[i]);
115 }
116
117 return TRUE;
118}
119
120/* points */
121gboolean lwo_cb_PNTS(G3DIffGlobal *global, G3DIffLocal *local)
122{
123 LwoObject *obj;
124 G3DObject *object;
125 gint32 i, off;
126
127 obj = (LwoObject *)global->user_data;
128 g_return_val_if_fail(obj != NULL, FALSE);
129
130 if(global->flags & LWO_FLAG_LWO2) {
131 object = lwo_create_object(global->stream, global->model,
132 global->flags);
133 obj->object = object;
134
135 if(obj->tex_vertices) {
136 g_free(obj->tex_vertices);
137 obj->tex_vertices = NULL;
138 }
139 } else {
140 object = (G3DObject *)obj->object;
141 if(object == NULL) {
142 object = lwo_create_object(global->stream, global->model,
143 global->flags);
144 obj->object = object;
145 }
146 }
147 off = object->vertex_count;
148 object->vertex_count += (local->nb / 12);
149 g_return_val_if_fail(object->vertex_count >= 3, FALSE);
150
151 object->vertex_data = g_realloc(object->vertex_data,
152 sizeof(G3DFloat) * object->vertex_count * 3);
153
154 for(i = off; i < object->vertex_count; i ++) {
155 object->vertex_data[i * 3 + 0] =
156 -g3d_stream_read_float_be(global->stream);
157 object->vertex_data[i * 3 + 1] =
158 g3d_stream_read_float_be(global->stream);
159 object->vertex_data[i * 3 + 2] =
160 g3d_stream_read_float_be(global->stream);
161 local->nb -= 12;
162 }
163 return TRUE;
164}
165
166/* polygons */
167gboolean lwo_cb_POLS(G3DIffGlobal *global, G3DIffLocal *local)
168{
169 LwoObject *obj;
170 G3DObject *object;
171 G3DFace *face;
172 gboolean skip_face;
173 guint32 type;
174 gint32 n = 0, i, nmat, det_cnt, cnt;
175 gint16 index;
176 gchar *tmp;
177
178 obj = (LwoObject *)global->user_data;
179 g_return_val_if_fail(obj != NULL, FALSE);
180
181 object = (G3DObject *)obj->object;
182 g_return_val_if_fail(object != NULL, FALSE);
183
184 if(global->flags & LWO_FLAG_LWO2) {
185 type = g3d_stream_read_int32_be(global->stream);
186 local->nb -= 4;
187
188 switch(type) {
189 case G3D_IFF_MKID('F', 'A', 'C', 'E'):
190 case G3D_IFF_MKID('P', 'T', 'C', 'H'):
191 break;
192 default:
193 tmp = g3d_iff_id_to_text(type);
194 g_warning("[LWO] unhandled polygon type %s", tmp);
195 g_free(tmp);
196 return FALSE;
197 }
198 }
199
200 while(local->nb > 0) {
201 n ++;
202 skip_face = FALSE;
203 face = g_new0(G3DFace, 1);
204 face->vertex_count = g3d_stream_read_int16_be(global->stream);
205 local->nb -= 2;
206
207 if(global->flags & LWO_FLAG_LWO2)
208 face->vertex_count &= 0x03FF;
209
210 face->vertex_indices = g_new0(guint32, face->vertex_count);
211
212 if(obj->tex_vertices) {
213 face->flags |= G3D_FLAG_FAC_TEXMAP;
214 face->tex_vertex_count = face->vertex_count;
215 face->tex_vertex_data = g_new0(G3DFloat, face->tex_vertex_count * 2);
216 }
217
218 for(i = 0; i < face->vertex_count; i ++) {
219 if(global->flags & LWO_FLAG_LWO2) {
220 local->nb -= lwo_read_vx(global->stream,
221 &(face->vertex_indices[i]));
222 } else {
223 index = g3d_stream_read_int16_be(global->stream);
224 local->nb -= 2;
225 if(index < 0) {
226 skip_face = TRUE;
227 } else
228 face->vertex_indices[i] = index;
229 }
230
231 if(obj->tex_vertices) {
232 face->tex_vertex_data[i * 2 + 0] =
233 obj->tex_vertices[face->vertex_indices[i] * 2 + 0];
234 face->tex_vertex_data[i * 2 + 1] =
235 obj->tex_vertices[face->vertex_indices[i] * 2 + 1];
236 }
237 } /* i: 0..face->vertex_count */
238
239 if(!(global->flags & LWO_FLAG_LWO2)) {
240 nmat = g3d_stream_read_int16_be(global->stream);
241 local->nb -= 2;
242
243 if(nmat < 0) {
244 /* detail polygons, skipped */
245 det_cnt = g3d_stream_read_int16_be(global->stream);
246 local->nb -= 2;
247 nmat *= -1;
248 while(det_cnt-- > 0) {
249 cnt = g3d_stream_read_int16_be(global->stream);
250 local->nb -= 2;
251 g3d_stream_skip(global->stream, cnt * 2 + 2);
252 local->nb -= cnt * 2 + 2;
253 }
254 } else if(nmat == 0) {
255 nmat = 1;
256 }
257
258 face->material = g_slist_nth_data(global->model->materials, nmat);
259
260 if(face->material == NULL) {
261#if 0
262 g_warning("[LWO] face->material is NULL (#%d)\n", nmat - 1);
263#endif
264 face->material = g_slist_nth_data(global->model->materials, 0);
265 }
266 } /* !LWO2 */ else {
267 face->material = g_slist_nth_data(global->model->materials, 0);
268 } /* LWO2 */
269
270 if(skip_face || (face->vertex_count < 3)) {
271 if(face->tex_vertex_data)
272 g_free(face->tex_vertex_data);
273 g_free(face->vertex_indices);
274 g_free(face);
275 } else {
276 object->faces = g_slist_prepend(object->faces, face);
277 }
278
279 g3d_context_update_interface(global->context);
280 } /* local->nb > 0 */
281
282 return TRUE;
283}
284
285/* poly tag mapping */
286gboolean lwo_cb_PTAG(G3DIffGlobal *global, G3DIffLocal *local)
287{
288 LwoObject *obj;
289 G3DObject *object;
290 G3DMaterial *material, *tmat;
291 G3DFace *face;
292 GSList *mlist;
293 gint32 id, fmax;
294 guint32 poly, tag;
295
296 obj = (LwoObject *)global->user_data;
297 g_return_val_if_fail(obj != NULL, FALSE);
298
299 object = (G3DObject *)obj->object;
300 g_return_val_if_fail(object != NULL, FALSE);
301
302 id = g3d_stream_read_int32_be(global->stream);
303 local->nb -= 4;
304
305 if(id != G3D_IFF_MKID('S','U','R','F'))
306 return FALSE;
307
308 fmax = g_slist_length(object->faces) - 1;
309
310 while(local->nb > 0)
311 {
312 local->nb -= lwo_read_vx(global->stream, &poly);
313 tag = g3d_stream_read_int16_be(global->stream);
314 local->nb -= 2;
315
316 face = (G3DFace *)g_slist_nth_data(object->faces, fmax - poly);
317 g_return_val_if_fail(face != NULL, FALSE);
318
319 if(tag > obj->ntags)
320 {
321 g_warning("[LWO] tag %d not listed (%d tags)", tag, obj->ntags);
322 continue;
323 }
324
325 material = NULL;
326 mlist = global->model->materials;
327 while(mlist != NULL)
328 {
329 tmat = (G3DMaterial*)mlist->data;
330 if(strcmp(obj->tags[tag], tmat->name) == 0)
331 {
332 material = tmat;
333 break;
334 }
335 mlist = mlist->next;
336 }
337
338 if(material)
339 face->material = material;
340 else
341 g_warning("[LWO] unknown material tag %s", obj->tags[tag]);
342 }
343
344 return TRUE;
345}
346
347/* specularity */
348gboolean lwo_cb_SPEC(G3DIffGlobal *global, G3DIffLocal *local)
349{
350 G3DMaterial *material;
351 GLfloat tmpf;
352
353 material = (G3DMaterial *)local->object;
354 g_return_val_if_fail(material != NULL, FALSE);
355
356 if(global->flags & LWO_FLAG_LWO2)
357 {
358 tmpf = 1.0 - g3d_stream_read_float_be(global->stream);
359 local->nb -= 4;
360 }
361 else
362 {
363 tmpf = 1.0 - (GLfloat)g3d_stream_read_int16_be(global->stream) / 256.0;
364 local->nb -= 2;
365 }
366
367 material->specular[0] = material->r * tmpf;
368 material->specular[1] = material->g * tmpf;
369 material->specular[2] = material->b * tmpf;
370
371 return TRUE;
372}
373
374/* surfaces */
375gboolean lwo_cb_SRFS(G3DIffGlobal *global, G3DIffLocal *local)
376{
377 LwoObject *obj;
378 G3DMaterial *material;
379 gchar buffer[512];
380
381 obj = (LwoObject *)global->user_data;
382 g_return_val_if_fail(obj != NULL, FALSE);
383
384 while(local->nb > 0)
385 {
386 material = g3d_material_new();
387 local->nb -= lwo_read_string(global->stream, buffer);
388 material->name = g_strdup(buffer);
389 global->model->materials = g_slist_append(global->model->materials,
390 material);
391
392 }
393
394 return TRUE;
395}
396
397/* still image */
398gboolean lwo_cb_STIL(G3DIffGlobal *global, G3DIffLocal *local)
399{
400 LwoObject *obj;
401
402 gchar buffer[512];
403
404 obj = (LwoObject *)global->user_data;
405 g_return_val_if_fail(obj != NULL, FALSE);
406
407 local->nb -= lwo_read_string(global->stream, buffer);
408
409 g_free(obj->clipfiles[obj->nclips - 1]);
410 obj->clipfiles[obj->nclips - 1] = g_strdup(buffer);
411 obj->clipfiles[obj->nclips] = NULL;
412
413 return TRUE;
414}
415
416/* surface */
417gboolean lwo_cb_SURF(G3DIffGlobal *global, G3DIffLocal *local)
418{
419 LwoObject *obj;
420 G3DObject *object;
421 G3DMaterial *material = NULL, *tmat;
422 GSList *mlist;
423 gchar name[512];
424
425 obj = (LwoObject *)global->user_data;
426 g_return_val_if_fail(obj != NULL, FALSE);
427
428 object = (G3DObject *)obj->object;
429 g_return_val_if_fail(object != NULL, FALSE);
430
431 if(!local->finalize)
432 {
433 local->nb -= lwo_read_string(global->stream, name);
434
435 if(global->flags & LWO_FLAG_LWO2)
436 {
437 g3d_stream_read_int16_be(global->stream);
438 local->nb -= 2;
439 }
440
441 mlist = global->model->materials;
442 while(mlist != NULL)
443 {
444 tmat = (G3DMaterial*)mlist->data;
445 if(strcmp(name, tmat->name) == 0)
446 {
447 material = tmat;
448 break;
449 }
450 mlist = mlist->next;
451 }
452
453 if(material == NULL)
454 {
455 material = g3d_material_new();
456 material->name = g_strdup(name);
457 global->model->materials = g_slist_append(global->model->materials,
458 material);
459 }
460
461 local->object = material;
462 }
463
464 return TRUE;
465}
466
467/* tags */
468gboolean lwo_cb_TAGS(G3DIffGlobal *global, G3DIffLocal *local)
469{
470 LwoObject *obj;
471 G3DMaterial *material;
472 gchar buffer[512];
473
474 obj = (LwoObject *)global->user_data;
475 g_return_val_if_fail(obj != NULL, FALSE);
476
477 if(obj->ntags)
478 {
479 g_strfreev(obj->tags);
480 obj->ntags = 0;
481 }
482
483 /* read tags */
484 while(local->nb > 0)
485 {
486 local->nb -= lwo_read_string(global->stream, buffer);
487 obj->ntags ++;
488 obj->tags = g_realloc(obj->tags, (1 + obj->ntags) * sizeof(gchar *));
489 obj->tags[obj->ntags - 1] = g_strdup(buffer);
490 obj->tags[obj->ntags] = NULL;
491
492 material = g3d_material_new();
493 material->name = g_strdup(buffer);
494 global->model->materials = g_slist_append(global->model->materials,
495 material);
496 }
497
498 return TRUE;
499}
500
501/* transparency */
502gboolean lwo_cb_TRAN(G3DIffGlobal *global, G3DIffLocal *local)
503{
504 G3DMaterial *material;
505
506 material = (G3DMaterial *)local->object;
507 g_return_val_if_fail(material != NULL, FALSE);
508
509 if(global->flags & LWO_FLAG_LWO2) {
510 material->a = 1.0 - g3d_stream_read_float_be(global->stream);
511 local->nb -= 4;
512 } else {
513 material->a = 1.0 -
514 (G3DFloat)g3d_stream_read_int16_be(global->stream) / 256.0;
515 local->nb -= 2;
516 }
517 if(material->a < 0.1)
518 material->a = 0.1;
519
520 return TRUE;
521}
522
523/* vertex mapping */
524gboolean lwo_cb_VMAP(G3DIffGlobal *global, G3DIffLocal *local)
525{
526 LwoObject *obj;
527 guint32 index, type, dim;
528 gchar buffer[512], *tmp;
529
530 obj = (LwoObject *)global->user_data;
531 g_return_val_if_fail(obj != NULL, FALSE);
532
533 tmp = g3d_iff_id_to_text(local->parent_id);
534 g_debug("[LWO][VMAP] parent is %s", tmp);
535 g_free(tmp);
536
537 if(local->parent_id == G3D_IFF_MKID('L','W','O','2'))
538 {
539 type = g3d_stream_read_int32_be(global->stream);
540 local->nb -= 4;
541
542 dim = g3d_stream_read_int16_be(global->stream);
543 local->nb -= 2;
544
545 local->nb -= lwo_read_string(global->stream, buffer);
546
547 if(type == G3D_IFF_MKID('T','X','U','V'))
548 {
549 g_debug("[LWO][VMAP] **TXUV**");
550
551 g_return_val_if_fail(obj->tex_vertices == NULL, FALSE);
552
553 obj->tex_vertices = g_new0(G3DFloat,
554 obj->object->vertex_count * 2);
555
556 while(local->nb > 0)
557 {
558 local->nb -= lwo_read_vx(global->stream, &index);
559 g_return_val_if_fail(index < obj->object->vertex_count, FALSE);
560
561 obj->tex_vertices[index * 2 + 0] =
562 g3d_stream_read_float_be(global->stream);
563 obj->tex_vertices[index * 2 + 1] = 1.0 -
564 g3d_stream_read_float_be(global->stream);
565#if DEBUG > 0
566 if((obj->tex_vertices[index * 2 + 0] > 1.0) ||
567 (obj->tex_vertices[index * 2 + 1] > 1.0))
568 g_debug("LWO: TXUV: %.2f, %.2f",
569 obj->tex_vertices[index * 2 + 0],
570 obj->tex_vertices[index * 2 + 1]);
571#endif
572 local->nb -= 8;
573 }
574 }
575 else
576 {
577 tmp = g3d_iff_id_to_text(type);
578 g_warning("[LWO][VMAP] unhandled vertex mapping %s", tmp);
579 g_free(tmp);
580 }
581 }
582
583 return TRUE;
584}