aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c
new file mode 100644
index 0000000..7893c1e
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_blend/imp_blend.c
@@ -0,0 +1,201 @@
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#include <stdlib.h>
25
26#include <g3d/types.h>
27#include <g3d/stream.h>
28
29#include "imp_blend_def.h"
30#include "imp_blend_types.h"
31#include "imp_blend_sdna.h"
32#include "imp_blend_read.h"
33#include "imp_blend_chunks.h"
34
35static gboolean blend_read_file(BlendGlobal *global);
36
37EAPI
38gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
39 G3DModel *model, gpointer user_data)
40{
41 gchar buf[BLEND_HEADER_SIZE + 1];
42 guint32 flags = 0, version;
43 BlendGlobal *global;
44
45 if(g3d_stream_read(stream, buf, BLEND_HEADER_SIZE) != BLEND_HEADER_SIZE) {
46 g_warning("Blend: %s: failed to read header", stream->uri);
47 return FALSE;
48 }
49 buf[BLEND_HEADER_SIZE] = '\0';
50 if(strncmp(buf, "BLENDER", 7) != 0) {
51 g_warning("Blend: %s: not a blender file", stream->uri);
52 return FALSE;
53 }
54 if(buf[7] == '_')
55 flags |= FLAG_POINTERSIZE_4;
56 if(buf[8] == 'v')
57 flags |= FLAG_LITTLE_ENDIAN;
58 version = atoi(buf + 9);
59
60 g_debug("Blend: version %.2f, %s endian, pointer size is %d",
61 version / 100.0,
62 (flags & FLAG_LITTLE_ENDIAN) ? "little" : "big",
63 (flags & FLAG_POINTERSIZE_4) ? 4 : 8);
64
65 if(!(flags & FLAG_POINTERSIZE_4)) {
66 g_warning("Blend: 8-byte pointers are not implemented as I lack a "
67 "test file. Please send me one :).");
68 return FALSE;
69 }
70
71 global = g_new0(BlendGlobal, 1);
72 global->context = context;
73 global->stream = stream;
74 global->model = model;
75 global->flags = flags;
76
77 blend_read_file(global);
78
79 g_free(global);
80
81 return TRUE;
82}
83
84EAPI
85gchar *plugin_description(void)
86{
87 return g_strdup("Blender models.");
88}
89
90EAPI
91gchar **plugin_extensions(void)
92{
93 return g_strsplit("blend", ":", 0);
94}
95
96/*****************************************************************************/
97
98static inline const BlendChunkInfo *blend_get_chunk_info(guint32 code,
99 guint32 oid)
100{
101 gint32 i;
102
103 for(i = 0; blend_chunks[i].code != 0; i ++)
104 if((blend_chunks[i].code == code) && (blend_chunks[i].oid == oid))
105 return &(blend_chunks[i]);
106 if(oid != 0)
107 return blend_get_chunk_info(code, 0);
108 return NULL;
109}
110
111static gboolean blend_read_file(BlendGlobal *global)
112{
113 guint32 code, old, sdnanr, nr;
114 gsize len;
115 BlendLocal *local;
116 const BlendChunkInfo *cinfo;
117 const BlendSdnaStruct *sstruct;
118 gint i;
119 G3DObject *object = NULL;
120 G3DObject *grpobject = NULL;
121 guint32 object_id = 0;
122
123 while(TRUE) {
124 code = blend_read_uint(global->stream, global->flags);
125 len = blend_read_uint(global->stream, global->flags);
126 if(code == MKID('E','N','D','B'))
127 return TRUE;
128
129 old = blend_read_uint(global->stream, global->flags);
130 sdnanr = blend_read_uint(global->stream, global->flags);
131 nr = blend_read_uint(global->stream, global->flags);
132
133 if((global->sdna == NULL) && (code != MKID('D','N','A','1'))) {
134 g3d_stream_skip(global->stream, len);
135 continue;
136 }
137
138 cinfo = blend_get_chunk_info(code, (code == ID_DATA) ? object_id : 0);
139 if(cinfo == NULL)
140 g_warning("unknown chunk: %c%c%c%c",
141 blend_from_id(code, 0), blend_from_id(code, 1),
142 blend_from_id(code, 2), blend_from_id(code, 3));
143
144 g_debug("\\%c%c%c%c: %-20s - %8d bytes (0x%08x, %d, %d)",
145 blend_from_id(code, 0), blend_from_id(code, 1),
146 blend_from_id(code, 2), blend_from_id(code, 3),
147 cinfo ? cinfo->description : "(unknown)",
148 (int) len, old, sdnanr, nr);
149
150 if(len == 0)
151 return FALSE;
152
153 /* on non-DATA nodes a new object starts */
154 if(code != ID_DATA) {
155 object_id = code;
156 }
157
158 local = g_new0(BlendLocal, 1);
159 local->ndata = nr;
160 local->data = g_new0(BlendSdnaData *, nr);
161
162 if(global->sdna) {
163 for(i = 0; i < nr; i ++) {
164 sstruct = blend_sdna_get_struct_by_id(global->sdna, sdnanr);
165 if(sstruct) {
166#if DEBUG > BLEND_DEBUG_STRUCT
167 g_debug("|struct %s /* %d */",
168 sstruct->name, sstruct->size);
169#endif
170 local->data[i] = blend_sdna_data_read(global->sdna,
171 sstruct, global, &len, 0);
172 }
173 }
174 }
175
176 local->object = object;
177 local->grpobject = grpobject;
178 local->object_id = object_id;
179 local->len = len;
180
181 if(cinfo && cinfo->callback)
182 if(!cinfo->callback(global, local))
183 return FALSE;
184
185 len = local->len;
186 object = local->object;
187 grpobject = local->grpobject;
188
189 for(i = 0; i < local->ndata; i ++)
190 if(local->data[i])
191 blend_sdna_data_free(local->data[i]);
192 g_free(local->data);
193 g_free(local);
194
195 /* skip remaining data */
196 g3d_stream_skip(global->stream, len);
197 }
198
199 blend_sdna_cleanup(global->sdna);
200 return TRUE;
201}