aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c
new file mode 100644
index 0000000..d9bea0b
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_glb/imp_glb.c
@@ -0,0 +1,258 @@
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 <stdlib.h>
25#include <string.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/iff.h>
32#include <g3d/vector.h>
33
34static G3DObject *glb_load_object(G3DContext *context, G3DStream *stream,
35 G3DModel *model);
36
37EAPI
38gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
39 G3DModel *model, gpointer user_data)
40{
41 return (glb_load_object(context, stream, model) != NULL);
42}
43
44EAPI
45gchar *plugin_description(G3DContext *context)
46{
47 return g_strdup("UltimateStunts models.");
48}
49
50EAPI
51gchar **plugin_extensions(G3DContext *context)
52{
53 return g_strsplit("glb", ":", 0);
54}
55
56/*****************************************************************************/
57/* GLB specific */
58
59static G3DFloat glb_get_float(G3DStream *stream)
60{
61 return 0.001 * (
62 (float)((guint32)g3d_stream_read_int32_be(stream)) - (float)(0x7FFFFFFF));
63}
64
65static G3DObject *glb_load_object(G3DContext *context, G3DStream *stream,
66 G3DModel *model)
67{
68 G3DObject *pobject, *object;
69 G3DMaterial *material;
70 G3DFace *face;
71 guint32 magic, otype, index;
72 gint32 i, j, msize, namelen, datalen, nvertices, nindices;
73 gchar *name;
74 G3DFloat *normals = NULL, *texcoords = NULL;
75
76 magic = g3d_stream_read_int32_be(stream);
77 if(magic != G3D_IFF_MKID('\0', 'G', 'L', 'B')) {
78 g_warning("%s is not a correct GLB file (wrong magic)\n",
79 stream->uri);
80 return NULL;
81 }
82
83 pobject = g_new0(G3DObject, 1);
84 pobject->name = g_strdup(stream->uri);
85 model->objects = g_slist_append(model->objects, pobject);
86
87 while(!g3d_stream_eof(stream)) {
88 otype = g3d_stream_read_int32_be(stream);
89 namelen = g3d_stream_read_int32_be(stream);
90
91 if(namelen == 0)
92 break;
93
94 name = g_new0(gchar, namelen + 1);
95 g3d_stream_read(stream, name, namelen);
96#if DEBUG > 0
97 printf("GLB: object named '%s'\n", name);
98#endif
99
100 object = g_new0(G3DObject, 1);
101 object->name = g_strdup(name);
102 g_free(name);
103 pobject->objects = g_slist_append(pobject->objects, object);
104
105 /* hide collision planes by default */
106 if(strncmp(object->name, "Collision plane", 15) == 0)
107 object->hide = TRUE;
108
109 datalen = g3d_stream_read_int32_be(stream);
110
111 if(otype != 0) {
112 /* skip */
113 g3d_stream_skip(stream, datalen);
114 continue;
115 }
116
117 /* object type 0 */
118 msize = g3d_stream_read_int32_be(stream);
119 nvertices = g3d_stream_read_int32_be(stream);
120 nindices = g3d_stream_read_int32_be(stream);
121
122#if DEBUG > 0
123 printf("GLB: material size: %d bytes, %d vertices, %d indices\n",
124 msize, nvertices, nindices);
125#endif
126 if(msize > 0) {
127 /* material */
128 material = g3d_material_new();
129 material->name = g_strdup("default material");
130 object->materials = g_slist_append(object->materials, material);
131
132 material->r = (G3DFloat)g3d_stream_read_int8(stream) / 255.0;
133 material->g = (G3DFloat)g3d_stream_read_int8(stream) / 255.0;
134 material->b = (G3DFloat)g3d_stream_read_int8(stream) / 255.0;
135 material->a = (G3DFloat)g3d_stream_read_int8(stream) / 255.0;
136
137 if(material->a == 0.0)
138 material->a = 1.0;
139
140 /* replacement color */
141 g3d_stream_read_int8(stream);
142 g3d_stream_read_int8(stream);
143 g3d_stream_read_int8(stream);
144 g3d_stream_read_int8(stream); /* unused */
145
146 g3d_stream_read_int8(stream); /* LODs */
147 g3d_stream_read_int8(stream); /* reflectance */
148 /* emissivity */
149 material->shininess = (G3DFloat)g3d_stream_read_int8(stream) / 255.0;
150 g3d_stream_read_int8(stream); /* static friction */
151 g3d_stream_read_int8(stream); /* dynamic friction */
152 g3d_stream_read_int8(stream); /* unused */
153 g3d_stream_read_int8(stream); /* unused */
154 g3d_stream_read_int8(stream); /* unused */
155
156 /* texture name */
157 namelen = msize - 16;
158 if(namelen > 0) {
159 name = g_new0(gchar, namelen + 1);
160 g3d_stream_read(stream, name, namelen);
161#if DEBUG > 1
162 printf("GLB: texture name: %s\n", name);
163#endif
164
165 /* texture name is something like "0", the real name is in
166 * "../$carname.conf"; try to load default texture */
167 if(name[0] == '0') {
168 if(g_file_test("textures.jpg", G_FILE_TEST_EXISTS)) {
169 material->tex_image = g3d_texture_load_cached(
170 context, model, "textures.jpg");
171 if(material->tex_image != NULL)
172 material->tex_image->tex_id = 1;
173 }
174 }
175
176 g_free(name);
177 }
178 }
179
180 /* vertices */
181 if(nvertices > 0) {
182 object->vertex_count = nvertices;
183 object->vertex_data = g_new0(G3DFloat, nvertices * 3);
184 normals = g_new0(G3DFloat, nvertices * 3);
185 texcoords = g_new0(G3DFloat, nvertices * 2);
186
187 for(i = 0; i < nvertices; i ++) {
188 object->vertex_data[i * 3 + 0] = glb_get_float(stream);
189 object->vertex_data[i * 3 + 1] = glb_get_float(stream);
190 object->vertex_data[i * 3 + 2] = glb_get_float(stream);
191
192#if DEBUG > 3
193 printf("D: %f, %f, %f\n",
194 object->vertex_data[i * 3 + 0],
195 object->vertex_data[i * 3 + 1],
196 object->vertex_data[i * 3 + 2]);
197#endif
198
199 /* normal */
200 normals[i * 3 + 0] = glb_get_float(stream);
201 normals[i * 3 + 1] = glb_get_float(stream);
202 normals[i * 3 + 2] = glb_get_float(stream);
203 g3d_vector_unify(
204 normals + i * 3 + 0,
205 normals + i * 3 + 1,
206 normals + i * 3 + 2);
207
208 /* texture coordinates */
209 texcoords[i * 2 + 0] = glb_get_float(stream) / 64;
210 texcoords[i * 2 + 1] = 1.0 - glb_get_float(stream) / 64;
211 }
212 }
213
214 if(nindices > 0) {
215 for(i = 0; i < nindices; i += 3) {
216 face = g_new0(G3DFace, 1);
217 face->vertex_count = 3;
218 face->vertex_indices = g_new0(guint32, 3);
219 face->normals = g_new0(G3DFloat, 3 * 3);
220 face->flags |= G3D_FLAG_FAC_NORMALS;
221 for(j = 0; j < 3; j ++) {
222 face->vertex_indices[j] = g3d_stream_read_int32_be(stream);
223
224 /* set normals */
225 index = face->vertex_indices[j];
226 face->normals[j * 3 + 0] = normals[index * 3 + 0];
227 face->normals[j * 3 + 1] = normals[index * 3 + 1];
228 face->normals[j * 3 + 2] = normals[index * 3 + 2];
229 }
230 face->material = g_slist_nth_data(object->materials, 0);
231
232 if(face->material->tex_image != NULL) {
233 face->tex_vertex_count = 3;
234 face->tex_vertex_data = g_new0(G3DFloat, 3 * 2);
235 face->tex_image = face->material->tex_image;
236 for(j = 0; j < 3; j ++) {
237 index = face->vertex_indices[j];
238
239 face->tex_vertex_data[j * 2 + 0] =
240 texcoords[index * 2 + 0];
241 face->tex_vertex_data[j * 2 + 1] =
242 texcoords[index * 2 + 1];
243 face->flags |= G3D_FLAG_FAC_TEXMAP;
244 }
245 }
246
247 object->faces = g_slist_append(object->faces, face);
248 }
249 }
250
251 if(normals != NULL)
252 g_free(normals);
253 if(texcoords != NULL)
254 g_free(texcoords);
255 }
256
257 return pobject;
258}