summaryrefslogtreecommitdiff
path: root/src/modules/evas/model_loaders/obj
diff options
context:
space:
mode:
authorBogdan Devichev <b.devichev@samsung.com>2014-11-27 13:27:01 +0200
committerCedric BAIL <cedric@osg.samsung.com>2014-12-23 21:14:30 +0100
commit9b7e22f5a5a2ee734264265267e2186cbebce65c (patch)
treecc175159cdd5320b1e9ecbd0644a927c49eb4894 /src/modules/evas/model_loaders/obj
parent8c09ad1b81b0139b6c97444b232950bd2a0df5e6 (diff)
evas: replace and rename savers/loaders.
Diffstat (limited to 'src/modules/evas/model_loaders/obj')
-rw-r--r--src/modules/evas/model_loaders/obj/evas_model_load_obj.c402
1 files changed, 401 insertions, 1 deletions
diff --git a/src/modules/evas/model_loaders/obj/evas_model_load_obj.c b/src/modules/evas/model_loaders/obj/evas_model_load_obj.c
index 8940b65..c6733a7 100644
--- a/src/modules/evas/model_loaders/obj/evas_model_load_obj.c
+++ b/src/modules/evas/model_loaders/obj/evas_model_load_obj.c
@@ -1 +1,401 @@
1//dummy of saver/loader 1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6#include "stdio.h"
7#include "evas_common_private.h"
8#include "evas_private.h"
9
10/* set value to position [x][y] to array name which have. */
11#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
12
13/* read 3 float values in string and put it in array */
14#define PUT_DATA_TO_ARRAY(array_name, name) \
15 sscanf (current,"%f %f %f", \
16 &ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 0, 3), \
17 &ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 1, 3), \
18 &ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 2, 3)); \
19 counts.current_##name##_counter++;
20
21/* Structures for reading data from file. */
22typedef struct _OBJ_Counts OBJ_Counts;
23
24struct _OBJ_Counts
25{
26 int _vertex_counter;
27 int _normal_counter;
28 int _texture_point_counter;
29 int _triangles_counter;
30
31 int current_vertex_counter;
32 int current_normal_counter;
33 int current_texture_point_counter;
34 int current_triangles_counter;
35
36 Eina_Bool existence_of_normal;
37 Eina_Bool existence_of_tex_point;
38};
39
40static inline char*
41_file_to_buf(const char *file, long *length)//prepare text file for reading
42{
43 FILE *file_for_print;
44 char *buf;
45 int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
46
47 *length = 0;
48 file_for_print = fopen(file, "rb");
49 if (!file_for_print) return NULL;
50 fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
51 *length = ftell(file_for_print);//set current position of file_for_print
52 if (*length < 0)
53 {
54 fclose(file_for_print);
55 return NULL;
56 }
57 buf = malloc(*length + 1);
58 fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
59 unused = fread(buf, *length, 1, file_for_print);
60 fclose(file_for_print);
61 buf[*length] = '\0';
62 return buf;
63}
64
65/* create new counter */
66static inline OBJ_Counts
67_new_count_elements()
68{
69 OBJ_Counts counts;
70
71 counts._vertex_counter = 0;
72 counts._normal_counter = 0;
73 counts._texture_point_counter = 0;
74 counts._triangles_counter = 0;
75
76 counts.current_vertex_counter = 0;
77 counts.current_normal_counter = 0;
78 counts.current_texture_point_counter = 0;
79 counts.current_triangles_counter = 0;
80
81 counts.existence_of_normal = EINA_FALSE;
82 counts.existence_of_tex_point = EINA_FALSE;
83 return counts;
84}
85
86/* count triangles in face */
87static void
88_analyze_face_line(char * face_analyzer,
89 int * count_of_triangles_in_line)
90{
91 int polygon_checker = -2;
92 Eina_Bool previous_is_space = EINA_TRUE;
93 while ((*face_analyzer != '\n') && (*face_analyzer != '#'))
94 {
95 if (*face_analyzer == ' ')
96 {
97 previous_is_space = EINA_TRUE;
98 }
99 else if ((previous_is_space) && (*face_analyzer >= '0') && (*face_analyzer <= '9'))
100 {
101 polygon_checker++;
102 previous_is_space = EINA_FALSE;
103 }
104 face_analyzer++;
105 }
106 *count_of_triangles_in_line = polygon_checker;
107}
108
109static inline OBJ_Counts
110_count_elements(char *start, long length)//count elements of mesh in .obj
111{
112 OBJ_Counts counts = _new_count_elements();
113
114 char * current = start;
115 int polygon_checker = -2;//polygons with n vertices can be represented as n-2 triangles
116 Eina_Bool will_check_next_char = EINA_FALSE;
117 Eina_Bool first_char_is_v = EINA_FALSE;
118 Eina_Bool first_char_is_f = EINA_FALSE;
119 Eina_Bool previous_is_space = EINA_FALSE;
120
121 long i = 0;
122 /* count elements of mesh in .obj */
123 for (; length > i; i++)
124 {
125 if (will_check_next_char)
126 {
127 if (first_char_is_v)
128 {
129 switch (*current)
130 {
131 case ' ':
132 counts._vertex_counter++;
133 break;
134 case 't':
135 counts._texture_point_counter++;
136 counts.existence_of_tex_point = EINA_TRUE;
137 break;
138 case 'n':
139 counts._normal_counter++;
140 counts.existence_of_normal = EINA_TRUE;
141 break;
142 default:
143 break;
144 }
145 first_char_is_v = EINA_FALSE;
146 will_check_next_char = EINA_FALSE;
147 }
148 else if (first_char_is_f)
149 {
150 switch (*current)
151 {
152 case '\n':
153 first_char_is_f = EINA_FALSE;
154 counts._triangles_counter += polygon_checker;
155 polygon_checker = -2;
156 previous_is_space = EINA_FALSE;
157 break;
158 case '#':
159 first_char_is_f = EINA_FALSE;
160 counts._triangles_counter += polygon_checker;
161 polygon_checker = -2;
162 previous_is_space = EINA_FALSE;
163 break;
164 case ' ':
165 previous_is_space = EINA_TRUE;
166 break;
167 default:
168 if ((previous_is_space) && (*current >= '0') && (*current <= '9'))
169 {
170 polygon_checker++;
171 previous_is_space = EINA_FALSE;
172 }
173 break;
174 }
175 }
176 else
177 {
178 switch (*current)
179 {
180 case 'v':
181 first_char_is_v = EINA_TRUE;
182 break;
183 case 'f':
184 first_char_is_f = EINA_TRUE;
185 break;
186 case 'm':
187 will_check_next_char = EINA_FALSE;
188 break;
189 default:
190 will_check_next_char = EINA_FALSE;
191 break;
192 }
193 }
194 }
195 else if (*current == '\n')
196 {
197 will_check_next_char = EINA_TRUE;
198 }
199 current++;
200 }
201 return counts;
202}
203
204void
205evas_3d_mesh_file_obj_set(Evas_3D_Mesh *mesh, const char *file)
206{
207 long length, i;
208 char * start = _file_to_buf(file, &length);
209 OBJ_Counts counts = _count_elements(start, length);//count elements of mesh in .obj
210 Eina_Bool will_check_next_char = EINA_FALSE;
211 Eina_Bool first_char_is_v = EINA_FALSE;
212 Eina_Bool first_char_is_f = EINA_FALSE;
213 float *pos, *nor, *tex;
214 int stride_pos, stride_nor, stride_tex;
215 int j, k;
216 char * current;
217
218 float *_vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float));
219 float *_normales_obj = malloc(counts._normal_counter * 3 * sizeof(float));
220 float *_tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float));
221 /* triangle has 3 points, every point has 3(vertix, texture and normal) coord */
222 int *_triangles = malloc(counts._triangles_counter * 9 * sizeof(int));
223
224 if ((start == NULL) || (_vertices_obj == NULL) ||
225 (_normales_obj == NULL) || (_tex_coords_obj == NULL) || (_triangles == NULL))
226 {
227 ERR("Allocate memory is failed.");
228 free(start);
229 free(_vertices_obj);
230 free(_normales_obj);
231 free(_tex_coords_obj);
232 free(_triangles);
233 return;
234 }
235
236 current = start;
237 i = 0;
238
239 /* put data to arrays */
240 for (; length > i; i++)
241 {
242 if (will_check_next_char)
243 {
244 if (first_char_is_v)
245 {
246 switch (*current)
247 {
248 case ' ':
249 PUT_DATA_TO_ARRAY(vertices, vertex)
250 i--;
251 break;
252 case 't':
253 current++;
254 PUT_DATA_TO_ARRAY(tex_coords, texture_point)
255 break;
256 case 'n':
257 current++;
258 PUT_DATA_TO_ARRAY(normales, normal)
259 break;
260 default:
261 break;
262 }
263 first_char_is_v = EINA_FALSE;
264 will_check_next_char = EINA_FALSE;
265 }
266 else if (first_char_is_f)
267 {
268 char * auxiliary_pointer = current;
269 int count_of_triangles_in_line;
270
271 _analyze_face_line(auxiliary_pointer,
272 &count_of_triangles_in_line);
273 current++;
274 i++;
275 int first_pos, first_tex, first_norm;
276 sscanf (current,"%i/%i/%i",
277 &first_pos,
278 &first_tex,
279 &first_norm);
280
281 do
282 {
283 current++;
284 i++;
285 }
286 while (*current != ' ');
287
288 current++;
289 i++;
290
291 for (j = 0; j < count_of_triangles_in_line; j++)
292 {
293 auxiliary_pointer = current;
294 ARRAY_2D(_triangles, counts.current_triangles_counter, 0, 9) = first_pos;
295 ARRAY_2D(_triangles, counts.current_triangles_counter, 1, 9) = first_tex;
296 ARRAY_2D(_triangles, counts.current_triangles_counter, 2, 9) = first_norm;
297 sscanf (auxiliary_pointer,"%i/%i/%i %i/%i/%i",
298 &ARRAY_2D(_triangles, counts.current_triangles_counter, 3, 9),
299 &ARRAY_2D(_triangles, counts.current_triangles_counter, 4, 9),
300 &ARRAY_2D(_triangles, counts.current_triangles_counter, 5, 9),
301 &ARRAY_2D(_triangles, counts.current_triangles_counter, 6, 9),
302 &ARRAY_2D(_triangles, counts.current_triangles_counter, 7, 9),
303 &ARRAY_2D(_triangles, counts.current_triangles_counter, 8, 9));
304
305 while (*current != ' ')
306 {
307 current++;
308 i++;
309 }
310
311 counts.current_triangles_counter++;
312 }
313 first_char_is_f = EINA_FALSE;
314 }
315 else
316 {
317 switch (*current)
318 {
319 case 'v':
320 first_char_is_v = EINA_TRUE;
321 break;
322 case 'f':
323 first_char_is_f = EINA_TRUE;
324 break;
325 case 'm':
326 will_check_next_char = EINA_FALSE;
327 break;
328 default:
329 will_check_next_char = EINA_FALSE;
330 break;
331 }
332 }
333 }
334 else if (*current == '\n')
335 {
336 will_check_next_char = EINA_TRUE;
337 }
338 current++;
339 }
340 free(start);
341
342 /* prepare of mesh and take pointers to data which must be read */
343 eo_do(mesh,
344 evas_3d_mesh_vertex_count_set(counts._triangles_counter * 3),
345 evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
346 evas_3d_mesh_frame_add(0),
347 evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
348 evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
349 evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
350
351 pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
352 nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
353 tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
354
355 stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
356 stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
357 stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
358
359 if (stride_pos == 0) stride_pos = sizeof(float) * 3;
360 if (stride_nor == 0) stride_nor = sizeof(float) * 3;
361 if (stride_tex == 0) stride_tex = sizeof(float) * 2;
362
363 for (j = 0; j < counts._triangles_counter; j++)
364 {
365 for (k = 0; k < 3; k++)
366 {
367 float *p, *n, *t;
368
369 p = (float *)((char *)pos + stride_pos * (j * 3 + k));
370 n = (float *)((char *)nor + stride_nor * (j * 3 + k));
371 t = (float *)((char *)tex + stride_tex * (j * 3 + k));
372
373 p[0] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 0, 3);
374 p[1] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 1, 3);
375 p[2] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 2, 3);
376
377 n[0] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 0, 3);
378 n[1] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 1, 3);
379 n[2] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 2, 3);
380
381 t[0] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 0, 3);
382 t[1] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 1, 3);
383 }
384 }
385 free(_vertices_obj);
386 free(_normales_obj);
387 free(_tex_coords_obj);
388 free(_triangles);
389 /* Unmap vertex buffer. */
390 eo_do(mesh,
391 evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
392 evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
393 evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
394
395 Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
396
397 if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
398 {
399 ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
400 }
401}