diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3ds/imp_3ds.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3ds/imp_3ds.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3ds/imp_3ds.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3ds/imp_3ds.c new file mode 100644 index 0000000..6125984 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3ds/imp_3ds.c | |||
@@ -0,0 +1,206 @@ | |||
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 <stdio.h> | ||
24 | #include <string.h> | ||
25 | #include <stdarg.h> | ||
26 | |||
27 | #include <g3d/types.h> | ||
28 | #include <g3d/stream.h> | ||
29 | #include <g3d/material.h> | ||
30 | #include <g3d/texture.h> | ||
31 | #include <g3d/matrix.h> | ||
32 | |||
33 | #include "imp_3ds.h" | ||
34 | #include "imp_3ds_chunks.h" | ||
35 | |||
36 | /*****************************************************************************/ | ||
37 | /* plugin interface */ | ||
38 | /*****************************************************************************/ | ||
39 | |||
40 | EAPI | ||
41 | gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream, | ||
42 | G3DModel *model, gpointer plugin_data) | ||
43 | { | ||
44 | G3DMatrix rmatrix[16]; | ||
45 | gint32 nbytes, magic; | ||
46 | gboolean retval; | ||
47 | x3ds_global_data global; | ||
48 | x3ds_parent_data *parent; | ||
49 | |||
50 | magic = g3d_stream_read_int16_le(stream); | ||
51 | if((magic != 0x4D4D) && (magic != 0xC23D)) | ||
52 | { | ||
53 | g_warning("file %s is not a 3ds file", stream->uri); | ||
54 | return FALSE; | ||
55 | } | ||
56 | nbytes = g3d_stream_read_int32_le(stream); | ||
57 | nbytes -= 6; | ||
58 | #if DEBUG > 0 | ||
59 | g_debug("\\[%4.4X] 3DS file: main length: %d", magic, nbytes); | ||
60 | #endif | ||
61 | |||
62 | global.context = context; | ||
63 | global.model = model; | ||
64 | global.stream = stream; | ||
65 | global.scale = 1.0; | ||
66 | global.max_tex_id = 0; | ||
67 | |||
68 | parent = g_new0(x3ds_parent_data, 1); | ||
69 | parent->id = magic; | ||
70 | parent->nb = nbytes; | ||
71 | |||
72 | retval = x3ds_read_ctnr(&global, parent); | ||
73 | |||
74 | g3d_matrix_identity(rmatrix); | ||
75 | g3d_matrix_rotate_xyz(G_PI * -90.0 / 180, 0.0, 0.0, rmatrix); | ||
76 | g3d_model_transform(model, rmatrix); | ||
77 | |||
78 | g_free(parent); | ||
79 | |||
80 | return retval; | ||
81 | } | ||
82 | |||
83 | EAPI | ||
84 | gchar *plugin_description(void) | ||
85 | { | ||
86 | return g_strdup("AutoCAD 3D Studio models."); | ||
87 | } | ||
88 | |||
89 | EAPI | ||
90 | gchar **plugin_extensions(void) | ||
91 | { | ||
92 | return g_strsplit("3ds:prj", ":", 0); | ||
93 | } | ||
94 | |||
95 | /*****************************************************************************/ | ||
96 | |||
97 | gboolean x3ds_read_ctnr(x3ds_global_data *global, x3ds_parent_data *parent) | ||
98 | { | ||
99 | gint32 chunk_id, chunk_len, i; | ||
100 | x3ds_parent_data *subparent; | ||
101 | gpointer level_object; | ||
102 | gchar *padding = " "; | ||
103 | |||
104 | level_object = NULL; | ||
105 | |||
106 | while(parent->nb > 0) { | ||
107 | chunk_id = g3d_stream_read_int16_le(global->stream); | ||
108 | chunk_len = g3d_stream_read_int32_le(global->stream); | ||
109 | parent->nb -= 6; | ||
110 | chunk_len -= 6; | ||
111 | |||
112 | i = 0; | ||
113 | while((x3ds_chunks[i].id != 0) && (x3ds_chunks[i].id != chunk_id)) | ||
114 | i ++; | ||
115 | |||
116 | if(x3ds_chunks[i].id == chunk_id) { | ||
117 | g_debug("\\%s(%d)[0x%04X][%c%c] %s (%d bytes)", | ||
118 | padding + (strlen(padding) - parent->level), parent->level, | ||
119 | chunk_id, | ||
120 | x3ds_chunks[i].container ? 'c' : ' ', | ||
121 | x3ds_chunks[i].callback ? 'f' : ' ', | ||
122 | x3ds_chunks[i].desc, chunk_len); | ||
123 | if (chunk_id==0) { | ||
124 | g_warning("error: bad chunk id"); | ||
125 | return FALSE; | ||
126 | } | ||
127 | |||
128 | subparent = g_new0(x3ds_parent_data, 1); | ||
129 | subparent->id = parent->id; | ||
130 | subparent->object = parent->object; | ||
131 | subparent->level = parent->level + 1; | ||
132 | subparent->level_object = level_object; | ||
133 | subparent->nb = chunk_len; | ||
134 | |||
135 | if(x3ds_chunks[i].callback) { | ||
136 | /* callback may change "nb" and "object" of | ||
137 | * "subparent" structure for following container run */ | ||
138 | |||
139 | x3ds_chunks[i].callback(global, subparent); | ||
140 | } | ||
141 | |||
142 | subparent->id = chunk_id; | ||
143 | |||
144 | if(x3ds_chunks[i].container) { | ||
145 | if(x3ds_read_ctnr(global, subparent) == FALSE) { | ||
146 | /* abort on error */ | ||
147 | return FALSE; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if(subparent->nb) | ||
152 | g3d_stream_skip(global->stream, subparent->nb); | ||
153 | |||
154 | level_object = subparent->level_object; | ||
155 | |||
156 | g_free(subparent); | ||
157 | } else { | ||
158 | g_warning("[3DS] unknown chunk type 0x%04X", chunk_id); | ||
159 | g3d_stream_skip(global->stream, chunk_len); | ||
160 | } | ||
161 | parent->nb -= chunk_len; | ||
162 | |||
163 | /* update progress bar */ | ||
164 | x3ds_update_progress(global, parent->level); | ||
165 | } | ||
166 | |||
167 | return TRUE; | ||
168 | } | ||
169 | |||
170 | void x3ds_update_progress(x3ds_global_data *global, guint32 level) | ||
171 | { | ||
172 | goffset fpos; | ||
173 | |||
174 | /* update progress bar */ | ||
175 | if(level < 4) { | ||
176 | fpos = g3d_stream_tell(global->stream); | ||
177 | g3d_context_update_progress_bar(global->context, | ||
178 | ((G3DFloat)fpos / (G3DFloat)g3d_stream_size(global->stream)), TRUE); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | gint32 x3ds_read_cstr(G3DStream *stream, gchar *string) | ||
183 | { | ||
184 | gint32 n = 0; | ||
185 | char c; | ||
186 | do { | ||
187 | c = g3d_stream_read_int8(stream); | ||
188 | string[n] = c; | ||
189 | n++; | ||
190 | } while(c != 0); | ||
191 | return n; | ||
192 | } | ||
193 | |||
194 | G3DObject *x3ds_newobject(G3DModel *model, const gchar *name) | ||
195 | { | ||
196 | G3DObject *object = g_malloc0(sizeof(G3DObject)); | ||
197 | G3DMaterial *material = g3d_material_new(); | ||
198 | |||
199 | object->name = g_strdup(name); | ||
200 | object->faces = NULL; | ||
201 | model->objects = g_slist_append(model->objects, object); | ||
202 | object->materials = g_slist_append(object->materials, material); | ||
203 | |||
204 | return object; | ||
205 | } | ||
206 | |||