diff options
Diffstat (limited to '')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_iob/imp_iob_callbacks.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_iob/imp_iob_callbacks.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_iob/imp_iob_callbacks.c new file mode 100644 index 0000000..ddbbc27 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_iob/imp_iob_callbacks.c | |||
@@ -0,0 +1,347 @@ | |||
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 | |||
26 | #include "imp_iob.h" | ||
27 | |||
28 | gboolean iob_cb_xLSx(G3DIffGlobal *global, G3DIffLocal *local) | ||
29 | { | ||
30 | G3DObject *object; | ||
31 | G3DMaterial *material; | ||
32 | G3DFace *face; | ||
33 | gint32 i, nitems; | ||
34 | |||
35 | object = (G3DObject *)local->object; | ||
36 | g_return_val_if_fail(object != NULL, FALSE); | ||
37 | |||
38 | if((local->id & 0xFF) == '2') | ||
39 | { | ||
40 | nitems = g3d_stream_read_int32_be(global->stream); | ||
41 | local->nb -= 4; | ||
42 | } | ||
43 | else | ||
44 | { | ||
45 | nitems = g3d_stream_read_int16_be(global->stream); | ||
46 | local->nb -= 2; | ||
47 | } | ||
48 | |||
49 | for(i = 0; i < nitems; i ++) | ||
50 | { | ||
51 | /* TODO: find material by parameters, don't create too much | ||
52 | * materials */ | ||
53 | |||
54 | /* default material + nth */ | ||
55 | material = g_slist_nth_data(object->materials, i + 1); | ||
56 | if(material == NULL) | ||
57 | { | ||
58 | material = g3d_material_new(); | ||
59 | material->flags |= G3D_FLAG_MAT_TWOSIDE; | ||
60 | material->name = g_strdup_printf("per face material #%d", i); | ||
61 | object->materials = g_slist_append(object->materials, material); | ||
62 | |||
63 | /* assign to face */ | ||
64 | face = g_slist_nth_data(object->faces, i); | ||
65 | if(face) | ||
66 | face->material = material; | ||
67 | } | ||
68 | |||
69 | switch(local->id) | ||
70 | { | ||
71 | case G3D_IFF_MKID('C', 'L', 'S', 'T'): | ||
72 | case G3D_IFF_MKID('C', 'L', 'S', '2'): | ||
73 | material->r = (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
74 | material->g = (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
75 | material->b = (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
76 | break; | ||
77 | |||
78 | case G3D_IFF_MKID('R', 'L', 'S', 'T'): | ||
79 | case G3D_IFF_MKID('R', 'L', 'S', '2'): | ||
80 | material->specular[0] = | ||
81 | (GLfloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
82 | material->specular[1] = | ||
83 | (GLfloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
84 | material->specular[2] = | ||
85 | (GLfloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
86 | break; | ||
87 | |||
88 | case G3D_IFF_MKID('T', 'L', 'S', 'T'): | ||
89 | case G3D_IFF_MKID('T', 'L', 'S', '2'): | ||
90 | material->a = 1.0 - ( | ||
91 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0 + | ||
92 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0 + | ||
93 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0) / 3.0; | ||
94 | break; | ||
95 | } | ||
96 | |||
97 | local->nb -= 3; | ||
98 | } | ||
99 | |||
100 | return TRUE; | ||
101 | } | ||
102 | |||
103 | gboolean iob_cb_COLR(G3DIffGlobal *global, G3DIffLocal *local) | ||
104 | { | ||
105 | G3DObject *object; | ||
106 | G3DMaterial *material; | ||
107 | |||
108 | object = (G3DObject *)local->object; | ||
109 | g_return_val_if_fail(object != NULL, FALSE); | ||
110 | |||
111 | material = g_slist_nth_data(object->materials, 0); | ||
112 | g_return_val_if_fail(material != NULL, FALSE); | ||
113 | |||
114 | g3d_stream_read_int8(global->stream); | ||
115 | material->r = (float)g3d_stream_read_int8(global->stream) / 255.0; | ||
116 | material->g = (float)g3d_stream_read_int8(global->stream) / 255.0; | ||
117 | material->b = (float)g3d_stream_read_int8(global->stream) / 255.0; | ||
118 | local->nb -= 4; | ||
119 | |||
120 | return TRUE; | ||
121 | } | ||
122 | |||
123 | gboolean iob_cb_DESC(G3DIffGlobal *global, G3DIffLocal *local) | ||
124 | { | ||
125 | G3DObject *object; | ||
126 | G3DMaterial *material; | ||
127 | |||
128 | if(local->finalize) return TRUE; | ||
129 | |||
130 | object = g_new0(G3DObject, 1); | ||
131 | global->model->objects = g_slist_append(global->model->objects, object); | ||
132 | |||
133 | material = g3d_material_new(); | ||
134 | material->flags |= G3D_FLAG_MAT_TWOSIDE; | ||
135 | material->name = g_strdup("(default material)"); | ||
136 | |||
137 | object->materials = g_slist_append(object->materials, material); | ||
138 | |||
139 | local->object = object; | ||
140 | |||
141 | return TRUE; | ||
142 | } | ||
143 | |||
144 | gboolean iob_cb_EDGx(G3DIffGlobal *global, G3DIffLocal *local) | ||
145 | { | ||
146 | G3DObject *object; | ||
147 | gint32 i, nedges; | ||
148 | gint32 *edges; | ||
149 | |||
150 | object = (G3DObject *)local->object; | ||
151 | g_return_val_if_fail(object != NULL, FALSE); | ||
152 | |||
153 | if(local->id == G3D_IFF_MKID('E','D','G','E')) | ||
154 | { | ||
155 | nedges = g3d_stream_read_int16_be(global->stream); | ||
156 | local->nb -= 2; | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | nedges = g3d_stream_read_int32_be(global->stream); | ||
161 | local->nb -= 4; | ||
162 | } | ||
163 | |||
164 | edges = g_malloc(nedges * 2 * sizeof(gint32)); | ||
165 | for(i = 0; i < nedges; i ++) | ||
166 | { | ||
167 | if(local->id == G3D_IFF_MKID('E','D','G','E')) | ||
168 | { | ||
169 | edges[i * 2 + 0] = g3d_stream_read_int16_be(global->stream); | ||
170 | edges[i * 2 + 1] = g3d_stream_read_int16_be(global->stream); | ||
171 | local->nb -= 4; | ||
172 | } | ||
173 | else | ||
174 | { | ||
175 | edges[i * 2 + 0] = g3d_stream_read_int32_be(global->stream); | ||
176 | edges[i * 2 + 1] = g3d_stream_read_int32_be(global->stream); | ||
177 | local->nb -= 8; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | local->level_object = edges; | ||
182 | |||
183 | return TRUE; | ||
184 | } | ||
185 | |||
186 | gboolean iob_cb_FACx(G3DIffGlobal *global, G3DIffLocal *local) | ||
187 | { | ||
188 | G3DObject *object; | ||
189 | gint32 *edges, e[3], v1, v2, v3; | ||
190 | gint32 i, nfaces; | ||
191 | |||
192 | object = (G3DObject *)local->object; | ||
193 | g_return_val_if_fail(object != NULL, FALSE); | ||
194 | |||
195 | /* edges are read in EDGE/EDG2 chunk */ | ||
196 | edges = (gint32 *)local->level_object; | ||
197 | g_return_val_if_fail(edges != NULL, FALSE); | ||
198 | |||
199 | if(local->id == G3D_IFF_MKID('F','A','C','E')) | ||
200 | { | ||
201 | nfaces = g3d_stream_read_int16_be(global->stream); | ||
202 | local->nb -= 2; | ||
203 | } | ||
204 | else | ||
205 | { | ||
206 | nfaces = g3d_stream_read_int32_be(global->stream); | ||
207 | local->nb -= 4; | ||
208 | } | ||
209 | |||
210 | for(i = 0; i < nfaces; i ++) | ||
211 | { | ||
212 | G3DFace *face = g_new0(G3DFace, 1); | ||
213 | face->vertex_count = 3; | ||
214 | face->vertex_indices = g_new0(guint32, 3); | ||
215 | |||
216 | if(local->id == G3D_IFF_MKID('F','A','C','E')) | ||
217 | { | ||
218 | e[0] = g3d_stream_read_int16_be(global->stream); | ||
219 | e[1] = g3d_stream_read_int16_be(global->stream); | ||
220 | e[2] = g3d_stream_read_int16_be(global->stream); | ||
221 | local->nb -= 6; | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | e[0] = g3d_stream_read_int32_be(global->stream); | ||
226 | e[1] = g3d_stream_read_int32_be(global->stream); | ||
227 | e[2] = g3d_stream_read_int32_be(global->stream); | ||
228 | local->nb -= 12; | ||
229 | } | ||
230 | |||
231 | face->vertex_indices[0] = v1 = edges[e[0] * 2 + 0]; | ||
232 | face->vertex_indices[1] = v2 = edges[e[0] * 2 + 1]; | ||
233 | if((v1 != edges[e[1] * 2 + 0]) && (v2 != edges[e[1] * 2 + 0])) | ||
234 | v3 = edges[e[1] * 2 + 0]; | ||
235 | else if((v1 != edges[e[1] * 2 + 1]) && (v2 != edges[e[1] * 2 + 1])) | ||
236 | v3 = edges[e[1] * 2 + 1]; | ||
237 | else if((v1 != edges[e[2] * 2 + 0]) && (v2 != edges[e[2] * 2 + 0])) | ||
238 | v3 = edges[e[2] * 2 + 0]; | ||
239 | else | ||
240 | v3 = edges[e[2] * 2 + 1]; | ||
241 | |||
242 | face->vertex_indices[2] = v3; | ||
243 | |||
244 | face->material = g_slist_nth_data(object->materials, 0); | ||
245 | object->faces = g_slist_append(object->faces, face); | ||
246 | } | ||
247 | |||
248 | /* free edges now */ | ||
249 | g_free(edges); | ||
250 | local->level_object = NULL; | ||
251 | |||
252 | return TRUE; | ||
253 | } | ||
254 | |||
255 | gboolean iob_cb_NAME(G3DIffGlobal *global, G3DIffLocal *local) | ||
256 | { | ||
257 | G3DObject *object; | ||
258 | gchar buffer[512]; | ||
259 | |||
260 | object = (G3DObject *)local->object; | ||
261 | g_return_val_if_fail(object != NULL, FALSE); | ||
262 | |||
263 | g3d_stream_read(global->stream, buffer, local->nb); | ||
264 | |||
265 | object->name = g_convert(buffer, local->nb, | ||
266 | "UTF-8", "ISO-8859-1", | ||
267 | NULL, NULL, NULL); | ||
268 | |||
269 | local->nb = 0; | ||
270 | |||
271 | return TRUE; | ||
272 | } | ||
273 | |||
274 | gboolean iob_cb_PNTx(G3DIffGlobal *global, G3DIffLocal *local) | ||
275 | { | ||
276 | G3DObject *object; | ||
277 | gint32 i; | ||
278 | |||
279 | object = (G3DObject *)local->object; | ||
280 | g_return_val_if_fail(object != NULL, FALSE); | ||
281 | |||
282 | if(local->id == G3D_IFF_MKID('P','N','T','S')) | ||
283 | { | ||
284 | object->vertex_count = g3d_stream_read_int16_be(global->stream); | ||
285 | local->nb -= 2; | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | object->vertex_count = g3d_stream_read_int32_be(global->stream); | ||
290 | local->nb -= 4; | ||
291 | } | ||
292 | |||
293 | object->vertex_data = g_new0(G3DFloat, object->vertex_count * 3); | ||
294 | |||
295 | for(i = 0; i < object->vertex_count; i ++) | ||
296 | { | ||
297 | object->vertex_data[i * 3 + 0] = iob_read_fract(global->stream); | ||
298 | object->vertex_data[i * 3 + 1] = iob_read_fract(global->stream); | ||
299 | object->vertex_data[i * 3 + 2] = iob_read_fract(global->stream); | ||
300 | local->nb -= 12; | ||
301 | } | ||
302 | |||
303 | return TRUE; | ||
304 | } | ||
305 | |||
306 | gboolean iob_cb_REFL(G3DIffGlobal *global, G3DIffLocal *local) | ||
307 | { | ||
308 | G3DObject *object; | ||
309 | G3DMaterial *material; | ||
310 | gint32 i; | ||
311 | |||
312 | object = (G3DObject *)local->object; | ||
313 | g_return_val_if_fail(object != NULL, FALSE); | ||
314 | |||
315 | material = g_slist_nth_data(object->materials, 0); | ||
316 | g_return_val_if_fail(material != NULL, FALSE); | ||
317 | |||
318 | g3d_stream_read_int8(global->stream); | ||
319 | for(i = 0; i < 3; i ++) | ||
320 | material->specular[i] = | ||
321 | (GLfloat)g3d_stream_read_int8(global->stream) / 255.0; | ||
322 | local->nb -= 4; | ||
323 | |||
324 | return TRUE; | ||
325 | } | ||
326 | |||
327 | gboolean iob_cb_TRAN(G3DIffGlobal *global, G3DIffLocal *local) | ||
328 | { | ||
329 | G3DObject *object; | ||
330 | G3DMaterial *material; | ||
331 | |||
332 | object = (G3DObject *)local->object; | ||
333 | g_return_val_if_fail(object != NULL, FALSE); | ||
334 | |||
335 | material = g_slist_nth_data(object->materials, 0); | ||
336 | g_return_val_if_fail(material != NULL, FALSE); | ||
337 | |||
338 | g3d_stream_read_int8(global->stream); | ||
339 | material->a = 1.0 - ( | ||
340 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0 + | ||
341 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0 + | ||
342 | (G3DFloat)g3d_stream_read_int8(global->stream) / 255.0) / 3.0; | ||
343 | local->nb -= 4; | ||
344 | |||
345 | return TRUE; | ||
346 | } | ||
347 | |||