evas: Evas_3D - add .eet export/import
authorBogdan Devichev <b.devichev@samsung.com>
Mon, 1 Sep 2014 13:43:16 +0000 (22:43 +0900)
committerChunEon Park <hermet@hermet.pe.kr>
Mon, 1 Sep 2014 13:43:16 +0000 (22:43 +0900)
Summary: The first version of .eet format is added.

Reviewers: Hermet, raster, cedric

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D1307

src/Makefile_Evas.am
src/examples/evas/evas-3d-eet.c [new file with mode: 0644]
src/lib/evas/Evas_Eo.h
src/lib/evas/canvas/evas_3d_mesh.c
src/lib/evas/canvas/evas_3d_mesh.eo
src/lib/evas/canvas/evas_3d_mesh_loader_eet.c [new file with mode: 0644]
src/lib/evas/canvas/evas_3d_mesh_saver_eet.c [new file with mode: 0644]
src/lib/evas/include/evas_3d_eet.h [new file with mode: 0644]

index 4f0ec0c915b8f75d4ffca755338953f83627443b..8fb3f7cb160089f0a26c1e33085c247b06a5b151 100644 (file)
@@ -299,7 +299,9 @@ lib/evas/canvas/evas_3d_texture.c \
 lib/evas/canvas/evas_3d_material.c \
 lib/evas/canvas/evas_3d_mesh_loader_md2.c \
 lib/evas/canvas/evas_3d_mesh_loader_obj.c \
-lib/evas/canvas/evas_3d_mesh_saver_obj.c
+lib/evas/canvas/evas_3d_mesh_saver_obj.c \
+lib/evas/canvas/evas_3d_mesh_loader_eet.c \
+lib/evas/canvas/evas_3d_mesh_saver_eet.c
 
 # Engine
 lib_evas_libevas_la_SOURCES += \
