cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=296e8c22b039fd5669ad95375733bf214b23d71e
commit 296e8c22b039fd5669ad95375733bf214b23d71e Author: Oleksandr Shcherbina <o.shcherb...@samsung.com> Date: Tue Mar 15 12:49:33 2016 -0700 evas.canvas3d: support static LOD technic Summary: Main flow: add several meshes(with different number of polygons) in one node, enable LOD for node, set boundary distances to choose need mesh depend on distance to the camera node, render only need mesh. Add API's enable lod in evas_canvas3d_node module and set boundary distance to module evas_canvas3d_mesh module Refactored function evas_canvas3d_node_mesh_collect to calculate distance. Refactored _scene_render to have possibility pass to the render only need LOD mesh. Reviewers: cedric, Hermet, raster Subscribers: jpeg Differential Revision: https://phab.enlightenment.org/D3731 Signed-off-by: Cedric Bail <ced...@osg.samsung.com> --- src/lib/evas/canvas/evas_canvas3d_mesh.c | 17 +++++++++++++++++ src/lib/evas/canvas/evas_canvas3d_mesh.eo | 14 ++++++++++++++ src/lib/evas/canvas/evas_canvas3d_node.c | 22 +++++++++++++++++++++- src/lib/evas/canvas/evas_canvas3d_node.eo | 13 +++++++++++++ src/lib/evas/canvas/evas_canvas3d_scene.c | 1 + src/lib/evas/canvas/evas_types.eot | 3 ++- src/lib/evas/include/evas_private.h | 6 +++++- src/modules/evas/engines/gl_common/evas_gl_3d.c | 21 ++++++++++++++++++--- 8 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/evas_canvas3d_mesh.c b/src/lib/evas/canvas/evas_canvas3d_mesh.c index d19a1fc..606d399 100644 --- a/src/lib/evas/canvas/evas_canvas3d_mesh.c +++ b/src/lib/evas/canvas/evas_canvas3d_mesh.c @@ -133,6 +133,8 @@ _mesh_init(Evas_Canvas3D_Mesh_Data *pd) pd->shadows_edges_filtering_level = 4; pd->shadows_edges_size = 300.0; pd->shadows_constant_bias = 0.00015; + pd->near_lod_boundary = 0.0; + pd->far_lod_boundary = 0.0; } static inline void @@ -1151,4 +1153,19 @@ _evas_canvas3d_mesh_convex_hull_data_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Mesh return; } +EOLIAN static void +_evas_canvas3d_mesh_lod_boundary_set(Eo *obj EINA_UNUSED, Evas_Canvas3D_Mesh_Data *pd, + Evas_Real near, Evas_Real far) +{ + pd->near_lod_boundary = near; + pd->far_lod_boundary = far; +} + +EOLIAN static void +_evas_canvas3d_mesh_lod_boundary_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Mesh_Data *pd, + Evas_Real *near, Evas_Real *far) +{ + *near = pd->near_lod_boundary; + *far = pd->far_lod_boundary; +} #include "canvas/evas_canvas3d_mesh.eo.c" diff --git a/src/lib/evas/canvas/evas_canvas3d_mesh.eo b/src/lib/evas/canvas/evas_canvas3d_mesh.eo index d41b910..3cbae53 100644 --- a/src/lib/evas/canvas/evas_canvas3d_mesh.eo +++ b/src/lib/evas/canvas/evas_canvas3d_mesh.eo @@ -405,6 +405,20 @@ class Evas.Canvas3D.Mesh (Evas.Canvas3D.Object, Evas.Common_Interface, Efl.File) bias: Evas.Real; [[Offset.]] } } + @property lod_boundary { + set { + [[Set LOD boundary distances.]] + } + get { + [[Get LOD boundary distances. + + See also @Evas.Canvas3D.Mesh.lod_boundary.set.]] + } + values { + near: Evas.Real; [[up boundary]] + far: Evas.Real; [[down boundary]] + } + } } implements { Eo.Base.constructor; diff --git a/src/lib/evas/canvas/evas_canvas3d_node.c b/src/lib/evas/canvas/evas_canvas3d_node.c index 54f4f07..ec7633d 100644 --- a/src/lib/evas/canvas/evas_canvas3d_node.c +++ b/src/lib/evas/canvas/evas_canvas3d_node.c @@ -892,7 +892,12 @@ evas_canvas3d_node_mesh_collect(Evas_Canvas3D_Node *node, void *data) if (pd->type == EVAS_CANVAS3D_NODE_TYPE_MESH) { scene_data->mesh_nodes = eina_list_append(scene_data->mesh_nodes, node); - + /*In case LOD calculate distance to the camera node*/ + if (pd->lod) + { + Evas_Canvas3D_Node_Data *pd_camera = eo_data_scope_get(scene_data->camera_node, MY_CLASS); + scene_data->lod_distance = eina_vector3_distance_get(&pd_camera->position, &pd->position_world); + } /* calculation of tangent space for all meshes */ list_meshes = (Eina_List *)evas_canvas3d_node_mesh_list_get(node); EINA_LIST_FOREACH(list_meshes, l, mesh) @@ -1034,6 +1039,7 @@ _evas_canvas3d_node_constructor(Eo *obj, Evas_Canvas3D_Node_Data *pd, Evas_Canva pd->scale_inherit = EINA_TRUE; pd->data.mesh.node_meshes = 0; pd->billboard_target = NULL; + pd->lod = EINA_FALSE; evas_box3_set(&pd->aabb, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); @@ -1652,4 +1658,18 @@ _evas_canvas3d_node_billboard_target_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Node { return pd->billboard_target; } + +EOLIAN static void +_evas_canvas3d_node_lod_enable_set(Eo *obj, Evas_Canvas3D_Node_Data *pd, + Eina_Bool enable) +{ + pd->lod = enable; + evas_canvas3d_object_change(obj, EVAS_CANVAS3D_STATE_NODE_LOD, NULL); +} + +EOLIAN static Eina_Bool +_evas_canvas3d_node_lod_enable_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Node_Data *pd) +{ + return pd->lod; +} #include "canvas/evas_canvas3d_node.eo.c" diff --git a/src/lib/evas/canvas/evas_canvas3d_node.eo b/src/lib/evas/canvas/evas_canvas3d_node.eo index 2ae271a..bded324 100644 --- a/src/lib/evas/canvas/evas_canvas3d_node.eo +++ b/src/lib/evas/canvas/evas_canvas3d_node.eo @@ -368,6 +368,19 @@ class Evas.Canvas3D.Node (Evas.Canvas3D.Object, Evas.Common_Interface) or $null if there're none.]] } } + @property lod_enable { + set { + [[Enable behavior of node like LOD object.]] + } + get { + [[Get(check) status of node does node is LOD object. + + See also @Evas.Canvas3D.Node.lod_enable.set.]] + } + values { + enable: bool; [[status property (true/false)]] + } + } } implements { Eo.Base.destructor; diff --git a/src/lib/evas/canvas/evas_canvas3d_scene.c b/src/lib/evas/canvas/evas_canvas3d_scene.c index cb7ffc3..a8cc117 100644 --- a/src/lib/evas/canvas/evas_canvas3d_scene.c +++ b/src/lib/evas/canvas/evas_canvas3d_scene.c @@ -12,6 +12,7 @@ evas_canvas3d_scene_data_init(Evas_Canvas3D_Scene_Public_Data *data) data->node_mesh_colors = NULL; data->colors_node_mesh = NULL; data->render_to_texture = EINA_FALSE; + data->lod_distance = 0; } void diff --git a/src/lib/evas/canvas/evas_types.eot b/src/lib/evas/canvas/evas_types.eot index 6f37537..27a2830 100644 --- a/src/lib/evas/canvas/evas_types.eot +++ b/src/lib/evas/canvas/evas_types.eot @@ -346,7 +346,8 @@ enum Evas.Canvas3D.State node_parent_orientation, node_parent_scale, node_member, - node_parent_billboard [[@since 1.14]] + node_parent_billboard, [[@since 1.14]] + node_lod [[@since 1.18]] } enum Evas.Canvas3D.Space diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 525ff1d..ceee4a7 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -289,6 +289,7 @@ struct _Evas_Canvas3D_Node Eina_Bool position_inherit : 1; Eina_Bool orientation_inherit : 1; Eina_Bool scale_inherit : 1; + Eina_Bool lod : 1; }; struct _Evas_Canvas3D_Camera @@ -387,6 +388,8 @@ struct _Evas_Canvas3D_Mesh int shadows_edges_filtering_level; Evas_Real shadows_edges_size; Evas_Real shadows_constant_bias; + Evas_Real near_lod_boundary; + Evas_Real far_lod_boundary; }; struct _Evas_Canvas3D_Texture @@ -437,7 +440,6 @@ struct _Evas_Canvas3D_Scene_Public_Data Eina_List *mesh_nodes; Eina_Bool shadows_enabled :1; Eina_Bool color_pick_enabled :1; - Eina_Hash *node_mesh_colors; Eina_Hash *colors_node_mesh; @@ -445,6 +447,8 @@ struct _Evas_Canvas3D_Scene_Public_Data Evas_Real depth_offset; Evas_Real depth_constant; Eina_Bool render_to_texture; + + unsigned int lod_distance; }; struct _Evas_Canvas3D_Pick_Data diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d.c b/src/modules/evas/engines/gl_common/evas_gl_3d.c index fd3e264..5ca627f 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c @@ -1,6 +1,16 @@ #include "evas_gl_private.h" #include "evas_gl_3d_private.h" +#define CHECK_LOD_DISTANCE \ + if (pd_mesh_node->lod) \ + { \ + if (pdmesh->near_lod_boundary > data->lod_distance) \ + continue; \ + else if ((pdmesh->near_lod_boundary < data->lod_distance) && \ + (pdmesh->far_lod_boundary < data->lod_distance)) \ + continue; \ + } + #define RENDER_MESH_NODE_ITERATE_BEGIN(param) \ Eina_Matrix4 matrix_mv; \ Eina_Matrix4 matrix_mvp; \ @@ -11,8 +21,9 @@ it = eina_hash_iterator_data_new(pd_mesh_node->data.mesh.node_meshes); \ while (eina_iterator_next(it, &ptr)) \ { \ - Evas_Canvas3D_Node_Mesh *nm = (Evas_Canvas3D_Node_Mesh *)ptr; \ - Evas_Canvas3D_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_CANVAS3D_MESH_CLASS); + Evas_Canvas3D_Node_Mesh *nm = (Evas_Canvas3D_Node_Mesh *)ptr; \ + Evas_Canvas3D_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_CANVAS3D_MESH_CLASS); \ + CHECK_LOD_DISTANCE #define RENDER_MESH_NODE_ITERATE_END \ } \ @@ -1282,6 +1293,10 @@ _scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_Canvas3D_Scen { Evas_Canvas3D_Node_Mesh *nm = (Evas_Canvas3D_Node_Mesh *)ptr; Evas_Canvas3D_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_CANVAS3D_MESH_CLASS); + /*In case LOD enable pass in render only LOD meshes in dependences of the + distance to the camera node: + near_boundary <= distance <= far_boundary*/ + CHECK_LOD_DISTANCE if (data->shadows_enabled) { pdmesh->shadowed = EINA_TRUE; @@ -1399,6 +1414,6 @@ e3d_drawable_texture_pixel_color_get(GLuint tex EINA_UNUSED, int x, int y, glBindFramebuffer(GL_FRAMEBUFFER, d->fbo); } - +#undef CHECK_LOD_DISTANCE #undef RENDER_MESH_NODE_ITERATE_BEGIN #undef RENDER_MESH_NODE_ITERATE_END --