forked from enlightenment/efl
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>
This commit is contained in:
parent
cdb7286485
commit
296e8c22b0
|
@ -133,6 +133,8 @@ _mesh_init(Evas_Canvas3D_Mesh_Data *pd)
|
||||||
pd->shadows_edges_filtering_level = 4;
|
pd->shadows_edges_filtering_level = 4;
|
||||||
pd->shadows_edges_size = 300.0;
|
pd->shadows_edges_size = 300.0;
|
||||||
pd->shadows_constant_bias = 0.00015;
|
pd->shadows_constant_bias = 0.00015;
|
||||||
|
pd->near_lod_boundary = 0.0;
|
||||||
|
pd->far_lod_boundary = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -1151,4 +1153,19 @@ _evas_canvas3d_mesh_convex_hull_data_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Mesh
|
||||||
return;
|
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"
|
#include "canvas/evas_canvas3d_mesh.eo.c"
|
||||||
|
|
|
@ -405,6 +405,20 @@ class Evas.Canvas3D.Mesh (Evas.Canvas3D.Object, Evas.Common_Interface, Efl.File)
|
||||||
bias: Evas.Real; [[Offset.]]
|
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 {
|
implements {
|
||||||
Eo.Base.constructor;
|
Eo.Base.constructor;
|
||||||
|
|
|
@ -892,7 +892,12 @@ evas_canvas3d_node_mesh_collect(Evas_Canvas3D_Node *node, void *data)
|
||||||
if (pd->type == EVAS_CANVAS3D_NODE_TYPE_MESH)
|
if (pd->type == EVAS_CANVAS3D_NODE_TYPE_MESH)
|
||||||
{
|
{
|
||||||
scene_data->mesh_nodes = eina_list_append(scene_data->mesh_nodes, node);
|
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 */
|
/* calculation of tangent space for all meshes */
|
||||||
list_meshes = (Eina_List *)evas_canvas3d_node_mesh_list_get(node);
|
list_meshes = (Eina_List *)evas_canvas3d_node_mesh_list_get(node);
|
||||||
EINA_LIST_FOREACH(list_meshes, l, mesh)
|
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->scale_inherit = EINA_TRUE;
|
||||||
pd->data.mesh.node_meshes = 0;
|
pd->data.mesh.node_meshes = 0;
|
||||||
pd->billboard_target = NULL;
|
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);
|
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;
|
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"
|
#include "canvas/evas_canvas3d_node.eo.c"
|
||||||
|
|
|
@ -368,6 +368,19 @@ class Evas.Canvas3D.Node (Evas.Canvas3D.Object, Evas.Common_Interface)
|
||||||
or $null if there're none.]]
|
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 {
|
implements {
|
||||||
Eo.Base.destructor;
|
Eo.Base.destructor;
|
||||||
|
|
|
@ -12,6 +12,7 @@ evas_canvas3d_scene_data_init(Evas_Canvas3D_Scene_Public_Data *data)
|
||||||
data->node_mesh_colors = NULL;
|
data->node_mesh_colors = NULL;
|
||||||
data->colors_node_mesh = NULL;
|
data->colors_node_mesh = NULL;
|
||||||
data->render_to_texture = EINA_FALSE;
|
data->render_to_texture = EINA_FALSE;
|
||||||
|
data->lod_distance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -346,7 +346,8 @@ enum Evas.Canvas3D.State
|
||||||
node_parent_orientation,
|
node_parent_orientation,
|
||||||
node_parent_scale,
|
node_parent_scale,
|
||||||
node_member,
|
node_member,
|
||||||
node_parent_billboard [[@since 1.14]]
|
node_parent_billboard, [[@since 1.14]]
|
||||||
|
node_lod [[@since 1.18]]
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Evas.Canvas3D.Space
|
enum Evas.Canvas3D.Space
|
||||||
|
|
|
@ -289,6 +289,7 @@ struct _Evas_Canvas3D_Node
|
||||||
Eina_Bool position_inherit : 1;
|
Eina_Bool position_inherit : 1;
|
||||||
Eina_Bool orientation_inherit : 1;
|
Eina_Bool orientation_inherit : 1;
|
||||||
Eina_Bool scale_inherit : 1;
|
Eina_Bool scale_inherit : 1;
|
||||||
|
Eina_Bool lod : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Canvas3D_Camera
|
struct _Evas_Canvas3D_Camera
|
||||||
|
@ -387,6 +388,8 @@ struct _Evas_Canvas3D_Mesh
|
||||||
int shadows_edges_filtering_level;
|
int shadows_edges_filtering_level;
|
||||||
Evas_Real shadows_edges_size;
|
Evas_Real shadows_edges_size;
|
||||||
Evas_Real shadows_constant_bias;
|
Evas_Real shadows_constant_bias;
|
||||||
|
Evas_Real near_lod_boundary;
|
||||||
|
Evas_Real far_lod_boundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Canvas3D_Texture
|
struct _Evas_Canvas3D_Texture
|
||||||
|
@ -437,7 +440,6 @@ struct _Evas_Canvas3D_Scene_Public_Data
|
||||||
Eina_List *mesh_nodes;
|
Eina_List *mesh_nodes;
|
||||||
Eina_Bool shadows_enabled :1;
|
Eina_Bool shadows_enabled :1;
|
||||||
Eina_Bool color_pick_enabled :1;
|
Eina_Bool color_pick_enabled :1;
|
||||||
|
|
||||||
Eina_Hash *node_mesh_colors;
|
Eina_Hash *node_mesh_colors;
|
||||||
Eina_Hash *colors_node_mesh;
|
Eina_Hash *colors_node_mesh;
|
||||||
|
|
||||||
|
@ -445,6 +447,8 @@ struct _Evas_Canvas3D_Scene_Public_Data
|
||||||
Evas_Real depth_offset;
|
Evas_Real depth_offset;
|
||||||
Evas_Real depth_constant;
|
Evas_Real depth_constant;
|
||||||
Eina_Bool render_to_texture;
|
Eina_Bool render_to_texture;
|
||||||
|
|
||||||
|
unsigned int lod_distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Canvas3D_Pick_Data
|
struct _Evas_Canvas3D_Pick_Data
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
#include "evas_gl_private.h"
|
#include "evas_gl_private.h"
|
||||||
#include "evas_gl_3d_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) \
|
#define RENDER_MESH_NODE_ITERATE_BEGIN(param) \
|
||||||
Eina_Matrix4 matrix_mv; \
|
Eina_Matrix4 matrix_mv; \
|
||||||
Eina_Matrix4 matrix_mvp; \
|
Eina_Matrix4 matrix_mvp; \
|
||||||
|
@ -12,7 +22,8 @@
|
||||||
while (eina_iterator_next(it, &ptr)) \
|
while (eina_iterator_next(it, &ptr)) \
|
||||||
{ \
|
{ \
|
||||||
Evas_Canvas3D_Node_Mesh *nm = (Evas_Canvas3D_Node_Mesh *)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_Mesh_Data *pdmesh = eo_data_scope_get(nm->mesh, EVAS_CANVAS3D_MESH_CLASS); \
|
||||||
|
CHECK_LOD_DISTANCE
|
||||||
|
|
||||||
#define RENDER_MESH_NODE_ITERATE_END \
|
#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_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_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)
|
if (data->shadows_enabled)
|
||||||
{
|
{
|
||||||
pdmesh->shadowed = EINA_TRUE;
|
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);
|
glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
|
||||||
}
|
}
|
||||||
|
#undef CHECK_LOD_DISTANCE
|
||||||
#undef RENDER_MESH_NODE_ITERATE_BEGIN
|
#undef RENDER_MESH_NODE_ITERATE_BEGIN
|
||||||
#undef RENDER_MESH_NODE_ITERATE_END
|
#undef RENDER_MESH_NODE_ITERATE_END
|
||||||
|
|
Loading…
Reference in New Issue