aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/evas
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/evas')
-rw-r--r--src/modules/evas/model_loaders/obj/evas_model_load_obj.c205
-rw-r--r--src/modules/evas/model_savers/obj/evas_model_save_obj.c107
2 files changed, 208 insertions, 104 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 64c4eb9e58..24f38c4cc7 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
@@ -12,13 +12,21 @@
#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
/* read 3 float values in string and put it in array */
-#define PUT_DATA_TO_ARRAY(array_name, name) \
- sscanf (current,"%f %f %f", \
+#define PUT_DATA_TO_ARRAY(array_name, name) \
+ sscanf (current,"%f %f %f", \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 0, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 1, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 2, 3)); \
counts.current_##name##_counter++;
+#define AFTER_NEXT_SPACE(pointer)\
+ do \
+ { \
+ pointer++; \
+ i++; \
+ } \
+ while (*pointer != ' ');
+
/* Structures for reading data from file. */
typedef struct _OBJ_Counts OBJ_Counts;
@@ -177,6 +185,37 @@ _count_elements(char *map)//count elements of mesh in .obj
return counts;
}
+static void
+_read_point(int *triangles,
+ int num,
+ OBJ_Counts counts,
+ int num_cur,
+ char *pointer)
+{
+ if (counts.existence_of_normal)
+ {
+ if (counts.existence_of_tex_point)
+ sscanf(pointer, "%i/%i/%i",
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3, 9),
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3 + 1, 9),
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3 + 2, 9));
+ else
+ sscanf(pointer, "%i//%i",
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3, 9),
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3 + 2, 9));
+ }
+ else
+ {
+ if (counts.existence_of_tex_point)
+ sscanf(pointer, "%i/%i",
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3, 9),
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3 + 1, 9));
+ else
+ sscanf(pointer, "%i",
+ &ARRAY_2D(triangles, num_cur, (num - 1) * 3, 9));
+ }
+}
+
void
evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
{
@@ -187,8 +226,10 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
Eina_Bool first_char_is_f = EINA_FALSE;
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex;
- int j, k;
+ int j, k, data_for_one_point;
char *current, *map;
+ float *_vertices_obj, *_normales_obj, *_tex_coords_obj;
+ int *_triangles;
map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
@@ -199,27 +240,36 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
}
counts = _count_elements(map);
+ _vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float));
+ data_for_one_point = 1;
+ if (counts.existence_of_normal)
+ {
+ data_for_one_point++;
+ _normales_obj = malloc(counts._normal_counter * 3 * sizeof(float));
+ }
+ if (counts.existence_of_tex_point)
+ {
+ data_for_one_point++;
+ _tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float));
+ }
+ _triangles = malloc(counts._triangles_counter * 9 * sizeof(int));
- float *_vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float));
- float *_normales_obj = malloc(counts._normal_counter * 3 * sizeof(float));
- float *_tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float));
- /* triangle has 3 points, every point has 3(vertix, texture and normal) coord */
- int *_triangles = malloc(counts._triangles_counter * 9 * sizeof(int));
-
- if ((map == NULL) || (_vertices_obj == NULL) ||
- (_normales_obj == NULL) || (_tex_coords_obj == NULL) || (_triangles == NULL))
+ if ((map == NULL) || (_vertices_obj == NULL) || (_triangles == NULL) ||
+ ((counts.existence_of_normal) && (_normales_obj == NULL)) ||
+ ((counts.existence_of_tex_point) && (_tex_coords_obj == NULL)))
{
ERR("Allocate memory is failed.");
free(_vertices_obj);
- free(_normales_obj);
- free(_tex_coords_obj);
free(_triangles);
+ if (counts.existence_of_normal)
+ free(_normales_obj);
+ if (counts.existence_of_tex_point)
+ free(_tex_coords_obj);
return;
}
current = map;
i = 0;
-
/* put data to arrays */
for (; *current != '\00'; i++)
{
@@ -235,11 +285,17 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
break;
case 't':
current++;
- PUT_DATA_TO_ARRAY(tex_coords, texture_point)
+ if (counts.existence_of_tex_point)
+ {
+ PUT_DATA_TO_ARRAY(tex_coords, texture_point)
+ }
break;
case 'n':
current++;
- PUT_DATA_TO_ARRAY(normales, normal)
+ if (counts.existence_of_normal)
+ {
+ PUT_DATA_TO_ARRAY(normales, normal)
+ }
break;
default:
break;
@@ -249,49 +305,42 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
}
else if (first_char_is_f)
{
- char * auxiliary_pointer = current;
+ char *auxiliary_pointer = current;
int count_of_triangles_in_line;
+ int the_first_point = counts.current_triangles_counter;
_analyze_face_line(auxiliary_pointer,
&count_of_triangles_in_line);
current++;
i++;
- int first_pos, first_tex, first_norm;
- sscanf (current,"%i/%i/%i",
- &first_pos,
- &first_tex,
- &first_norm);
+ _read_point(_triangles, 1, counts,
+ the_first_point,
+ current);
- do
- {
- current++;
- i++;
- }
- while (*current != ' ');
-
- current++;
- i++;
+ AFTER_NEXT_SPACE(current)
for (j = 0; j < count_of_triangles_in_line; j++)
{
auxiliary_pointer = current;
- ARRAY_2D(_triangles, counts.current_triangles_counter, 0, 9) = first_pos;
- ARRAY_2D(_triangles, counts.current_triangles_counter, 1, 9) = first_tex;
- ARRAY_2D(_triangles, counts.current_triangles_counter, 2, 9) = first_norm;
- sscanf (auxiliary_pointer,"%i/%i/%i %i/%i/%i",
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 3, 9),
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 4, 9),
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 5, 9),
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 6, 9),
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 7, 9),
- &ARRAY_2D(_triangles, counts.current_triangles_counter, 8, 9));
-
- while (*current != ' ')
+ if (counts.current_triangles_counter != the_first_point)
{
- current++;
- i++;
+ ARRAY_2D(_triangles, counts.current_triangles_counter, 0, 9) = \
+ ARRAY_2D(_triangles, the_first_point, 0, 9);
+ ARRAY_2D(_triangles, counts.current_triangles_counter, 1, 9) = \
+ ARRAY_2D(_triangles, the_first_point, 1, 9);
+ ARRAY_2D(_triangles, counts.current_triangles_counter, 2, 9) = \
+ ARRAY_2D(_triangles, the_first_point, 2, 9);
}
+ _read_point(_triangles, 2, counts,
+ counts.current_triangles_counter,
+ auxiliary_pointer);
+ AFTER_NEXT_SPACE(auxiliary_pointer);
+ _read_point(_triangles, 3, counts,
+ counts.current_triangles_counter,
+ auxiliary_pointer);
+ AFTER_NEXT_SPACE(current);
+
counts.current_triangles_counter++;
}
first_char_is_f = EINA_FALSE;
@@ -328,20 +377,26 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
- evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
- evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
-
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
- nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
- tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
+ stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION));
- stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
- stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
- stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
+ if (counts.existence_of_normal)
+ eo_do(mesh,
+ evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
+ nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
+ stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL));
+
+ if (counts.existence_of_tex_point)
+ eo_do(mesh,
+ evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
+ tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
+ stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
- if (stride_nor == 0) stride_nor = sizeof(float) * 3;
- if (stride_tex == 0) stride_tex = sizeof(float) * 2;
+ if ((counts.existence_of_normal) && (stride_nor == 0))
+ stride_nor = sizeof(float) * 3;
+ if ((counts.existence_of_tex_point) && (stride_tex == 0))
+ stride_tex = sizeof(float) * 2;
for (j = 0; j < counts._triangles_counter; j++)
{
@@ -350,30 +405,43 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
float *p, *n, *t;
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
- n = (float *)((char *)nor + stride_nor * (j * 3 + k));
- t = (float *)((char *)tex + stride_tex * (j * 3 + k));
+ if (counts.existence_of_normal)
+ n = (float *)((char *)nor + stride_nor * (j * 3 + k));
+ if (counts.existence_of_tex_point)
+ t = (float *)((char *)tex + stride_tex * (j * 3 + k));
p[0] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 0, 3);
p[1] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 1, 3);
p[2] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 2, 3);
- n[0] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 0, 3);
- n[1] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 1, 3);
- n[2] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 2, 3);
+ if (counts.existence_of_normal)
+ {
+ n[0] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 0, 3);
+ n[1] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 1, 3);
+ n[2] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 2, 3);
+ }
- t[0] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 0, 3);
- t[1] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 1, 3);
+ if (counts.existence_of_tex_point)
+ {
+ t[0] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 0, 3);
+ t[1] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 1, 3);
+ }
}
}
+
free(_vertices_obj);
- free(_normales_obj);
- free(_tex_coords_obj);
+ if (counts.existence_of_normal)
+ free(_normales_obj);
+ if (counts.existence_of_tex_point)
+ free(_tex_coords_obj);
free(_triangles);
+
/* Unmap vertex buffer. */
- eo_do(mesh,
- evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
- evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
- evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
+ eo_do(mesh, evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION));
+ if (counts.existence_of_normal)
+ eo_do(mesh, evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL));
+ if (counts.existence_of_tex_point)
+ eo_do(mesh, evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
@@ -388,4 +456,3 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, Eina_File *file)
map = NULL;
}
}
-
diff --git a/src/modules/evas/model_savers/obj/evas_model_save_obj.c b/src/modules/evas/model_savers/obj/evas_model_save_obj.c
index 1cc7e8a744..00f8a76cc4 100644
--- a/src/modules/evas/model_savers/obj/evas_model_save_obj.c
+++ b/src/modules/evas/model_savers/obj/evas_model_save_obj.c
@@ -9,25 +9,54 @@
#include "evas_private.h"
#define OPEN_FILE(extension)\
- FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");\
-
-#define SAVE_GEOMETRICS(a, format)\
- vb = &f->vertices[a];\
- fprintf(_obj_file, "o %s\n",_obj_file_name);\
- if (vb->data == NULL)\
- {\
- ERR("Reading of geometrics is failed.");\
- fclose(_obj_file);\
- return;\
- }\
- src = (float *)vb->data;\
- for (i = 0; i < pd->vertex_count; i++)\
- {\
- fprintf(_obj_file, format, src[0], src[1], src[2]);\
- src += f->vertices[a].element_count;\
+ FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");
+
+#define SAVE_GEOMETRICS(a, format) \
+ vb = &f->vertices[a]; \
+ if (vb->data != NULL) \
+ { \
+ fprintf(_obj_file, "o %s\n",_obj_file_name); \
+ src = (float *)vb->data; \
+ for (i = 0; i < pd->vertex_count; i++) \
+ { \
+ fprintf(_obj_file, format, src[0], src[1]); \
+ if (a != EVAS_3D_VERTEX_TEXCOORD) \
+ fprintf(_obj_file, " %.4f", src[2]); \
+ fprintf(_obj_file, "\n"); \
+ src += f->vertices[a].element_count; \
+ } \
}
static void
+_write_point(FILE * obj_file,
+ int num,
+ int num_of_point,
+ Eina_Bool existence_of_normal,
+ Eina_Bool existence_of_tex_point)
+{
+ if (num_of_point == 1)
+ fprintf(obj_file, "f ");
+
+ if (existence_of_normal)
+ {
+ if (existence_of_tex_point)
+ fprintf(obj_file, "%i/%i/%i ", num, num, num);
+ else
+ fprintf(obj_file, "%i//%i ", num, num);
+ }
+ else
+ {
+ if (existence_of_tex_point)
+ fprintf(obj_file, "%i/%i ", num, num);
+ else
+ fprintf(obj_file, "%i ", num);
+ }
+
+ if (num_of_point == 3)
+ fprintf(obj_file, "\n");
+}
+
+static void
_save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Vertex_Buffer *vb;
@@ -35,6 +64,7 @@ _save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame
char* c_time_string;
int i;
float *src;
+ Eina_Bool existence_of_normal, existence_of_tex_point;
OPEN_FILE(obj)
if (!_obj_file)
@@ -73,26 +103,30 @@ _save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame
return;
}
- SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f %.4f \n")
- SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f %.4f \n")
- SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f %.4f \n")
+ SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f")
+ SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f")
+ SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f")
+
+ existence_of_normal = (f->vertices[EVAS_3D_VERTEX_NORMAL].data != NULL);
+ existence_of_tex_point = (f->vertices[EVAS_3D_VERTEX_TEXCOORD].data != NULL);
+
fprintf(_obj_file,"usemtl Material\n s off\n");
for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1
{
- fprintf(_obj_file,"f %i/%i/%i ", i, i, i);
+ _write_point(_obj_file, i, 1, existence_of_normal, existence_of_tex_point);
i++;
- fprintf(_obj_file,"%i/%i/%i ", i, i, i);
+ _write_point(_obj_file, i, 2, existence_of_normal, existence_of_tex_point);
i++;
- fprintf(_obj_file,"%i/%i/%i \n", i, i, i);
+ _write_point(_obj_file, i, 3, existence_of_normal, existence_of_tex_point);
}
fclose(_obj_file);
}
static void
-_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED, const char *_mtl_file_name, Evas_3D_Mesh_Frame *f)
+_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED,
+ const char *_mtl_file_name,
+ Evas_3D_Material_Data *mat)
{
- Evas_3D_Material_Data *mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
-
OPEN_FILE(mtl)
if (!_mtl_file)
{
@@ -126,21 +160,24 @@ void
evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
{
int len;
- char *without_extention, *_mtl_extension, *_mtl_file_name;
+ char *_mtl_file_name, *_without_extention;
+ Evas_3D_Material_Data *mat;
len = strlen(_obj_file_name);
- without_extention = (char*)malloc((len - 4) * sizeof(char));
- _mtl_extension = ".mtl";
- _mtl_file_name = (char *)malloc(len * sizeof(char));
-
- memcpy(without_extention, _obj_file_name, len-4);
- strcpy(_mtl_file_name, without_extention);
- strcpy(_mtl_file_name + len - 4, _mtl_extension);
+ _without_extention = (char *)malloc(len - 3);
+ _mtl_file_name = (char *)malloc(len + 1);
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
_save_mesh(pd, _obj_file_name, f);
- _save_material(pd, _mtl_file_name, f);
- free(without_extention);
+ mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
+ if (mat != NULL)
+ {
+ eina_strlcpy(_without_extention, _obj_file_name, len - 3);
+ eina_str_join(_mtl_file_name, len + 1, '.', _without_extention, "mtl");
+ _save_material(pd, _mtl_file_name, mat);
+ }
+
+ free(_without_extention);
free(_mtl_file_name);
}