diff --git a/src/examples/evas/evas-3d-mmap-set.c b/src/examples/evas/evas-3d-mmap-set.c new file mode 100644 index 0000000000..b474e48cbd --- /dev/null +++ b/src/examples/evas/evas-3d-mmap-set.c @@ -0,0 +1,250 @@ +/** +* Simple Evas example illustrating import from mmap. +* +* Open files to Eina_Files. +* Read meshes from Eina_Files. +* Show the results. +* +* @verbatim +* gcc -o evas-3d-mmap-set evas-3d-mmap-set.c `pkg-config --libs --cflags evas ecore ecore-evas eina eo` +* @endverbatim +*/ +//TODO This example will be cool in nearest future + +#define EFL_EO_API_SUPPORT +#define EFL_BETA_API_SUPPORT + +#include +#include +#include +#include + +#define WIDTH 400 +#define HEIGHT 400 + +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_obj = NULL; +Eo *mesh_obj = NULL; +Eo *mesh_node_ply = NULL; +Eo *mesh_ply = NULL; +Eo *mesh_node_eet = NULL; +Eo *mesh_eet = NULL; +Eo *mesh_node_md2 = NULL; +Eo *mesh_md2 = NULL; +Eo *material = NULL; +Eo *light = NULL; + +static float angle = 0; + +static Eina_Bool +_animate_scene(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 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; + + Eina_File *obj_file; + Eina_File *ply_file; + Eina_File *eet_file; + Eina_File *md2_file; + + obj_file = eina_file_open("man_mesh.obj", 0); + ply_file = eina_file_open("ply_files/Normal_UVs_Colors.ply", 0); + eet_file = eina_file_open("sonic.eet", 0); + md2_file = eina_file_open("sonic.md2", 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(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(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(100.0, 0.0, 20.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(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)); + + material = eo_add(EVAS_3D_MATERIAL_CLASS, evas); + + /* Add the meshes. */ + mesh_obj = eo_add(EVAS_3D_MESH_CLASS, evas); + mesh_ply = eo_add(EVAS_3D_MESH_CLASS, evas); + mesh_eet = eo_add(EVAS_3D_MESH_CLASS, evas); + mesh_md2 = eo_add(EVAS_3D_MESH_CLASS, evas); + + eo_do(mesh_obj, + evas_3d_mesh_mmap_set(obj_file, NULL), + evas_3d_mesh_frame_material_set(0, material), + evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG)); + + eo_do(mesh_ply, + evas_3d_mesh_mmap_set(ply_file, NULL), + evas_3d_mesh_frame_material_set(0, material), + evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG)); + + eo_do(mesh_eet, + evas_3d_mesh_mmap_set(eet_file, NULL), + evas_3d_mesh_frame_material_set(0, material), + evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG)); + + eo_do(mesh_md2, + evas_3d_mesh_mmap_set(md2_file, 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.01, 0.01, 0.01, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE, + 1.0, 1.0, 1.0, 1.0), + evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR, + 1.0, 1.0, 1.0, 1.0), + evas_3d_material_shininess_set(50.0)); + + mesh_node_obj = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH)); + mesh_node_ply = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH)); + mesh_node_eet = eo_add(EVAS_3D_NODE_CLASS, evas, + evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH)); + mesh_node_md2 = eo_add(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_obj)); + eo_do(root_node, evas_3d_node_member_add(mesh_node_ply)); + eo_do(root_node, evas_3d_node_member_add(mesh_node_md2)); + eo_do(root_node, evas_3d_node_member_add(mesh_node_eet)); + + eo_do(mesh_node_obj, evas_3d_node_mesh_add(mesh_obj), + evas_3d_node_position_set(0, -30, 0)); + eo_do(mesh_node_ply, evas_3d_node_mesh_add(mesh_ply), + evas_3d_node_position_set(0, -10, 0)); + eo_do(mesh_node_eet, evas_3d_node_mesh_add(mesh_eet), + evas_3d_node_position_set(0, 10, 0)); + eo_do(mesh_node_md2, evas_3d_node_mesh_add(mesh_md2), + evas_3d_node_position_set(0, 30, 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_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_scene, mesh_node_obj); + ecore_timer_add(0.01, _animate_scene, mesh_node_ply); + ecore_timer_add(0.01, _animate_scene, mesh_node_eet); + ecore_timer_add(0.01, _animate_scene, mesh_node_md2); + + /* Enter main loop. */ + ecore_main_loop_begin(); + + ecore_evas_free(ecore_evas); + ecore_evas_shutdown(); + + eina_file_close(obj_file); + eina_file_close(ply_file); + eina_file_close(eet_file); + eina_file_close(md2_file); + + return 0; +} diff --git a/src/examples/evas/sonic.eet b/src/examples/evas/sonic.eet new file mode 100644 index 0000000000..e1fa9ef38c Binary files /dev/null and b/src/examples/evas/sonic.eet differ diff --git a/src/lib/evas/canvas/evas_3d_mesh.c b/src/lib/evas/canvas/evas_3d_mesh.c index 36c38c3a72..2328293625 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.c +++ b/src/lib/evas/canvas/evas_3d_mesh.c @@ -769,6 +769,18 @@ _evas_3d_mesh_fog_enable_get(Eo *obj EINA_UNUSED, Evas_3D_Mesh_Data *pd) return pd->fog_enabled; } +EOLIAN static void +_evas_3d_mesh_mmap_set(Eo *obj, Evas_3D_Mesh_Data *pd, + Eina_File *file, const char *key EINA_UNUSED) +{ + _mesh_fini(pd); + _mesh_init(pd); + + if (file == NULL) return; + + evas_common_load_model_from_eina_file(obj, file); +} + EOLIAN static void _evas_3d_mesh_file_set(Eo *obj, Evas_3D_Mesh_Data *pd, const char *file, const char *key EINA_UNUSED) @@ -778,7 +790,7 @@ _evas_3d_mesh_file_set(Eo *obj, Evas_3D_Mesh_Data *pd, if (file == NULL) return; - evas_common_load_model_to_file(obj, file); + evas_common_load_model_from_file(obj, file); } EOLIAN static void diff --git a/src/lib/evas/canvas/evas_3d_mesh.eo b/src/lib/evas/canvas/evas_3d_mesh.eo index f2b420aebb..0c79941b6a 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.eo +++ b/src/lib/evas/canvas/evas_3d_mesh.eo @@ -4,6 +4,21 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface) data: Evas_3D_Mesh_Data; methods { + mmap_set { + /** + * Load mesh data from Eina_File. + * + * Loading a mesh from existing Eina_File is supported. Currently, only MD2, OBJ, + * PLY and EET file formats are supported. + * + * @ingroup Evas_3D_Mesh + */ + params { + @in Eina_File* file; /*@ Eina_File with mesh data. */ + @in const(char)* key; /*@ Key in the mesh file. */ + } + } + file_set { /** * Load mesh data from file. diff --git a/src/lib/evas/common/evas_model_load.c b/src/lib/evas/common/evas_model_load.c index 0598d31e21..e00290e315 100644 --- a/src/lib/evas/common/evas_model_load.c +++ b/src/lib/evas/common/evas_model_load.c @@ -8,11 +8,35 @@ #include "evas_private.h" void -evas_common_load_model_to_file(Evas_3D_Mesh *model, const char *file) +_evas_common_load_model(Evas_3D_Mesh *model, + Eina_File *file, + const char *file_path) { char *p; char *loader_type = NULL; + p = strrchr(file_path, '.'); + if (p) + { + p++; +#define CHECK_EXTENTION_BY_FILE_NAME(extention) \ + if (!strcasecmp(p, #extention)) \ + { \ + evas_model_load_file_##extention(model, file); \ + loader_type = #extention; \ + } + CHECK_EXTENTION_BY_FILE_NAME(eet) + CHECK_EXTENTION_BY_FILE_NAME(md2) + CHECK_EXTENTION_BY_FILE_NAME(obj) + CHECK_EXTENTION_BY_FILE_NAME(ply) +#undef CHECK_EXTENTION_BY_FILE_NAME + } + if (!loader_type) ERR("Invalid mesh file type."); +} + +void +evas_common_load_model_from_file(Evas_3D_Mesh *model, const char *file) +{ Eina_File *tmp_file = eina_file_open(file, 0); Eina_File *e_file = eina_file_dup(tmp_file); @@ -29,23 +53,27 @@ evas_common_load_model_to_file(Evas_3D_Mesh *model, const char *file) eina_file_close(tmp_file); - p = strrchr(file, '.'); - if (p) - { - p++; -#define CHECK_EXTENTION_BY_FILE_NAME(extention) \ - if (!strcasecmp(p, #extention)) \ - { \ - evas_model_load_file_##extention(model, e_file); \ - loader_type = #extention; \ - } - CHECK_EXTENTION_BY_FILE_NAME(eet) - CHECK_EXTENTION_BY_FILE_NAME(md2) - CHECK_EXTENTION_BY_FILE_NAME(obj) - CHECK_EXTENTION_BY_FILE_NAME(ply) -#undef CHECK_EXTENTION_BY_FILE_NAME - } - if (!loader_type) ERR("Invalid mesh file type."); + _evas_common_load_model(model, e_file, file); + + eina_file_close(e_file); + e_file = NULL; +} + +void +evas_common_load_model_from_eina_file(Evas_3D_Mesh *model, Eina_File *file) +{ + Eina_File *e_file = eina_file_dup(file); + + if (e_file == NULL) + { + ERR("Failed to open file %s\n", file); + eina_file_close(e_file); + e_file = NULL; + ERR("Failed to initialize loader."); + return; + } + + _evas_common_load_model(model, e_file, eina_file_filename_get(e_file)); eina_file_close(e_file); e_file = NULL; diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 411016da87..84299ebf4e 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1637,7 +1637,8 @@ void _evas_3d_eet_descriptor_shutdown(void); void _evas_3d_eet_file_free(void); /* Temporary save/load functions */ -void evas_common_load_model_to_file(Evas_3D_Mesh *model, const char *file); +void evas_common_load_model_from_file(Evas_3D_Mesh *model, const char *file); +void evas_common_load_model_from_eina_file(Evas_3D_Mesh *model, Eina_File *file); void evas_common_save_model_to_file(Evas_3D_Mesh *model, const char *file, Evas_3D_Mesh_Frame *f); void evas_model_load_file_eet(Evas_3D_Mesh *mesh, Eina_File *file); void evas_model_load_file_md2(Evas_3D_Mesh *mesh, Eina_File *file); diff --git a/src/tests/evas/evas_test_mesh.c b/src/tests/evas/evas_test_mesh.c index dde1dd348f..51f601e4b1 100644 --- a/src/tests/evas/evas_test_mesh.c +++ b/src/tests/evas/evas_test_mesh.c @@ -48,6 +48,11 @@ eo_do(mesh2, evas_3d_mesh_file_set(buffer, NULL)); \ res = _compare_meshes(mesh, mesh2); \ fail_if(res == 1); \ + eo_do(mesh, evas_3d_mesh_mmap_set(eina_file_open(file->path, 0), NULL)); \ + eo_do(mesh, evas_3d_mesh_save(buffer, NULL)); \ + eo_do(mesh2, evas_3d_mesh_mmap_set(eina_file_open(buffer, 0), NULL)); \ + res = _compare_meshes(mesh, mesh2); \ + fail_if(res == 1); \ eo_del(mesh2); \ eo_del(mesh); \ }