summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Shcherbina <o.shcherbina@samsung.com>2016-03-15 12:49:33 -0700
committerCedric Bail <cedric@osg.samsung.com>2016-03-15 12:49:39 -0700
commit296e8c22b039fd5669ad95375733bf214b23d71e (patch)
tree1aee03de378e591cbe0039bbaaa1c4f4788a8459
parentcdb72864853d5c3d81148c7a5846f39300eb46dc (diff)
downloadefl-296e8c22b039fd5669ad95375733bf214b23d71e.tar.gz
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 <cedric@osg.samsung.com>
-rw-r--r--src/lib/evas/canvas/evas_canvas3d_mesh.c17
-rw-r--r--src/lib/evas/canvas/evas_canvas3d_mesh.eo14
-rw-r--r--src/lib/evas/canvas/evas_canvas3d_node.c22
-rw-r--r--src/lib/evas/canvas/evas_canvas3d_node.eo13
-rw-r--r--src/lib/evas/canvas/evas_canvas3d_scene.c1
-rw-r--r--src/lib/evas/canvas/evas_types.eot3
-rw-r--r--src/lib/evas/include/evas_private.h6
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_3d.c21
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 d19a1fc39a..606d3994b0 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 d41b9103ec..3cbae535fb 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 54f4f07b73..ec7633d812 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 2ae271ad20..bded3241fe 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 cb7ffc373a..a8cc117050 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 6f37537347..27a2830769 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 525ff1da9e..ceee4a7aeb 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 fd3e26451e..5ca627fbaf 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