diff --git a/src/examples/evas/evas-3d-eet.c b/src/examples/evas/evas-3d-eet.c
new file mode 100644 (file)
index 0000000..eefa1f9
--- /dev/null
@@ -0,0 +1,226 @@
+/**
+* Simple Evas example illustrating .eet import/export
+*
+* Take mesh from md2.
+* Set material to it.
+* Show it in left side.
+* Save the first frame of this mesh to eet. (static only)
+* Take result to another mesh from eet.
+* Show it in right side.
+*
+* @verbatim
+* gcc -o evas-3d-eet evas-3d-eet.c `pkg-config --libs --cflags evas ecore ecore-evas eo`
+* @endverbatim
+*/
+
+#define EFL_EO_API_SUPPORT
+#define EFL_BETA_API_SUPPORT
+
+#include <Eo.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+
+#define  WIDTH 1024
+#define  HEIGHT 1024
+
+Ecore_Evas *ecore_evas = NULL;
+Evas *evas = NULL;
+Eo *background = NULL;
+Eo *image = NULL;
+
+Eo *scene = NULL;
+Eo *root_node = NULL;
+Eo *camera_node = NULL;
+Eo *light_node = NULL;
+Eo *camera = NULL;
+Eo *mesh_node = NULL;
+Eo *mesh = NULL;
+Eo *mesh_node2 = NULL;
+Eo *mesh2 = NULL;
+Eo *material = NULL;
+Eo *light = NULL;
+
+static float angle = 0;
+
+static Eina_Bool
+_animate_eet(void *data)
+{
+   angle += 0.5;
+
+   eo_do((Evas_3D_Node *)data, evas_3d_node_orientation_angle_axis_set(angle, 1.0, 1.0, 1.0));
+
+   /* Rotate */
+   if (angle > 360.0) angle -= 360.0f;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_animate_md2(void *data)
+{
+   static int frame = 0;
+
+   eo_do((Evas_3D_Node *)data, evas_3d_node_mesh_frame_set(mesh, frame));
+
+   frame += 32;
+
+   if (frame > 256 * 50) frame = 0;
+
+   return EINA_TRUE;
+}
+
+static void
+_on_delete(Ecore_Evas *ee EINA_UNUSED)
+{
+   ecore_main_loop_quit();
+}
+
+static void
+_on_canvas_resize(Ecore_Evas *ee)
+{
+   int w, h;
+
+   ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+   eo_do(background, evas_obj_size_set(w, h));
+   eo_do(image, evas_obj_size_set(w, h));
+}
+
+int
+main(void)
+{
+   //Unless Evas 3D supports Software renderer, we set gl backened forcely.
+   setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1);
+
+   if (!ecore_evas_init()) return 0;
+
+   ecore_evas = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
+
+   if (!ecore_evas) return 0;
+
+   ecore_evas_callback_delete_request_set(ecore_evas, _on_delete);
+   ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize);
+   ecore_evas_show(ecore_evas);
+
+   evas = ecore_evas_get(ecore_evas);
+
+   /* Add a scene object .*/
+   scene = eo_add(EVAS_3D_SCENE_CLASS, evas);
+
+   /* Add the root node for the scene. */
+   root_node = eo_add_custom(EVAS_3D_NODE_CLASS, evas,
+                             evas_3d_node_constructor(EVAS_3D_NODE_TYPE_NODE));
+
+   /* Add the camera. */
+   camera = eo_add(EVAS_3D_CAMERA_CLASS, evas);
+   eo_do(camera,
+         evas_3d_camera_projection_perspective_set(60.0, 1.0, 1.0, 500.0));
+
+   camera_node =
+      eo_add_custom(EVAS_3D_NODE_CLASS, evas,
+                    evas_3d_node_constructor(EVAS_3D_NODE_TYPE_CAMERA));
+   eo_do(camera_node,
+         evas_3d_node_camera_set(camera));
+   eo_do(root_node,
+         evas_3d_node_member_add(camera_node));
+   eo_do(camera_node,
+         evas_3d_node_position_set(200.0, 0.0, 40.0),
+         evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 20.0,
+                                  EVAS_3D_SPACE_PARENT, 0.0, 0.0, 1.0));
+   /* Add the light. */
+   light = eo_add(EVAS_3D_LIGHT_CLASS, evas);
+   eo_do(light,
+         evas_3d_light_ambient_set(1.0, 1.0, 1.0, 1.0),
+         evas_3d_light_diffuse_set(1.0, 1.0, 1.0, 1.0),
+         evas_3d_light_specular_set(1.0, 1.0, 1.0, 1.0),
+         evas_3d_light_directional_set(EINA_TRUE));
+
+   light_node =
+      eo_add_custom(EVAS_3D_NODE_CLASS, evas,
+                    evas_3d_node_constructor(EVAS_3D_NODE_TYPE_LIGHT));
+   eo_do(light_node,
+         evas_3d_node_light_set(light),
+         evas_3d_node_position_set(1000.0, 0.0, 1000.0),
+         evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0,
+                                  EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0));
+   eo_do(root_node,
+         evas_3d_node_member_add(light_node));
+
+   /* Add the meshes. */
+   mesh = eo_add(EVAS_3D_MESH_CLASS, evas);
+   mesh2 = eo_add(EVAS_3D_MESH_CLASS, evas);
+   material = eo_add(EVAS_3D_MATERIAL_CLASS, evas);
+
+   eo_do(mesh,
+         evas_3d_mesh_file_set(EVAS_3D_MESH_FILE_TYPE_MD2, "sonic.md2", NULL),
+         evas_3d_mesh_frame_material_set(0, material),
+         evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG));
+
+   eo_do(material,
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT,
+                                    0.50, 0.50, 0.00, 0.30),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE,
+                                    0.00, 0.50, 0.50, 0.30),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
+                                    0.50, 0.00, 0.50, 0.30),
+         evas_3d_material_shininess_set(50.0));
+
+   eo_do(mesh, evas_3d_mesh_save(EVAS_3D_MESH_FILE_TYPE_EET, "saved_Sonic_EET.eet", NULL));
+   eo_do(mesh2,
+         evas_3d_mesh_file_set(EVAS_3D_MESH_FILE_TYPE_EET, "saved_Sonic_EET.eet", NULL),
+         evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG));
+
+   mesh_node = eo_add_custom(EVAS_3D_NODE_CLASS, evas,
+                             evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
+   eo_do(root_node,
+         evas_3d_node_member_add(mesh_node));
+   eo_do(mesh_node,
+         evas_3d_node_mesh_add(mesh),
+         evas_3d_node_position_set(0.0, -40.0, 0.0));
+
+   mesh_node2 = eo_add_custom(EVAS_3D_NODE_CLASS, evas,
+                             evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
+   eo_do(root_node,
+         evas_3d_node_member_add(mesh_node2));
+   eo_do(mesh_node2,
+         evas_3d_node_mesh_add(mesh2),
+         evas_3d_node_position_set(0.0, 40.0, 0.0));
+
+   /* Set up scene. */
+   eo_do(scene,
+         evas_3d_scene_root_node_set(root_node),
+         evas_3d_scene_camera_node_set(camera_node),
+         evas_3d_scene_size_set(WIDTH, HEIGHT));
+
+   /* Add a background rectangle objects. */
+   background = eo_add(EVAS_RECTANGLE_CLASS, evas);
+   eo_unref(background);
+   eo_do(background,
+         evas_obj_color_set(0, 0, 0, 255),
+         evas_obj_size_set(WIDTH, HEIGHT),
+         evas_obj_visibility_set(EINA_TRUE));
+
+   /* Add an image object for 3D scene rendering. */
+   image = evas_object_image_filled_add(evas);
+   eo_do(image,
+         evas_obj_size_set(WIDTH, HEIGHT),
+         evas_obj_visibility_set(EINA_TRUE));
+
+   /* Set the image object as render target for 3D scene. */
+   eo_do(image, evas_obj_image_scene_set(scene));
+
+   ecore_timer_add(0.01, _animate_md2, mesh_node);
+   ecore_timer_add(0.01, _animate_eet, mesh_node2);
+
+   /* Enter main loop. */
+   ecore_main_loop_begin();
+
+   ecore_evas_free(ecore_evas);
+   ecore_evas_shutdown();
+
+   return 0;
+}
index a807e0a96383b04e2c56ef0c14583d1c8e18e963..078a6fc990014072a131c86ed42718f79f5c8964 100644 (file)
@@ -707,6 +707,7 @@ typedef enum _Evas_3D_Mesh_File_Type
 {
    EVAS_3D_MESH_FILE_TYPE_MD2 = 0,   /**< Quake's MD2 mesh file format */
    EVAS_3D_MESH_FILE_TYPE_OBJ,
+   EVAS_3D_MESH_FILE_TYPE_EET,
 } Evas_3D_Mesh_File_Type;
 
 #include "canvas/evas_image.eo.h"
index bc19481ccb1d077f018b8d1d2c81ef562207af89..d1a1c6ef1099a0897143aaa716b30589dbad1906 100644 (file)
@@ -788,6 +788,9 @@ _evas_3d_mesh_file_set(Eo *obj, Evas_3D_Mesh_Data *pd, Evas_3D_Mesh_File_Type ty
       case EVAS_3D_MESH_FILE_TYPE_OBJ:
         evas_3d_mesh_file_obj_set(obj, file);
         break;
+      case EVAS_3D_MESH_FILE_TYPE_EET:
+        evas_3d_mesh_file_eet_set(obj, file);
+        break;
       default:
         ERR("Invalid mesh file type.");
         break;
@@ -815,6 +818,19 @@ _evas_3d_mesh_save(Eo *obj, Evas_3D_Mesh_Data *pd, Evas_3D_Mesh_File_Type type,
            evas_3d_mesh_save_obj(obj, file, f);//file without extension!
            break;
         }
+      case EVAS_3D_MESH_FILE_TYPE_EET:
+        {
+           Evas_3D_Mesh_Frame *f = evas_3d_mesh_frame_find(pd, 0);
+
+           if (f == NULL)
+             {
+                ERR("Not existing mesh frame.");
+                return;
+             }
+
+           evas_3d_mesh_save_eet(obj, file, f);
+           break;
+        }
       default:
         ERR("Invalid mesh file type.");
         break;
index a8a199d19fa9192f818e4c79b535e9806ffa8144..1fa70c4a119d937cc8cb9c28db022d7fe78e2876 100644 (file)
@@ -8,7 +8,7 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface)
          /**
           * Load mesh data from file.
           *
-          * Loading a mesh from existing file is supported. Currently, only MD2 and OBJ file
+          * Loading a mesh from existing file is supported. Currently, only MD2, OBJ and EET file
           * formats are supported.
           *
           * @ingroup Evas_3D_Mesh
@@ -24,8 +24,8 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface)
          /**
           * Save mesh data to file.
           *
-          * Saving a mesh to file is supported. Currently, only OBJ file
-          * format is supported.
+          * Saving a mesh to file is supported. Currently, only OBJ and EET file
+          * formats are supported.
           *
           * @ingroup Evas_3D_Mesh
           */
diff --git a/src/lib/evas/canvas/evas_3d_mesh_loader_eet.c b/src/lib/evas/canvas/evas_3d_mesh_loader_eet.c
new file mode 100644 (file)
index 0000000..1aee8f2
--- /dev/null
@@ -0,0 +1,124 @@
+#ifdef HAVE_CONFIG_H
+   #include "config.h"
+#endif
+
+#define EFL_EO_API_SUPPORT
+#define EFL_BETA_API_SUPPORT
+
+#include <Eo.h>
+#include <stdio.h>
+#include "evas_common_private.h"
+#include "evas_private.h"
+#include "evas_3d_eet.h"
+
+void
+_set_geometry_to_mesh_from_eet_file(Evas_3D_Mesh *mesh, Evas_3D_Mesh_Eet *eet_mesh)
+{
+   float *pos, *nor, *tex;
+   int stride_pos, stride_nor, stride_tex, j;
+
+   eo_do(mesh,
+         evas_3d_mesh_vertex_count_set(eet_mesh->geometries->vertices_count),
+         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_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 (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;
+
+   for (j = 0; j < eet_mesh->geometries->vertices_count; j++)
+     {
+        float *p, *n, *t;
+
+        p = (float *)((char *)pos + stride_pos * j);
+        n = (float *)((char *)nor + stride_nor * j);
+        t = (float *)((char *)tex + stride_tex * j);
+
+        p[0] = eet_mesh->geometries->vertices[j].position.x;
+        p[1] = eet_mesh->geometries->vertices[j].position.y;
+        p[2] = eet_mesh->geometries->vertices[j].position.z;
+
+        n[0] = eet_mesh->geometries->vertices[j].normal.x;
+        n[1] = eet_mesh->geometries->vertices[j].normal.y;
+        n[2] = eet_mesh->geometries->vertices[j].normal.z;
+
+        t[0] = eet_mesh->geometries->vertices[j].texcoord.x;
+        t[1] = eet_mesh->geometries->vertices[j].texcoord.y;
+     }
+
+        /* 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));
+}
+
+void
+_set_material_to_mesh_from_eet_file(Evas_3D_Mesh *mesh, Evas_3D_Mesh_Eet *eet_mesh)
+{
+   int j;
+   Evas_3D_Object_Data *pd = eo_data_scope_get(mesh, EVAS_3D_OBJECT_CLASS);
+   Eo *material = NULL;
+   material = eo_add(EVAS_3D_MATERIAL_CLASS, pd->evas);
+
+   eo_do(material,
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, !!(eet_mesh->materials->colors[0].a > 0)),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, !!(eet_mesh->materials->colors[1].a > 0)),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, !!(eet_mesh->materials->colors[2].a > 0)),
+         evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT,
+                                    eet_mesh->materials->colors[0].r,
+                                    eet_mesh->materials->colors[0].g,
+                                    eet_mesh->materials->colors[0].b,
+                                    eet_mesh->materials->colors[0].a),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE,
+                                    eet_mesh->materials->colors[1].r,
+                                    eet_mesh->materials->colors[1].g,
+                                    eet_mesh->materials->colors[1].b,
+                                    eet_mesh->materials->colors[1].a),
+         evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
+                                    eet_mesh->materials->colors[2].r,
+                                    eet_mesh->materials->colors[2].g,
+                                    eet_mesh->materials->colors[2].b,
+                                    eet_mesh->materials->colors[2].a),
+         evas_3d_material_shininess_set(eet_mesh->materials->shininess));
+
+   eo_do(mesh, evas_3d_mesh_frame_material_set(0, material));
+}
+
+void
+evas_3d_mesh_file_eet_set(Evas_3D_Mesh *mesh, const char *file)
+{
+   Eet_File *ef;
+   Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
+
+   _mesh_init();
+
+   ef = eet_open(file, EET_FILE_MODE_READ);
+   eet_mesh = eet_data_read(ef, _mesh_descriptor, EVAS_3D_MESH_CACHE_FILE_ENTRY);
+   eet_close(ef);
+
+   if (eet_mesh == NULL || eet_mesh->geometries == NULL)
+     {
+        ERR("Reading of file is failed.");
+        _mesh_free();
+        return;
+     }
+
+   _set_geometry_to_mesh_from_eet_file(mesh, eet_mesh);
+   _set_material_to_mesh_from_eet_file(mesh, eet_mesh);
+   _mesh_free();
+}
+
diff --git a/src/lib/evas/canvas/evas_3d_mesh_saver_eet.c b/src/lib/evas/canvas/evas_3d_mesh_saver_eet.c
new file mode 100644 (file)
index 0000000..33a06d7
--- /dev/null
@@ -0,0 +1,157 @@
+#ifdef HAVE_CONFIG_H
+   #include "config.h"
+#endif
+
+#include <stdio.h>
+#include "evas_common_private.h"
+#include "evas_private.h"
+#include "evas_3d_eet.h"
+
+#define COMPONENT_OF_DEFAULT_GREY_COLOR 0.3
+#define TRANSPARENCY_OF_DEFAULT_GREY_COLOR 0.5
+
+void
+_set_geometry_to_eet_file_from_mesh(Evas_3D_Mesh_Data *mesh, Evas_3D_Mesh_Eet *eet_mesh, Evas_3D_Mesh_Frame *f)
+{
+   Evas_3D_Vertex_Buffer *vb;
+   int i;
+   float *src;
+   Evas_3D_Vertex_Eet *vertices = malloc(sizeof(Evas_3D_Vertex_Eet) * mesh->vertex_count);
+   Evas_3D_Geometry_Eet *geometry = malloc(sizeof(Evas_3D_Geometry_Eet));
+
+   if ((vertices == NULL) || (geometry == NULL))
+     {
+        ERR("Allocating of memory is failed.");
+        free(vertices);
+        free(geometry);
+        return;
+     }
+
+   geometry->name = "geometry";
+   geometry->vertices_count = mesh->vertex_count;
+
+#define SAVE_GEOMETRICS(a, component)\
+   vb = &f->vertices[a];\
+   if (vb->data == NULL)\
+     {\
+        ERR("Reading of geometrics is failed.");\
+        eina_stringshare_del(geometry->name);\
+        free(vertices);\
+        free(geometry);\
+        return;\
+     }\
+   src = (float *)vb->data;\
+   for (i = 0; i < mesh->vertex_count; i++)\
+     {\
+        vertices[i].component.x = src[0];\
+        vertices[i].component.y = src[1];\
+        vertices[i].component.z = src[2];\
+        src += f->vertices[a].element_count;\
+     }
+
+   geometry->vertices = vertices;
+   SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, position)
+   SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, normal)
+   SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, texcoord)
+
+#undef SAVE_GEOMETRICS
+
+   eet_mesh->geometries = geometry;
+}
+
+void
+_set_material_to_eet_file_from_mesh(Evas_3D_Mesh_Data *mesh, Evas_3D_Mesh_Eet *eet_mesh, Evas_3D_Mesh_Frame *f)
+{
+   int i;
+   Evas_3D_Material_Data *material = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
+   Evas_3D_Material_Eet *saved_materials = malloc(sizeof(Evas_3D_Material_Eet));
+   Evas_3D_Color_Eet *saved_colors = malloc(sizeof(Evas_3D_Color_Eet) * EVAS_3D_MATERIAL_ATTRIB_COUNT);
+
+   if ((saved_materials == NULL) || (saved_colors == NULL))
+     {
+        ERR("Allocating of memory is failed.");
+        free(material);
+        free(saved_materials);
+        free(saved_colors);
+        return;
+     }
+
+   if (material == NULL)
+     {
+        ERR("Default material is set to saved file, because custom material was not saved before using of function evas_3d_mesh_save.");
+
+        for (i = 0; i < 5; i++)
+          {
+             saved_colors[i].r = COMPONENT_OF_DEFAULT_GREY_COLOR;
+             saved_colors[i].g = COMPONENT_OF_DEFAULT_GREY_COLOR;
+             saved_colors[i].b = COMPONENT_OF_DEFAULT_GREY_COLOR;
+             saved_colors[i].a = TRANSPARENCY_OF_DEFAULT_GREY_COLOR;
+          }
+
+        saved_materials->shininess = 50;
+     }
+   else
+     {
+
+        for (i = 0; i < 5; i++)
+          {
+             saved_colors[i].r = material->attribs[i].color.r;
+             saved_colors[i].g = material->attribs[i].color.g;
+             saved_colors[i].b = material->attribs[i].color.b;
+             saved_colors[i].a = material->attribs[i].color.a;
+          }
+
+        saved_materials->shininess = material->shininess;
+     }
+
+   saved_materials->colors_count = EVAS_3D_MATERIAL_ATTRIB_COUNT;
+   saved_materials->id = 1;
+   saved_materials->colors = saved_colors;
+   eet_mesh->materials = saved_materials;
+}
+
+void
+_set_frame_to_eet_file_from_mesh(Evas_3D_Mesh_Eet *eet_mesh)
+{
+   eet_mesh->frames = malloc(sizeof(Evas_3D_Frame_Eet));
+
+   if (eet_mesh->frames == NULL)
+     {
+        ERR("Allocating of memory is failed.");
+        return;
+     }
+
+   eet_mesh->frames->id = 1;
+   eet_mesh->frames->geometry_id = 1;
+   eet_mesh->frames->material_id = 1;
+}
+
+void
+evas_3d_mesh_save_eet(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
+{
+   Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
+   Eet_File *ef = eet_open(file, EET_FILE_MODE_WRITE);
+
+   _mesh_init();
+   eet_mesh = _mesh_new();
+   _set_geometry_to_eet_file_from_mesh(pd, eet_mesh, f);
+   _set_material_to_eet_file_from_mesh(pd, eet_mesh, f);
+   _set_frame_to_eet_file_from_mesh(eet_mesh);
+
+   if (ef == NULL)
+     {
+        ERR("Opening of file is failed.");
+        _mesh_free();
+        return;
+     }
+
+   eet_mesh->materials_count = 1;
+   eet_mesh->frames_count = 1;
+   eet_mesh->geometries_count = 1;
+
+   eet_data_write
+       (ef, _mesh_descriptor, EVAS_3D_MESH_CACHE_FILE_ENTRY, eet_mesh, EINA_TRUE);
+   eet_close(ef);
+   _mesh_free();
+}
+
diff --git a/src/lib/evas/include/evas_3d_eet.h b/src/lib/evas/include/evas_3d_eet.h
new file mode 100644 (file)
index 0000000..7bf8b9e
--- /dev/null
@@ -0,0 +1,190 @@
+typedef struct _Evas_3D_Vec3_Eet
+{
+   float x;
+   float y;
+   float z;
+} Evas_3D_Vec3_Eet;
+
+typedef struct _Evas_3D_Vertex_Eet
+{
+   Evas_3D_Vec3_Eet position;
+   Evas_3D_Vec3_Eet normal;
+   Evas_3D_Vec3_Eet texcoord;
+} Evas_3D_Vertex_Eet;
+
+typedef struct _Evas_3D_Geometry_Eet
+{
+   unsigned int id;
+   const char *name;
+   int vertices_count;
+   Evas_3D_Vertex_Eet *vertices;
+} Evas_3D_Geometry_Eet;
+
+typedef struct _Evas_3D_Color_Eet
+{
+   float r;
+   float g;
+   float b;
+   float a;
+} Evas_3D_Color_Eet;
+
+typedef struct _Evas_3D_Material_Eet
+{
+   int id;
+   float shininess;
+   int colors_count;
+   Evas_3D_Color_Eet *colors;//Color per attribute
+} Evas_3D_Material_Eet;
+
+typedef struct _Evas_3D_Frame_Eet
+{
+   int id;
+   int geometry_id;
+   int material_id;
+} Evas_3D_Frame_Eet;//only ids to prevent of spending of memory
+
+typedef struct _Evas_3D_Mesh_Eet
+{
+   int materials_count;
+   int frames_count;
+   int geometries_count;
+   Evas_3D_Material_Eet *materials;
+   Evas_3D_Frame_Eet *frames;
+   Evas_3D_Geometry_Eet *geometries;
+} Evas_3D_Mesh_Eet;
+
+static Evas_3D_Mesh_Eet* eet_mesh;
+static const char EVAS_3D_MESH_CACHE_FILE_ENTRY[] = "evas_3d mesh";
+static Eet_Data_Descriptor *_vec3_descriptor;
+static Eet_Data_Descriptor *_vertex_descriptor;
+static Eet_Data_Descriptor *_geometry_descriptor;
+static Eet_Data_Descriptor *_color_descriptor;
+static Eet_Data_Descriptor *_material_descriptor;
+static Eet_Data_Descriptor *_frame_descriptor;
+static Eet_Data_Descriptor *_mesh_descriptor;
+
+static inline struct Evas_3D_Geometry_Eet *
+_mesh_new(void)
+{
+   const struct Evas_3D_Mesh_Eet *creating_mesh = calloc(1, sizeof(Evas_3D_Geometry_Eet));
+
+   if (!creating_mesh)
+     {
+        ERR("Could not calloc Evas_3D_Geometry_Eet");
+        return NULL;
+     }
+
+   return creating_mesh;
+}
+
+static inline void
+_mesh_init(void)
+{
+   eina_init();
+   eet_init();
+
+   Eet_Data_Descriptor_Class eddc;
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Vec3_Eet);
+   _vec3_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Vertex_Eet);
+   _vertex_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Geometry_Eet);
+   _geometry_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Color_Eet);
+   _color_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Frame_Eet);
+   _frame_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Material_Eet);
+   _material_descriptor = eet_data_descriptor_file_new(&eddc);
+   EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Evas_3D_Mesh_Eet);
+   _mesh_descriptor = eet_data_descriptor_file_new(&eddc);
+
+/* Vec_3 */
+#define ADD_BASIC(member, eet_type) EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_vec3_descriptor, Evas_3D_Vec3_Eet, # member, member, eet_type);
+   ADD_BASIC(x, EET_T_FLOAT);
+   ADD_BASIC(y, EET_T_FLOAT);
+   ADD_BASIC(z, EET_T_FLOAT);
+#undef ADD_BASIC
+
+/* Vertex */
+   EET_DATA_DESCRIPTOR_ADD_SUB_NESTED(_vertex_descriptor, Evas_3D_Vertex_Eet, "position", position, _vec3_descriptor);
+   EET_DATA_DESCRIPTOR_ADD_SUB_NESTED(_vertex_descriptor, Evas_3D_Vertex_Eet, "normal", normal, _vec3_descriptor);
+   EET_DATA_DESCRIPTOR_ADD_SUB_NESTED(_vertex_descriptor, Evas_3D_Vertex_Eet, "texcoord", texcoord, _vec3_descriptor);
+
+/* Geometry */
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY (_geometry_descriptor, Evas_3D_Geometry_Eet, "vertices", vertices, _vertex_descriptor);
+#define ADD_BASIC(member, eet_type) \
+   EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_geometry_descriptor, Evas_3D_Geometry_Eet, # member, member, eet_type);
+   ADD_BASIC(vertices_count, EET_T_INT);
+   ADD_BASIC(id, EET_T_UINT);
+   ADD_BASIC(name, EET_T_STRING);
+#undef ADD_BASIC
+
+/* Color */
+#define ADD_BASIC(member, eet_type) EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_color_descriptor, Evas_3D_Color_Eet, # member, member, eet_type);
+   ADD_BASIC(r, EET_T_FLOAT);
+   ADD_BASIC(g, EET_T_FLOAT);
+   ADD_BASIC(b, EET_T_FLOAT);
+   ADD_BASIC(a, EET_T_FLOAT);
+#undef ADD_BASIC
+
+/* Material */
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY (_material_descriptor, Evas_3D_Material_Eet, "colors", colors, _color_descriptor);
+#define ADD_BASIC(member, eet_type) \
+   EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_material_descriptor, Evas_3D_Material_Eet, # member, member, eet_type);
+   ADD_BASIC(id, EET_T_UINT);
+   ADD_BASIC(colors_count, EET_T_UINT);
+   ADD_BASIC(shininess, EET_T_FLOAT);
+#undef ADD_BASIC
+
+/* Frame */
+#define ADD_BASIC(member, eet_type) EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_frame_descriptor, Evas_3D_Frame_Eet, # member, member, eet_type);
+   ADD_BASIC(id, EET_T_UINT);
+   ADD_BASIC(geometry_id, EET_T_UINT);
+   ADD_BASIC(material_id, EET_T_UINT);
+#undef ADD_BASIC
+
+/* Mesh */
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY (_mesh_descriptor, Evas_3D_Mesh_Eet, "frames", frames, _frame_descriptor);
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY (_mesh_descriptor, Evas_3D_Mesh_Eet, "geometries", geometries, _geometry_descriptor);
+   EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY (_mesh_descriptor, Evas_3D_Mesh_Eet, "materials", materials, _material_descriptor);
+#define ADD_BASIC(member, eet_type) \
+   EET_DATA_DESCRIPTOR_ADD_BASIC \
+   (_mesh_descriptor, Evas_3D_Mesh_Eet, # member, member, eet_type);
+   ADD_BASIC(materials_count, EET_T_UINT);
+   ADD_BASIC(frames_count, EET_T_UINT);
+   ADD_BASIC(geometries_count, EET_T_UINT);
+#undef ADD_BASIC
+}
+
+static inline void
+_descriptor_shutdown(void)
+{
+   eet_data_descriptor_free (_geometry_descriptor);
+   eet_data_descriptor_free (_vertex_descriptor);
+   eet_data_descriptor_free (_vec3_descriptor);
+   eet_data_descriptor_free (_color_descriptor);
+   eet_data_descriptor_free (_material_descriptor);
+   eet_data_descriptor_free (_frame_descriptor);
+   eet_data_descriptor_free (_mesh_descriptor);
+}
+
+static inline void
+_mesh_free(void)
+{
+   free(eet_mesh->geometries[0].vertices);
+   free(eet_mesh->geometries);
+   free(eet_mesh->frames);
+   free(eet_mesh->materials[0].colors);
+   free(eet_mesh->materials);
+   free(eet_mesh);
+   _descriptor_shutdown();
+   eet_shutdown();
+   eina_shutdown();
+}
+