aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c
new file mode 100644
index 0000000..5a73a1a
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_acf/imp_acf.c
@@ -0,0 +1,338 @@
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 <math.h>
25
26#include <g3d/types.h>
27#include <g3d/stream.h>
28#include <g3d/object.h>
29#include <g3d/face.h>
30#include <g3d/material.h>
31#include <g3d/matrix.h>
32#include <g3d/vector.h>
33
34#include "imp_acf.h"
35#include "imp_acf_airfoil.h"
36#include "imp_acf_wing.h"
37#include "imp_acf_def.h"
38#include "imp_acf_detect.h"
39
40static gboolean acf_load_body(AcfGlobalData *global);
41static gboolean acf_load_wings(AcfGlobalData *global);
42
43EAPI
44gpointer plugin_init(G3DContext *context)
45{
46 return acf_airfoil_init();
47}
48
49EAPI
50void plugin_cleanup(gpointer user_data)
51{
52 AcfAirfoilDb *db = user_data;
53
54 if(db)
55 acf_airfoil_cleanup(db);
56}
57
58EAPI
59gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
60 G3DModel *model, gpointer user_data)
61{
62 AcfGlobalData *global;
63 const AcfDef *def;
64 gboolean bigendian;
65 gchar magic;
66
67 magic = g3d_stream_read_int8(stream);
68 if(magic == 'i') {
69 bigendian = FALSE;
70 g_debug("ACF: intel file found");
71 } else if(magic == 'a') {
72 bigendian = TRUE;
73 g_debug("ACF: apple file found");
74 } else {
75 g_warning("ACF: not a valid .acf file");
76 return FALSE;
77 }
78
79 g3d_stream_seek(stream, 0, G_SEEK_SET);
80
81 global = g_new0(AcfGlobalData, 1);
82 global->context = context;
83 global->model = model;
84 global->stream = stream;
85 global->afldb = user_data;
86
87 def = acf_detect_version(global);
88 if(def == NULL) {
89 g_free(global);
90 return FALSE;
91 }
92
93 global->acf = acf_def_read(stream, def, bigendian);
94 if(global->acf == NULL) {
95 g_free(global);
96 return FALSE;
97 }
98
99 if(!acf_load_body(global)) {
100 acf_def_free(global->acf);
101 g_free(global);
102 return FALSE;
103 }
104 if(!acf_load_wings(global)) {
105 acf_def_free(global->acf);
106 g_free(global);
107 return FALSE;
108 }
109
110 acf_def_free(global->acf);
111 g_free(global);
112
113 return TRUE;
114}
115
116EAPI
117gchar *plugin_description(void)
118{
119 return g_strdup("XPlane models.");
120}
121
122EAPI
123gchar **plugin_extensions(void)
124{
125 return g_strsplit("acf", ":", 0);
126}
127
128/*****************************************************************************/
129
130#define ACF_OBJECT_MIN 44
131#define ACF_OBJECT_MAX 66
132#define ACF_BODY_NUMSEC 20
133#define ACF_BODY_SECVER 18
134#define ACF_VERTS_PER_OBJECT (ACF_BODY_NUMSEC * ACF_BODY_SECVER)
135
136#define ACF_REQUIRE_PART(var, name, t) do { \
137 var = acf_def_lookup(global->acf, name); \
138 if((var == NULL) || (var->type != t)) { \
139 g_warning("ACF: %s is missing or has wrong type", name); \
140 return FALSE; \
141 } } while(0);
142
143#define ACF_USE_PART(var, name, t) do { \
144 var = acf_def_lookup(global->acf, name); \
145 if((var != NULL) && (var->type != t)) { \
146 g_warning("ACF: %s has wrong type", name); \
147 var = NULL; \
148 } } while(0);
149
150static gboolean acf_load_body(AcfGlobalData *global)
151{
152 AcfValue *vpart_eq, *vbody_x, *vbody_y, *vbody_z, *vbody_r;
153 AcfValue *vxarm, *vyarm, *vzarm, *vx_body, *vy_body, *vz_body;
154 G3DObject *object;
155 G3DMaterial *material;
156 G3DFace *face;
157 gint32 i, j;
158 guint32 min_obj, max_obj;
159
160 /* lookup some required data in library an return FALSE if one of
161 * them is missing */
162 ACF_REQUIRE_PART(vpart_eq, "PARTS_part_eq", XINT);
163 ACF_REQUIRE_PART(vbody_x, "PARTS_body_X", XFLT);
164 ACF_REQUIRE_PART(vbody_y, "PARTS_body_Y", XFLT);
165 ACF_REQUIRE_PART(vbody_z, "PARTS_body_Z", XFLT);
166 ACF_REQUIRE_PART(vxarm, "PARTS_Xarm", XFLT);
167 ACF_REQUIRE_PART(vyarm, "PARTS_Yarm", XFLT);
168 ACF_REQUIRE_PART(vzarm, "PARTS_Zarm", XFLT);
169 ACF_REQUIRE_PART(vx_body, "PARTS_X_body_aero", XFLT);
170 ACF_REQUIRE_PART(vy_body, "PARTS_Y_body_aero", XFLT);
171 ACF_REQUIRE_PART(vz_body, "PARTS_Z_body_aero", XFLT);
172 ACF_REQUIRE_PART(vbody_r, "PARTS_body_r", XFLT);
173
174 material = g3d_material_new();
175 material->name = g_strdup("(default material)");
176 global->model->materials = g_slist_append(global->model->materials,
177 material);
178
179 min_obj = ACF_OBJECT_MIN;
180 max_obj = MIN(ACF_OBJECT_MAX, (vpart_eq->num - 1));
181 if(vpart_eq->num <= 57) {
182 min_obj = 30;
183 max_obj = 49;
184 }
185
186 for(i = min_obj; i <= max_obj; i ++) {
187 if(!vpart_eq->xint[i])
188 continue;
189
190 g_debug("ACF: part[%i]: (%.2f, %.2f, %.2f), %.2f", i,
191 vx_body->xflt[i], vy_body->xflt[i], vz_body->xflt[i],
192 vbody_r->xflt[i]);
193
194 object = g_new0(G3DObject, 1);
195 object->name = g_strdup_printf("object[%d]", i);
196 object->vertex_count = ACF_VERTS_PER_OBJECT;
197 object->vertex_data = g_new0(G3DFloat, object->vertex_count * 3);
198 for(j = 0; j < object->vertex_count; j ++) {
199 object->vertex_data[j * 3 + 0] =
200 vbody_x->xflt[i * ACF_VERTS_PER_OBJECT + j] + vxarm->xflt[i];
201 object->vertex_data[j * 3 + 1] =
202 vbody_y->xflt[i * ACF_VERTS_PER_OBJECT + j] + vyarm->xflt[i];
203 object->vertex_data[j * 3 + 2] =
204 vbody_z->xflt[i * ACF_VERTS_PER_OBJECT + j] + vzarm->xflt[i];
205#if DEBUG > 3
206 g_debug("\tVERT: (%04d) %.3f, %.3f, %.3f", j,
207 object->vertex_data[j * 3 + 0],
208 object->vertex_data[j * 3 + 1],
209 object->vertex_data[j * 3 + 2]);
210#endif
211 }
212
213 global->model->objects = g_slist_append(global->model->objects,
214 object);
215
216 for(j = 0; j < (ACF_VERTS_PER_OBJECT - ACF_BODY_SECVER - 1); j ++) {
217 face = g3d_face_new_tri(material, j + 1, j, j + ACF_BODY_SECVER);
218 object->faces = g_slist_prepend(object->faces, face);
219
220 face = g3d_face_new_tri(material, j + ACF_BODY_SECVER,
221 j + ACF_BODY_SECVER + 1, j + 1);
222 object->faces = g_slist_prepend(object->faces, face);
223 }
224 }
225
226 return TRUE;
227}
228
229static gboolean acf_load_wings(AcfGlobalData *global)
230{
231 AcfValue *vpart_eq, *vrafl0, *vtafl0;
232 AcfValue *vctip, *vcroot, *vdihed, *vsweep, *vels;
233 AcfValue *vxarm, *vyarm, *vzarm, *visleft, *vlatsign;
234 AcfValue *vslseg, *vsljnd, *vpartss, *vpartse;
235 AcfAirfoil *afrt, *aftp;
236 G3DObject *object;
237 G3DMaterial *material;
238 gint32 i;
239 guint32 cnt;
240 G3DFloat m_dihed[16], m_sweep[16], m_trans[16];
241 G3DFloat vecrt[3], vectp[3], lf, ls;
242 gchar *title;
243
244 ACF_REQUIRE_PART(vpart_eq, "PARTS_part_eq", XINT);
245 ACF_REQUIRE_PART(vrafl0, "PARTS_Rafl0", XCHR);
246 ACF_REQUIRE_PART(vtafl0, "PARTS_Tafl0", XCHR);
247 ACF_REQUIRE_PART(vcroot, "PARTS_Croot", XFLT);
248 ACF_REQUIRE_PART(vctip, "PARTS_Ctip", XFLT);
249 ACF_REQUIRE_PART(vels, "PARTS_els", XINT);
250 ACF_REQUIRE_PART(vxarm, "PARTS_Xarm", XFLT);
251 ACF_REQUIRE_PART(vyarm, "PARTS_Yarm", XFLT);
252 ACF_REQUIRE_PART(vzarm, "PARTS_Zarm", XFLT);
253
254 ACF_USE_PART(vdihed, "PARTS_dihed", XFLT);
255 if(vdihed == NULL)
256 ACF_REQUIRE_PART(vdihed, "PARTS_dihed1", XFLT);
257 ACF_USE_PART(vsweep, "PARTS_sweep", XFLT);
258 if(vsweep == NULL)
259 ACF_REQUIRE_PART(vsweep, "PARTS_sweep1", XFLT);
260
261 ACF_REQUIRE_PART(vpartss, "PARTS_s", XFLT);
262 ACF_REQUIRE_PART(vpartse, "PARTS_e", XFLT);
263 ACF_REQUIRE_PART(vlatsign, "OVERFLOW_lat_sign", XFLT);
264 ACF_REQUIRE_PART(vslseg, "PARTS_semilen_SEG", XFLT);
265 ACF_REQUIRE_PART(vsljnd, "PARTS_semilen_JND", XFLT);
266
267 ACF_USE_PART(visleft, "OVERFLOW_is_left", XINT);
268
269
270 material = g_slist_nth_data(global->model->materials, 0);
271
272 cnt = vrafl0->num / vpart_eq->num;
273
274 for(i = 8; i < vpart_eq->num; i ++) {
275 if(strlen(vrafl0->xchr + i * cnt) == 0)
276 continue;
277 if(vels->xint[i] == 0)
278 continue;
279#if DEBUG > 0
280 g_debug("PARTS_Rafl0[%d]: %s", i, vrafl0->xchr + i * cnt);
281 g_debug("PARTS_Tafl0[%d]: %s", i, vtafl0->xchr + i * cnt);
282 g_debug(
283 "[%i] lat_sign=%.2f, Croot=%.2f, Ctip=%.2f, dihed=%.2f, els=%i", i,
284 vlatsign->xflt[i],
285 vcroot->xflt[i], vctip->xflt[i],
286 vdihed ? vdihed->xflt[i] : -1337.0,
287 vels->xint[i]);
288 g_debug("[%i] semilen_SEG=%.2f, semilen_JND=%.2f, parts_e=%.2f", i,
289 vslseg->xflt[i], vsljnd->xflt[i], vpartse->xflt[i]);
290 g_debug("PARTS_s[%i]: %f, %f ... %f, %f", i,
291 vpartss->xflt[i * 10 + 0], vpartss->xflt[i * 10 + 1],
292 vpartss->xflt[i * 10 + 8], vpartss->xflt[i * 10 + 9]);
293#endif
294 afrt = acf_airfoil_lookup(global->afldb, "naca16006.dat");
295 aftp = acf_airfoil_lookup(global->afldb, "naca16006.dat");
296 if((afrt == NULL) || (aftp == NULL))
297 continue;
298
299 if(afrt->vertex_count != aftp->vertex_count) {
300 g_warning("ACF: airfoil vertex count mismatch: %s=%d, %s=%d",
301 afrt->filename, afrt->vertex_count,
302 aftp->filename, aftp->vertex_count);
303 continue;
304 }
305
306 lf = ((visleft && visleft->xint[i]) ? -1 : 1);
307 ls = (vlatsign ? vlatsign->xflt[i] : 1.0);
308
309 /* translation */
310 g3d_matrix_identity(m_trans);
311 g3d_matrix_translate(vxarm->xflt[i], vyarm->xflt[i], vzarm->xflt[i],
312 m_trans);
313
314 /* rotation matrices */
315 g3d_matrix_rotate(lf * vdihed->xflt[i] * G_PI / 180.0,
316 0.0, 0.0, 1.0, m_dihed);
317 g3d_matrix_rotate(lf * -1.0 * vsweep->xflt[i] * G_PI / 180.0,
318 0.0, 1.0, 0.0, m_sweep);
319
320 /* wing root & tip center */
321 memset(vecrt, 0, sizeof(vecrt));
322 memset(vectp, 0, sizeof(vectp));
323 vectp[0] = vslseg->xflt[i];
324 g3d_vector_transform(vectp, vectp + 1, vectp + 2, m_dihed);
325 g3d_vector_transform(vectp, vectp + 1, vectp + 2, m_sweep);
326
327 title = g_strdup_printf("Wing[%d]", i);
328 object = acf_wing(material, title,
329 m_sweep, m_dihed, m_trans,
330 vecrt, vectp,
331 afrt, aftp,
332 vcroot->xflt[i], vctip->xflt[i], lf);
333 g_free(title);
334 global->model->objects = g_slist_append(global->model->objects,
335 object);
336 }
337 return TRUE;
338}