From 9ebb28e3d6690f8548309fd97d2037c9e4ef2c07 Mon Sep 17 00:00:00 2001 From: Bogdan Devichev Date: Mon, 1 Sep 2014 22:43:16 +0900 Subject: [PATCH] evas: Evas_3D - add .eet export/import 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 | 4 +- src/examples/evas/evas-3d-eet.c | 226 ++++++++++++++++++ src/lib/evas/Evas_Eo.h | 1 + src/lib/evas/canvas/evas_3d_mesh.c | 16 ++ src/lib/evas/canvas/evas_3d_mesh.eo | 6 +- src/lib/evas/canvas/evas_3d_mesh_loader_eet.c | 124 ++++++++++ src/lib/evas/canvas/evas_3d_mesh_saver_eet.c | 157 ++++++++++++ src/lib/evas/include/evas_3d_eet.h | 190 +++++++++++++++ 8 files changed, 720 insertions(+), 4 deletions(-) create mode 100644 src/examples/evas/evas-3d-eet.c create mode 100644 src/lib/evas/canvas/evas_3d_mesh_loader_eet.c create mode 100644 src/lib/evas/canvas/evas_3d_mesh_saver_eet.c create mode 100644 src/lib/evas/include/evas_3d_eet.h diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 4f0ec0c915..8fb3f7cb16 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -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 index 0000000000..eefa1f9199 --- /dev/null +++ b/src/examples/evas/evas-3d-eet.c @@ -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 +#include +#include +#include + +#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; +} diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index a807e0a963..078a6fc990 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -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" diff --git a/src/lib/evas/canvas/evas_3d_mesh.c b/src/lib/evas/canvas/evas_3d_mesh.c index bc19481ccb..d1a1c6ef10 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.c +++ b/src/lib/evas/canvas/evas_3d_mesh.c @@ -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; diff --git a/src/lib/evas/canvas/evas_3d_mesh.eo b/src/lib/evas/canvas/evas_3d_mesh.eo index a8a199d19f..1fa70c4a11 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.eo +++ b/src/lib/evas/canvas/evas_3d_mesh.eo @@ -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 index 0000000000..1aee8f2e2e --- /dev/null +++ b/src/lib/evas/canvas/evas_3d_mesh_loader_eet.c @@ -0,0 +1,124 @@ +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#define EFL_EO_API_SUPPORT +#define EFL_BETA_API_SUPPORT + +#include +#include +#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 index 0000000000..33a06d7897 --- /dev/null +++ b/src/lib/evas/canvas/evas_3d_mesh_saver_eet.c @@ -0,0 +1,157 @@ +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#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 index 0000000000..7bf8b9e047 --- /dev/null +++ b/src/lib/evas/include/evas_3d_eet.h @@ -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(); +} +