diff options
author | David Walter Seikel | 2016-03-29 02:16:55 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-03-29 02:16:55 +1000 |
commit | cb3716ffb584fe0f593b6f1669a8efdba1305104 (patch) | |
tree | 5d1ebc4b6fc17b30f4b34e7e64a2d9514893459b /src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c | |
parent | Add Prosody build script. (diff) | |
download | SledjHamr-cb3716ffb584fe0f593b6f1669a8efdba1305104.zip SledjHamr-cb3716ffb584fe0f593b6f1669a8efdba1305104.tar.gz SledjHamr-cb3716ffb584fe0f593b6f1669a8efdba1305104.tar.bz2 SledjHamr-cb3716ffb584fe0f593b6f1669a8efdba1305104.tar.xz |
Added my version of libg3d and friends.
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c new file mode 100644 index 0000000..4c9d4c6 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_md2/imp_md2.c | |||
@@ -0,0 +1,292 @@ | |||
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 | |||
26 | #include <g3d/types.h> | ||
27 | #include <g3d/material.h> | ||
28 | #include <g3d/texture.h> | ||
29 | #include <g3d/stream.h> | ||
30 | #include <g3d/iff.h> | ||
31 | |||
32 | #include "imp_md2_normals.h" | ||
33 | |||
34 | #define MD2_SKINNAMELEN 64 | ||
35 | |||
36 | static const char *textureExtensions[] = { | ||
37 | ".pcx", ".bmp", ".jpg", ".tga", ".png", NULL }; | ||
38 | |||
39 | EAPI | ||
40 | gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream, | ||
41 | G3DModel *model, gpointer user_data) | ||
42 | { | ||
43 | guint32 idid, idver, skinwidth, skinheight, framesize; | ||
44 | guint32 numskins, numverts, numtexs, numfaces, numglcmds, numframes; | ||
45 | guint32 offskins, offtexs, offfaces, offframes, offglcmds, offend; | ||
46 | G3DFloat *texco = NULL, *normals; | ||
47 | gchar **skinnames = NULL; | ||
48 | gint i, j; | ||
49 | G3DObject *object; | ||
50 | G3DMaterial *material; | ||
51 | G3DImage *image = NULL; | ||
52 | |||
53 | idid = g3d_stream_read_int32_be(stream); | ||
54 | if(idid != G3D_IFF_MKID('I','D','P','2')) { | ||
55 | g_critical("file '%s' is not a .md2 file", stream->uri); | ||
56 | return FALSE; | ||
57 | } | ||
58 | |||
59 | idver = g3d_stream_read_int32_le(stream); | ||
60 | if(idver != 8) { | ||
61 | g_warning("file '%s' has wrong version (%d)", stream->uri, idver); | ||
62 | #define CLOSE_ON_WRONG_VERSION | ||
63 | #ifdef CLOSE_ON_WRONG_VERSION | ||
64 | return FALSE; | ||
65 | #endif | ||
66 | } | ||
67 | |||
68 | object = g_new0(G3DObject, 1); | ||
69 | object->name = g_strdup("Q2Object"); | ||
70 | material = g3d_material_new(); | ||
71 | object->materials = g_slist_append(object->materials, material); | ||
72 | model->objects = g_slist_append(model->objects, object); | ||
73 | |||
74 | skinwidth = g3d_stream_read_int32_le(stream); | ||
75 | skinheight = g3d_stream_read_int32_le(stream); | ||
76 | framesize = g3d_stream_read_int32_le(stream); | ||
77 | numskins = g3d_stream_read_int32_le(stream); | ||
78 | numverts = g3d_stream_read_int32_le(stream); | ||
79 | numtexs = g3d_stream_read_int32_le(stream); | ||
80 | numfaces = g3d_stream_read_int32_le(stream); | ||
81 | numglcmds = g3d_stream_read_int32_le(stream); | ||
82 | numframes = g3d_stream_read_int32_le(stream); | ||
83 | |||
84 | object->vertex_count = numverts; | ||
85 | object->vertex_data = g_new0(G3DFloat, numverts * 3); | ||
86 | normals = g_new0(G3DFloat, numverts * 3); | ||
87 | |||
88 | offskins = g3d_stream_read_int32_le(stream); | ||
89 | offtexs = g3d_stream_read_int32_le(stream); | ||
90 | offfaces = g3d_stream_read_int32_le(stream); | ||
91 | offframes = g3d_stream_read_int32_le(stream); | ||
92 | offglcmds = g3d_stream_read_int32_le(stream); | ||
93 | offend = g3d_stream_read_int32_le(stream); | ||
94 | |||
95 | if(numskins > 0) { | ||
96 | skinnames = g_new0(gchar *, numskins); | ||
97 | for(i = 0; i < numskins; i ++) { | ||
98 | skinnames[i] = g_new0(gchar, MD2_SKINNAMELEN); | ||
99 | g3d_stream_read(stream, skinnames[i], MD2_SKINNAMELEN); | ||
100 | |||
101 | /* some md2 models have a dot as first character to tell the engine | ||
102 | * load the texture from the dir where the model is located */ | ||
103 | if(skinnames[i][0] == '.') | ||
104 | memmove(skinnames[i], skinnames[i] + 1, MD2_SKINNAMELEN - 1); | ||
105 | #if DEBUG > 0 | ||
106 | g_debug("skin #%d: %s", i + 1, skinnames[i]); | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | /* not every skin has a texture assigned, the engines will search | ||
111 | * a list of supported images to get the texture */ | ||
112 | for(j = 0; j < numskins; j++) { | ||
113 | gchar skinname[MD2_SKINNAMELEN]; | ||
114 | gchar *basename; | ||
115 | |||
116 | /* real filename */ | ||
117 | if(g_file_test(skinnames[j], G_FILE_TEST_EXISTS)) | ||
118 | image = g3d_texture_load_cached(context, model, skinnames[j]); | ||
119 | if(image) | ||
120 | break; | ||
121 | basename = g_path_get_basename(skinnames[j]); | ||
122 | if(g_file_test(basename, G_FILE_TEST_EXISTS)) | ||
123 | image = g3d_texture_load_cached(context, model, skinnames[j]); | ||
124 | g_free(basename); | ||
125 | if(image) | ||
126 | break; | ||
127 | |||
128 | /* without extension */ | ||
129 | for(i = 0; textureExtensions[i] != NULL; i ++) { | ||
130 | g_snprintf(skinname, sizeof(skinname), "%s%s", skinnames[j], | ||
131 | textureExtensions[i]); | ||
132 | if(g_file_test(skinname, G_FILE_TEST_EXISTS)) | ||
133 | image = g3d_texture_load_cached(context, model, skinname); | ||
134 | if(image) | ||
135 | break; | ||
136 | basename = g_path_get_basename(skinname); | ||
137 | if(g_file_test(basename, G_FILE_TEST_EXISTS)) | ||
138 | image = g3d_texture_load_cached(context, model, skinname); | ||
139 | g_free(basename); | ||
140 | if(image) | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | /* replace extension */ | ||
145 | for(i = 0; textureExtensions[i] != NULL; i ++) { | ||
146 | g_snprintf(skinname, sizeof(skinname), "%.*s%s", | ||
147 | ((int) strlen(skinnames[j])) - 4, skinnames[j], | ||
148 | textureExtensions[i]); | ||
149 | if(g_file_test(skinname, G_FILE_TEST_EXISTS)) | ||
150 | image = g3d_texture_load_cached(context, model, skinname); | ||
151 | if(image) | ||
152 | break; | ||
153 | basename = g_path_get_basename(skinname); | ||
154 | if(g_file_test(basename, G_FILE_TEST_EXISTS)) | ||
155 | image = g3d_texture_load_cached(context, model, skinname); | ||
156 | g_free(basename); | ||
157 | if(image) | ||
158 | break; | ||
159 | } | ||
160 | if(image) | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | /* fallback skin name */ | ||
165 | if(image == NULL) | ||
166 | image = g3d_texture_load_cached(context, model, "tris0.bmp"); | ||
167 | if(image) | ||
168 | image->tex_env = G3D_TEXENV_REPLACE; | ||
169 | } | ||
170 | |||
171 | g3d_stream_seek(stream, offframes, G_SEEK_SET); | ||
172 | /* vertices per frame */ | ||
173 | #if DEBUG > 0 | ||
174 | g_debug("numframes: %d", numframes); | ||
175 | #endif | ||
176 | for(i = 0; i < numframes; i ++) { | ||
177 | G3DFloat s0,s1,s2, t0,t1,t2; | ||
178 | gchar fname[16]; | ||
179 | guint32 j; | ||
180 | |||
181 | s0 = g3d_stream_read_float_le(stream); /* scale */ | ||
182 | s1 = g3d_stream_read_float_le(stream); | ||
183 | s2 = g3d_stream_read_float_le(stream); | ||
184 | t0 = g3d_stream_read_float_le(stream); /* translate */ | ||
185 | t1 = g3d_stream_read_float_le(stream); | ||
186 | t2 = g3d_stream_read_float_le(stream); | ||
187 | g3d_stream_read(stream, fname, 16); /* frame name*/ | ||
188 | |||
189 | for(j = 0; j < numverts; j ++) { | ||
190 | G3DFloat x,y,z; | ||
191 | guint32 v,n; | ||
192 | |||
193 | v = g3d_stream_read_int8(stream); | ||
194 | x = (G3DFloat)v * s0 + t0; | ||
195 | v = g3d_stream_read_int8(stream); | ||
196 | y = (G3DFloat)v * s1 + t1; | ||
197 | v = g3d_stream_read_int8(stream); | ||
198 | z = (G3DFloat)v * s2 + t2; | ||
199 | n = g3d_stream_read_int8(stream); | ||
200 | if(i == 0) { | ||
201 | object->vertex_data[j * 3 + 0] = x; | ||
202 | object->vertex_data[j * 3 + 1] = y; | ||
203 | object->vertex_data[j * 3 + 2] = z; | ||
204 | |||
205 | normals[j * 3 + 0] = md2_normals[n * 3 + 0]; | ||
206 | normals[j * 3 + 1] = md2_normals[n * 3 + 1]; | ||
207 | normals[j * 3 + 2] = md2_normals[n * 3 + 2]; | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | g3d_stream_seek(stream, offtexs, G_SEEK_SET); | ||
213 | /* texture coordinates */ | ||
214 | if(numtexs > 0) { | ||
215 | texco = g_new0(G3DFloat, numtexs * 2); | ||
216 | for(i = 0; i < numtexs; i ++) { | ||
217 | texco[i * 2 + 0] = g3d_stream_read_int16_le(stream) / | ||
218 | (G3DFloat)skinwidth; | ||
219 | texco[i * 2 + 1] = g3d_stream_read_int16_le(stream) / | ||
220 | (G3DFloat)skinheight; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | /* faces */ | ||
225 | for(i = 0; i < numfaces; i ++) { | ||
226 | G3DFace *face; | ||
227 | guint32 i; | ||
228 | guint16 index; | ||
229 | |||
230 | face = g_new0(G3DFace, 1); | ||
231 | object->faces = g_slist_append(object->faces, face); | ||
232 | face->material = material; | ||
233 | face->vertex_count = 3; | ||
234 | face->vertex_indices = g_new0(guint32, 3); | ||
235 | face->tex_vertex_data = g_new0(G3DFloat, 3 * 2); | ||
236 | face->normals = g_new0(G3DFloat, 3 * 3); | ||
237 | face->flags |= G3D_FLAG_FAC_NORMALS; | ||
238 | |||
239 | if(image) | ||
240 | { | ||
241 | face->flags |= G3D_FLAG_FAC_TEXMAP; | ||
242 | face->tex_image = image; | ||
243 | } | ||
244 | |||
245 | for(i = 0; i < 3; i ++) | ||
246 | { | ||
247 | face->vertex_indices[i] = g3d_stream_read_int16_le(stream); | ||
248 | face->normals[i * 3 + 0] = | ||
249 | - normals[face->vertex_indices[i] * 3 + 0]; | ||
250 | face->normals[i * 3 + 1] = | ||
251 | - normals[face->vertex_indices[i] * 3 + 1]; | ||
252 | face->normals[i * 3 + 2] = | ||
253 | - normals[face->vertex_indices[i] * 3 + 2]; | ||
254 | } | ||
255 | |||
256 | for(i = 0; i < 3; i ++) | ||
257 | { | ||
258 | index = g3d_stream_read_int16_le(stream); | ||
259 | face->tex_vertex_data[i * 2 + 0] = texco[index * 2 + 0]; | ||
260 | face->tex_vertex_data[i * 2 + 1] = texco[index * 2 + 1]; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | |||
265 | /* free skin names */ | ||
266 | if(skinnames) | ||
267 | { | ||
268 | for(i = 0; i < numskins; i ++) | ||
269 | g_free(skinnames[i]); | ||
270 | g_free(skinnames); | ||
271 | } | ||
272 | |||
273 | if(texco) | ||
274 | g_free(texco); | ||
275 | if(normals) | ||
276 | g_free(normals); | ||
277 | |||
278 | return TRUE; | ||
279 | } | ||
280 | |||
281 | EAPI | ||
282 | gchar *plugin_description(G3DContext *context) | ||
283 | { | ||
284 | return g_strdup("ID Software's Quake II models."); | ||
285 | } | ||
286 | |||
287 | EAPI | ||
288 | gchar **plugin_extensions(G3DContext *context) | ||
289 | { | ||
290 | return g_strsplit("md2", ":", 0); | ||
291 | } | ||
292 | |||