aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c496
1 files changed, 496 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c
new file mode 100644
index 0000000..590c342
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad.c
@@ -0,0 +1,496 @@
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 <stdlib.h>
24#include <string.h>
25#include <locale.h>
26
27#include <math.h>
28
29#include <g3d/types.h>
30#include <g3d/context.h>
31#include <g3d/model.h>
32#include <g3d/read.h>
33#include <g3d/vector.h>
34#include <g3d/matrix.h>
35
36#include "imp_leocad_library.h"
37
38static int leocad_load_lcd(G3DStream *stream, G3DModel *model,
39 LeoCadLibrary *library, G3DContext *context);
40
41EAPI
42gpointer plugin_init(G3DContext *context)
43{
44 LeoCadLibrary *library;
45 const gchar *libdir;
46
47 libdir = g_getenv("LEOCAD_LIB");
48 if(libdir == NULL)
49 libdir = "/usr/local/share/leocad";
50
51 library = leocad_library_load(libdir);
52
53 if(library == NULL)
54 {
55#if DEBUG > 1
56 g_warning("LeoCAD: failed to load library");
57#endif
58 return NULL;
59 }
60
61 return library;
62}
63
64EAPI
65void plugin_cleanup(gpointer user_data)
66{
67 LeoCadLibrary *library;
68
69#if DEBUG > 1
70 g_debug("LeoCAD: cleaning up library\n");
71#endif
72
73 library = (LeoCadLibrary *)user_data;
74
75 if(library)
76 leocad_library_free(library);
77}
78
79EAPI
80gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
81 G3DModel *model, gpointer user_data)
82{
83 LeoCadLibrary *library;
84
85 library = (LeoCadLibrary *)user_data;
86
87 if(library == NULL)
88 {
89 g_warning("LeoCAD: library not loaded");
90 return FALSE;
91 }
92
93 setlocale(LC_NUMERIC, "C");
94
95 return leocad_load_lcd(stream, model, library, context);
96}
97
98EAPI
99gchar *plugin_description(G3DContext *context)
100{
101 return g_strdup("LeoCAD models.");
102}
103
104EAPI
105gchar **plugin_extensions(G3DContext *context)
106{
107 return g_strsplit("lcd", ":", 0);
108}
109
110/*
111 * LeoCAD specific stuff
112 */
113
114static gboolean leocad_change_key(guint16 ktime, G3DFloat *param, guint8 ktype,
115 G3DFloat *matrix, G3DFloat *mloc, gboolean *valid_matrix)
116{
117 /* get first frame */
118 if(ktime == 1)
119 {
120 switch(ktype)
121 {
122 case 0x00: /* translation */
123 g3d_matrix_identity(mloc);
124 g3d_matrix_translate(param[0], param[1], param[2], mloc);
125 g3d_matrix_multiply(matrix, mloc, matrix);
126 *valid_matrix = TRUE;
127 break;
128
129 case 0x01: /* rotation */
130 g3d_matrix_rotate((G3DFloat)param[3] * G_PI / 180.0,
131 param[0], param[1], param[2], matrix);
132 g3d_matrix_multiply(mloc, matrix, matrix);
133 *valid_matrix = TRUE;
134 break;
135
136 default:
137 break;
138 }
139 }
140#if DEBUG > 0
141 g_debug("LeoCAD: key 0x%02x (%d): %+2.2f %+2.2f %+2.2f %+2.2f",
142 ktype, ktime, param[0], param[1], param[2], param[3]);
143#endif
144 return TRUE;
145}
146
147static gboolean leocad_load_lcd_piece(G3DStream *stream, G3DModel *model,
148 LeoCadLibrary *library, G3DFloat lcdversion)
149{
150 guint32 i, j, k, nkeys, nobjs;
151 guint16 ktime;
152 guint8 pver, over, ktype, color = 0, len8;
153 gchar name[9];
154 G3DFloat param[4], matrix[16], mloc[16];
155 G3DFloat offx = 0.0, offy = 0.0, offz = 0.0;
156 G3DFloat rotx = 0.0, roty = 0.0, rotz = 0.0;
157 G3DObject *object;
158 G3DMaterial *mat_change;
159 G3DFace *face;
160 GSList *fitem;
161 gboolean valid_matrix = FALSE;
162
163 g3d_matrix_identity(mloc);
164 g3d_matrix_identity(matrix);
165
166 mat_change = leocad_library_get_nth_material(library, 0x10);
167
168 if(lcdversion > 0.4)
169 {
170 pver = g3d_stream_read_int8(stream);
171
172 if(pver >= 9)
173 {
174 /* object stuff */
175 over = g3d_stream_read_int8(stream);
176 nobjs = g3d_stream_read_int32_le(stream);
177 for(i = 0; i < nobjs; i ++)
178 {
179 /* time */
180 ktime = g3d_stream_read_int16_le(stream);
181 /* param */
182 param[0] = g3d_stream_read_float_le(stream);
183 param[1] = g3d_stream_read_float_le(stream);
184 param[2] = g3d_stream_read_float_le(stream);
185 param[3] = g3d_stream_read_float_le(stream);
186 /* type */
187 ktype = g3d_stream_read_int8(stream);
188
189 leocad_change_key(ktime, param, ktype, matrix, mloc,
190 &valid_matrix);
191 }
192
193 if(over == 1)
194 {
195 nobjs = g3d_stream_read_int32_le(stream);
196 for(i = 0; i < nobjs; i ++)
197 {
198 ktime = g3d_stream_read_int16_le(stream);
199 param[0] = g3d_stream_read_float_le(stream);
200 param[1] = g3d_stream_read_float_le(stream);
201 param[2] = g3d_stream_read_float_le(stream);
202 param[3] = g3d_stream_read_float_le(stream);
203 ktype = g3d_stream_read_int8(stream);
204 }
205 }
206 }
207 else /* pver < 9 */
208 {
209 if(pver > 5)
210 {
211 nkeys = g3d_stream_read_int32_le(stream);
212 for(i = 0; i < nkeys; i ++)
213 {
214 /* param */
215 param[0] = g3d_stream_read_float_le(stream);
216 param[1] = g3d_stream_read_float_le(stream);
217 param[2] = g3d_stream_read_float_le(stream);
218 param[3] = g3d_stream_read_float_le(stream);
219
220 /* time */
221 ktime = g3d_stream_read_int16_le(stream);
222
223 /* type */
224 ktype = g3d_stream_read_int8(stream);
225
226 leocad_change_key(ktime, param, ktype, matrix, mloc,
227 &valid_matrix);
228
229 } /* keys */
230
231 nkeys = g3d_stream_read_int32_le(stream);
232 for(i = 0; i < nkeys; i ++)
233 {
234 /* param */
235 param[0] = g3d_stream_read_float_le(stream);
236 param[1] = g3d_stream_read_float_le(stream);
237 param[2] = g3d_stream_read_float_le(stream);
238 param[3] = g3d_stream_read_float_le(stream);
239
240 /* time */
241 ktime = g3d_stream_read_int16_le(stream);
242
243 /* type */
244 ktype = g3d_stream_read_int8(stream);
245 }
246 } /* pver > 5 */
247 else /* pver <= 5 */
248 {
249 if(pver > 2)
250 {
251 nkeys = g3d_stream_read_int8(stream);
252 for(i = 0; i < nkeys; i ++)
253 {
254 if(pver > 3)
255 {
256#if DEBUG > 2
257 g_debug("LeoCAD: matrix\n");
258#endif
259 /* matrix */
260 for(j = 0; j < 4; j ++)
261 for(k = 0; k < 4; k ++)
262 matrix[j * 4 + k] =
263 g3d_stream_read_float_le(stream);
264
265 valid_matrix = TRUE;
266 }
267 else
268 {
269 /* move: 3 x float */
270 offx = g3d_stream_read_float_le(stream);
271 offy = g3d_stream_read_float_le(stream);
272 offz = g3d_stream_read_float_le(stream);
273
274 /* rotate: 3 x float */
275 rotx = g3d_stream_read_float_le(stream);
276 roty = g3d_stream_read_float_le(stream);
277 rotz = g3d_stream_read_float_le(stream);
278 }
279
280 /* time */
281 ktime = g3d_stream_read_int8(stream);
282
283 /* bl? */
284 g3d_stream_read_int32_le(stream);
285 } /* .. nkeys */
286 } /* pver > 2 */
287 else /* pver <= 2 */
288 {
289 /* move: 3 x float */
290 offx = g3d_stream_read_float_le(stream);
291 offy = g3d_stream_read_float_le(stream);
292 offz = g3d_stream_read_float_le(stream);
293
294 /* rotate: 3 x float */
295 rotx = g3d_stream_read_float_le(stream);
296 roty = g3d_stream_read_float_le(stream);
297 rotz = g3d_stream_read_float_le(stream);
298 }
299 } /* pver <= 5 */
300 } /* pver < 9 */
301
302 /* common stuff */
303
304 /* name of piece */
305 g3d_stream_read(stream, name, 9);
306
307 /* color */
308 color = g3d_stream_read_int8(stream);
309
310 if(pver < 5)
311 color = leocad_library_convert_color(color);
312
313#if DEBUG > 0
314 g_debug("LeoCAD: [%d]: '%-8s', color 0x%02x", pver, name, color);
315#endif
316
317 /* step show */
318 g3d_stream_read_int8(stream);
319
320 /* step hide */
321 if(pver > 1)
322 g3d_stream_read_int8(stream);
323
324 if(pver > 5)
325 {
326 /* frame show */
327 g3d_stream_read_int16_le(stream);
328 /* frame hide */
329 g3d_stream_read_int16_le(stream);
330
331 if(pver > 7) {
332 /* state */
333 g3d_stream_read_int8(stream);
334
335 len8 = g3d_stream_read_int8(stream);
336 g3d_stream_skip(stream, len8);
337 } else { /* pver <= 7 */
338 /* hide */
339 g3d_stream_read_int32_le(stream);
340 g3d_stream_skip(stream, 81);
341 } /* pver <= 7 */
342
343 if(pver > 6) {
344 /* group pointer ?! */
345 g3d_stream_read_int32_le(stream);
346 }
347 } /* pver > 5 */
348 else /* pver <= 5 */
349 {
350 /* group pointer ?! */
351 g3d_stream_read_int8(stream);
352
353 /* hide */
354 g3d_stream_read_int8(stream);
355 }
356
357 } /* lcdversion > 0.4 */
358
359 object = leocad_library_get_piece(library, name);
360 if(object == NULL)
361 {
362 g_warning("LeoCAD: failed to load piece '%s'", name);
363 return FALSE;
364 }
365
366 /* matrix */
367 if(!valid_matrix)
368 {
369 /* translation */
370 g3d_matrix_identity(mloc);
371 g3d_matrix_translate(offx, offy, offz, mloc);
372 /* rotation */
373 rotx = (G3DFloat)(rotx * G_PI) / 180.0;
374 roty = (G3DFloat)(roty * G_PI) / 180.0;
375 rotz = (G3DFloat)(rotz * G_PI) / 180.0;
376 g3d_matrix_identity(matrix);
377 g3d_matrix_rotate_xyz(rotx, roty, rotz, matrix);
378
379 /* combine */
380 g3d_matrix_multiply(mloc, matrix, matrix);
381 }
382
383 /*g3d_matrix_dump(matrix);*/
384
385 /* transform vertices */
386 for(i = 0; i < object->vertex_count; i ++)
387 g3d_vector_transform(
388 &(object->vertex_data[i * 3 + 0]),
389 &(object->vertex_data[i * 3 + 1]),
390 &(object->vertex_data[i * 3 + 2]),
391 matrix);
392
393 /* change color */
394 fitem = object->faces;
395 while(fitem)
396 {
397 face = (G3DFace *)fitem->data;
398 if(face->material == mat_change)
399 {
400 face->material = leocad_library_get_nth_material(library, color);
401 }
402
403 if(face->material == NULL)
404 {
405 face->material = leocad_library_get_nth_material(library, 0);
406 }
407
408 fitem = fitem->next;
409 }
410
411 /* add to model object list */
412 model->objects = g_slist_append(model->objects, object);
413
414 return TRUE;
415}
416
417static gboolean leocad_load_lcd(G3DStream *stream, G3DModel *model,
418 LeoCadLibrary *library, G3DContext *context)
419{
420 gchar magic[32];
421 float version;
422 guint32 i, count;
423 G3DFloat r, g, b;
424 G3DMatrix rmatrix[16];
425
426 g3d_stream_read(stream, magic, 32);
427 if(strncmp(magic, "LeoCAD", 6) != 0) {
428 g_warning("LeoCAD: '%s' is not a valid LeoCAD project file",
429 stream->uri);
430 return FALSE;
431 }
432
433 sscanf(&magic[7], "%f", &version);
434
435 if(version > 0.4) {
436#if DEBUG > 0
437 g_debug("LeoCAD: file version %.1f, getting next float", version);
438#endif
439 version = g3d_stream_read_float_le(stream);
440 }
441
442#if DEBUG > 0
443 g_debug("LeoCAD: file version %.1f", version);
444#endif
445
446 r = g3d_stream_read_int8(stream) / 255.0;
447 g = g3d_stream_read_int8(stream) / 255.0;
448 b = g3d_stream_read_int8(stream) / 255.0;
449 /* background color */
450 g3d_context_set_bgcolor(context, r, g, b, 1.0);
451 g3d_stream_read_int8(stream);
452
453 /* view */
454 if(version < 0.6) {
455 /* eye: 3 x double */
456 g3d_stream_skip(stream, 24);
457
458 /* target: 3 x double */
459 g3d_stream_skip(stream, 24);
460 }
461
462 /* angle snap */
463 g3d_stream_read_int32_le(stream);
464 /* snap */
465 g3d_stream_read_int32_le(stream);
466 /* line width */
467 g3d_stream_read_float_le(stream);
468 /* detail */
469 g3d_stream_read_int32_le(stream);
470 /* cur group */
471 g3d_stream_read_int32_le(stream);
472 /* cur color */
473 g3d_stream_read_int32_le(stream);
474 /* action */
475 g3d_stream_read_int32_le(stream);
476 /* cur step */
477 g3d_stream_read_int32_le(stream);
478
479 if(version > 0.8) {
480 /* scene */
481 g3d_stream_read_int32_le(stream);
482 }
483
484 /* piece count */
485 count = g3d_stream_read_int32_le(stream);
486 for(i = 0; i < count; i ++) {
487 /* load piece */
488 leocad_load_lcd_piece(stream, model, library, version);
489 }
490
491 g3d_matrix_identity(rmatrix);
492 g3d_matrix_rotate_xyz(G_PI * -90.0 / 180, 0.0, 0.0, rmatrix);
493 g3d_model_transform(model, rmatrix);
494
495 return TRUE;
496}