[evas/evas_3D] Billboard mechanism

Summary:
Add pointer to target billboard node in Evas_3D_Node
Skip set flags change orientation for billboard node
Add method node_billboard_update to use it for change orientation during traverse
by nodes
Split API evas_3d_node_look_at_set to have possibility change orientation of node
without set flags

Reviewers: cedric, Hermet

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D2245
This commit is contained in:
Oleksandr Shcherbina 2015-04-06 14:10:28 +09:00 committed by ChunEon Park
parent 5a5322706e
commit bc8dfbb1ef
7 changed files with 285 additions and 76 deletions

View File

@ -359,6 +359,7 @@ resources/images/four_NM_height.tga \
resources/images/rocks_NM_height.tga \
resources/images/grid.png \
resources/images/grid_n.png \
resources/images/billboard.png \
resources/models/mesh_for_mmap.eet \
resources/models/mesh_for_mmap.md2 \
resources/models/mesh_for_mmap.obj \

View File

@ -1,9 +1,11 @@
/**
* This example illustrating use of shadows in the scene and callbacks(clicked, collision).
* This example illustrating use of shadows, callbacks(clicked, collision),
* and technic of the billboard.
* Model and cube are clickable. Model detects collision with sphere.
* Cube detects collision with sphere, model and cone.
* @see evas_3d_scene_shadows_enable_set(Eina_Bool _shadows_enabled)
* @see evas_3d_object_callback_register
* @see evas_3d_billboard_set/get
*
* @verbatim
* gcc -o evas-3d-shadows evas-3d-shadows.c evas-3d-primitives.c `pkg-config --libs --cflags efl evas ecore ecore-evas eo eina` -lm
@ -37,7 +39,8 @@
#define SPECULAR_LIGHT 1.0, 1.0, 1.0
static const char *model_path = PACKAGE_EXAMPLES_DIR EVAS_MODEL_FOLDER "/sonic.md2";
static const char *image_path = PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/sonic.png";
static const char *b_image_path = PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/billboard.png";
static const vec2 tex_scale = {1, 1};
static const vec2 fence_tex_scale = {80, 6};
@ -89,6 +92,7 @@ typedef struct _Body_3D
Eo *material;
Eo *mesh;
Eo *node;
Eo *texture;
} Body_3D;
typedef struct _Scene_Data
@ -99,6 +103,7 @@ typedef struct _Scene_Data
Eo *camera;
Eo *light_node;
Eo *light;
Eo *mediator;
Body_3D sphere;
Body_3D cube;
@ -107,6 +112,9 @@ typedef struct _Scene_Data
Body_3D model;
Body_3D cone;
Body_3D fence;
Body_3D billboard;
Eina_Bool init;
} Scene_Data;
static void
@ -114,23 +122,37 @@ _show_help()
{
fprintf(stdout, "Press 'w'/'s' key to move up/down object\n");
fprintf(stdout, "Press 'a'/'d' key to move left/right object\n");
fprintf(stdout, "Press 'q'/'e' key to to move near/far object\n");
fprintf(stdout, "Press 'q'/'e' key to move near/far object\n");
fprintf(stdout, "Cude and model can be moved.\n");
fprintf(stdout, "Cube detects intersection with model, sphere, cone\n");
fprintf(stdout, "Model detects intersection with sphere\n");
fprintf(stdout, "Press '1'/'2' key to change kind of node - billboard/normal model\n");
fprintf(stdout, "Press Up/Down key to change position of camera\n");
fprintf(stdout, "Press 'i' key to return initial view of scene\n");
}
static Eina_Bool
_animate_scene(void *data)
{
static int frame = 0;
Body_3D *body = (Body_3D *)data;
eo_do(body->node, evas_3d_node_mesh_frame_set(body->mesh, frame));
/*frame += 32;*/
if (frame > 256 * 20) frame = 0;
static float angle = 0;
Evas_Real x, y, z;
Scene_Data *scene = (Scene_Data *)data;
if (scene->init)
{
eo_do(scene->mediator,
evas_3d_node_position_get(EVAS_3D_SPACE_PARENT, &x, &y, &z));
eo_do(scene->mediator,
evas_3d_node_position_set(sin(angle) * 20 , y , cos(angle) * 20),
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 3.0, 0.0,
EVAS_3D_SPACE_PARENT, 0.0, 5.0, 0.0));
angle += 0.005;
if (angle > 360) angle = 0.0;
}
else
eo_do(scene->mediator,
evas_3d_node_position_set(0.0, 6.0, 12.0),
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 3.0, 0.0,
EVAS_3D_SPACE_PARENT, 0.0, 5.0, 0.0));
return EINA_TRUE;
}
@ -241,6 +263,9 @@ _fence_setup(Body_3D *fence)
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_texture_set(EVAS_3D_MATERIAL_NORMAL, texture1),
evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT, 1.0, 1.0, 1.0, 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(100.0));
fence->mesh = eo_add(EVAS_3D_MESH_CLASS, evas);
evas_3d_add_cylinder_frame(fence->mesh, 0, 50, fence_tex_scale);
@ -292,9 +317,9 @@ _box_setup(Body_3D *box)
static void
_model_setup(Body_3D *model)
{
Eo *texture = eo_add(EVAS_3D_TEXTURE_CLASS, evas);
eo_do(texture,
evas_3d_texture_file_set(PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/sonic.png", NULL),
model->texture = eo_add(EVAS_3D_TEXTURE_CLASS, evas);
eo_do(model->texture,
evas_3d_texture_file_set(image_path, NULL),
evas_3d_texture_filter_set(EVAS_3D_TEXTURE_FILTER_NEAREST,
EVAS_3D_TEXTURE_FILTER_NEAREST),
evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT,
@ -302,8 +327,8 @@ _model_setup(Body_3D *model)
model->material = eo_add(EVAS_3D_MATERIAL_CLASS, evas);
eo_do(model->material,
evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, texture),
evas_3d_material_texture_set(EVAS_3D_MATERIAL_AMBIENT, texture),
evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, model->texture),
evas_3d_material_texture_set(EVAS_3D_MATERIAL_AMBIENT, model->texture),
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),
@ -311,7 +336,6 @@ _model_setup(Body_3D *model)
model->mesh = eo_add(EVAS_3D_MESH_CLASS, evas);
eo_do(model->mesh,
efl_file_set(model_path, NULL),
evas_3d_mesh_frame_material_set(0, model->material),
@ -325,25 +349,70 @@ _model_setup(Body_3D *model)
evas_3d_node_orientation_angle_axis_set(120.0, -0.577, -0.577, -0.577));
}
static void
_billboard_setup(Scene_Data *data)
{
data->billboard.texture = eo_add(EVAS_3D_TEXTURE_CLASS, evas);
eo_do(data->billboard.texture,
evas_3d_texture_file_set(b_image_path, NULL),
evas_3d_texture_filter_set(EVAS_3D_TEXTURE_FILTER_NEAREST,
EVAS_3D_TEXTURE_FILTER_NEAREST),
evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT,
EVAS_3D_WRAP_MODE_REPEAT));
data->billboard.mesh = eo_add(EVAS_3D_MESH_CLASS, evas);
evas_3d_add_square_frame(data->billboard.mesh, 0);
_body_material_set(&(data->billboard), 1.0, 1.0, 1.0);
eo_do(data->billboard.material,
evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, data->billboard.texture));
eo_do(data->billboard.mesh,
evas_3d_mesh_frame_material_set(0, data->billboard.material),
evas_3d_mesh_alpha_func_set(EVAS_3D_COMPARISON_GREATER, 0),
evas_3d_mesh_alpha_test_enable_set(EINA_TRUE),
evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_DIFFUSE),
evas_3d_mesh_blending_enable_set(EINA_TRUE),
evas_3d_mesh_blending_func_set(EVAS_3D_BLEND_SRC_ALPHA,
EVAS_3D_BLEND_ONE_MINUS_SRC_ALPHA));
data->billboard.node = eo_add(EVAS_3D_NODE_CLASS, evas,
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
eo_do(data->billboard.node,
evas_3d_node_mesh_add(data->billboard.mesh),
evas_3d_node_position_set(0.0, 2.0, 0.0),
evas_3d_node_scale_set(2.2, 4.6, 4.0));
eo_do(data->billboard.node,
evas_3d_node_billboard_target_set(data->mediator));
}
static void
_camera_setup(Scene_Data *data)
{
data->camera = eo_add(EVAS_3D_CAMERA_CLASS, evas);
data->mediator = eo_add(EVAS_3D_NODE_CLASS, evas,
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_NODE));
eo_do(data->camera,
evas_3d_camera_projection_perspective_set(50.0, 1.0, 2.0, 50.0));
evas_3d_camera_projection_perspective_set(50.0, 1.0, 2.0, 100.0));
data->camera_node =
eo_add(EVAS_3D_NODE_CLASS, evas,
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_CAMERA));
eo_do(data->camera_node,
evas_3d_node_camera_set(data->camera),
evas_3d_node_camera_set(data->camera));
eo_do(data->mediator,
evas_3d_node_position_set(0.0, 6.0, 12.0),
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 3.0, 0.0,
EVAS_3D_SPACE_PARENT, 0.0, 5.0, 0.0));
eo_do(data->root_node, evas_3d_node_member_add(data->camera_node));
eo_do(data->mediator, evas_3d_node_member_add(data->camera_node));
eo_do(data->root_node, evas_3d_node_member_add(data->mediator));
}
static void
@ -362,7 +431,7 @@ _light_setup(Scene_Data *data)
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_LIGHT));
eo_do(data->light_node,
evas_3d_node_light_set(data->light),
evas_3d_node_position_set(50.0, 50.0, 20.0),
evas_3d_node_position_set(50.0, 50.0, 70.0),
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 15.0, 0.0, -5.0,
EVAS_3D_SPACE_PARENT, 0.0, 0.0, 1.0));
eo_do(data->root_node, evas_3d_node_member_add(data->light_node));
@ -371,6 +440,8 @@ _light_setup(Scene_Data *data)
static void
_scene_setup(Scene_Data *data)
{
data->init = EINA_FALSE;
data->scene = eo_add(EVAS_3D_SCENE_CLASS, evas);
eo_do(data->scene,
@ -392,8 +463,9 @@ _scene_setup(Scene_Data *data)
_model_setup(&data->model);
_cone_setup(&data->cone);
_fence_setup(&data->fence);
_billboard_setup(data);
eo_do(data->root_node,
eo_do(data->root_node,
evas_3d_node_member_add(data->sphere.node),
evas_3d_node_member_add(data->cube.node),
evas_3d_node_member_add(data->cylinder.node),
@ -412,6 +484,7 @@ static void
_on_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *eo EINA_UNUSED, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
Scene_Data *scene = (Scene_Data *)data;
if (!strcmp("w", ev->key))
{
Evas_Real x, y, z;
@ -448,6 +521,34 @@ _on_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *eo EINA_U
eo_do(choosed_node, evas_3d_node_position_get(EVAS_3D_SPACE_PARENT, &x, &y, &z));
eo_do(choosed_node, evas_3d_node_position_set(x, y, z + STEP));
}
else if(!strcmp("1", ev->key))
{
eo_do(scene->root_node, evas_3d_node_member_del(scene->model.node));
eo_do(scene->root_node, evas_3d_node_member_add(scene->billboard.node));
}
else if(!strcmp("2", ev->key))
{
eo_do(scene->root_node, evas_3d_node_member_add(scene->model.node));
eo_do(scene->root_node, evas_3d_node_member_del(scene->billboard.node));
}
else if(!strcmp("Up", ev->key))
{
Evas_Real x, y, z;
eo_do(scene->camera_node, evas_3d_node_position_get(EVAS_3D_SPACE_PARENT, &x, &y, &z));
eo_do(scene->camera_node, evas_3d_node_position_set(x, y, z + STEP));
}
else if(!strcmp("Down", ev->key))
{
Evas_Real x, y, z;
eo_do(scene->camera_node, evas_3d_node_position_get(EVAS_3D_SPACE_PARENT, &x, &y, &z));
eo_do(scene->camera_node, evas_3d_node_position_set(x, y, z - STEP));
}
else if (!strcmp("i", ev->key))
{
scene->init = !scene->init;
eo_do(scene->model.node, evas_3d_node_position_set(0.0, 0.0, 0.0));
eo_do(scene->billboard.node, evas_3d_node_position_set(0.0, 2.0, 0.0));
}
else
{
_show_help();
@ -551,12 +652,15 @@ main(void)
eo_do(data.model.node, eo_event_callback_add(EVAS_3D_OBJECT_EVENT_CLICKED, _cb_clicked, NULL));
eo_do(data.model.node, eo_event_callback_add(EVAS_3D_OBJECT_EVENT_COLLISION, _cb_collision, nodes1));
eo_do(data.billboard.node, eo_event_callback_add(EVAS_3D_OBJECT_EVENT_CLICKED, _cb_clicked, NULL));
eo_do(data.billboard.node, eo_event_callback_add(EVAS_3D_OBJECT_EVENT_COLLISION, _cb_collision, nodes1));
evas_object_event_callback_add(image, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, &data);
evas_object_event_callback_add(image, EVAS_CALLBACK_KEY_DOWN, _on_key_down, &data);
/* Add animator. */
ecore_animator_frametime_set(0.008);
anim = ecore_animator_add(_animate_scene, &data.model);
anim = ecore_animator_add(_animate_scene, &data);
/* Enter main loop. */
ecore_main_loop_begin();

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -516,6 +516,7 @@ typedef enum _Evas_3D_State
EVAS_3D_STATE_NODE_PARENT_ORIENTATION,
EVAS_3D_STATE_NODE_PARENT_SCALE,
EVAS_3D_STATE_NODE_MEMBER,
EVAS_3D_STATE_NODE_PARENT_BILLBOARD,
} Evas_3D_State;
/**

View File

@ -7,6 +7,9 @@
Evas_3D_Mesh_Frame *evas_3d_mesh_frame_find(Evas_3D_Mesh_Data *pd, int frame);
static void
_look_at_set(Evas_3D_Node_Data *pd, Evas_Vec3 *target, Evas_Vec3 *up);
static Eina_Stringshare *
_generate_unic_color_key(Evas_Color *color, Evas_Color *bg_color, Evas_3D_Node *node, Evas_3D_Mesh *mesh,
Eina_Bool init)
@ -156,9 +159,13 @@ _evas_3d_node_evas_3d_object_change_notify(Eo *obj, Evas_3D_Node_Data *pd, Evas_
{
eo_do(n, evas_3d_object_change(EVAS_3D_STATE_NODE_PARENT_SCALE, obj));
}
if (orientation)
if (orientation && !(pd->billboard_target))
EINA_LIST_FOREACH(pd->members, l, n)
{
/*Skip change orientation if node is billboard*/
Evas_3D_Node_Data *pdm = eo_data_scope_get(n, EVAS_3D_NODE_CLASS);
if (pdm->billboard_target)
continue;
eo_do(n, evas_3d_object_change(EVAS_3D_STATE_NODE_PARENT_ORIENTATION, obj));
}
if (position)
@ -285,6 +292,46 @@ _node_transform_update(Evas_3D_Node *node, void *data EINA_UNUSED)
return EINA_TRUE;
}
static Eina_Bool
_node_billboard_update(Evas_3D_Node *node, void *data EINA_UNUSED)
{
Evas_Vec3 target;
Evas_Vec3 up;
Evas_3D_Node_Data *pd_node = eo_data_scope_get(node, MY_CLASS);
if (pd_node->billboard_target)
{
Evas_3D_Node_Data *pd_target = eo_data_scope_get(pd_node->billboard_target,
MY_CLASS);
evas_vec3_set(&target, pd_target->position.x, pd_target->position.y,
pd_target->position.z);
evas_vec3_set(&up, 0, 1, 0);
_look_at_set(pd_node, &target, &up);
if (pd_node->type == EVAS_3D_NODE_TYPE_MESH)
{
evas_mat4_build(&pd_node->data.mesh.matrix_local_to_world,
&pd_node->position, &pd_node->orientation,
&pd_node->scale);
}
else if (pd_node->type == EVAS_3D_NODE_TYPE_LIGHT)
{
evas_mat4_build(&pd_node->data.light.matrix_local_to_world,
&pd_node->position, &pd_node->orientation,
&pd_node->scale);
}
else if (pd_node->type == EVAS_3D_NODE_TYPE_CAMERA)
{
evas_mat4_inverse_build(&pd_node->data.light.matrix_local_to_world,
&pd_node->position, &pd_node->orientation,
&pd_node->scale);
}
else
ERR("Not supported type of node: line %d in file %s", __LINE__ , __FILE__);
}
return EINA_TRUE;
}
static Eina_Bool
_node_item_update(Evas_3D_Node *node, void *data EINA_UNUSED)
{
@ -589,7 +636,9 @@ _evas_3d_node_evas_3d_object_update_notify(Eo *obj, Evas_3D_Node_Data *pd EINA_U
/* Update transform. */
evas_3d_node_tree_traverse(obj, EVAS_3D_TREE_TRAVERSE_LEVEL_ORDER, EINA_FALSE,
_node_transform_update, NULL);
/*Update billboard*/
evas_3d_node_tree_traverse(obj, EVAS_3D_TREE_TRAVERSE_ANY_ORDER, EINA_FALSE,
_node_billboard_update, NULL);
/* Update AABB. */
evas_3d_node_tree_traverse(obj, EVAS_3D_TREE_TRAVERSE_POST_ORDER, EINA_FALSE,
_node_aabb_update, NULL);
@ -1035,6 +1084,7 @@ _evas_3d_node_constructor(Eo *obj, Evas_3D_Node_Data *pd, Evas_3D_Node_Type type
pd->orientation_inherit = EINA_TRUE;
pd->scale_inherit = EINA_TRUE;
pd->data.mesh.node_meshes = 0;
pd->billboard_target = NULL;
evas_box3_set(&pd->aabb, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
@ -1310,62 +1360,15 @@ _evas_3d_node_scale_inherit_get(Eo *obj EINA_UNUSED, Evas_3D_Node_Data *pd)
return pd->scale_inherit;
}
EOLIAN static void
_evas_3d_node_look_at_set(Eo *obj, Evas_3D_Node_Data *pd,
Evas_3D_Space target_space, Evas_Real tx, Evas_Real ty, Evas_Real tz,
Evas_3D_Space up_space, Evas_Real ux, Evas_Real uy, Evas_Real uz)
static void
_look_at_set(Evas_3D_Node_Data *pd, Evas_Vec3 *target, Evas_Vec3 *up)
{
Evas_Vec3 target;
Evas_Vec3 up;
Evas_Vec3 x, y, z;
/* Target position in parent space. */
if (target_space == EVAS_3D_SPACE_LOCAL)
{
ERR("TODO:");
return;
}
else if (target_space == EVAS_3D_SPACE_PARENT)
{
evas_vec3_set(&target, tx, ty, tz);
}
else if (target_space == EVAS_3D_SPACE_WORLD)
{
ERR("TODO:");
return;
}
else
{
ERR("Invalid coordinate space.");
return;
}
if (up_space == EVAS_3D_SPACE_LOCAL)
{
evas_vec3_set(&up, ux, uy, uz);
//ERR("TODO:");
//return;
}
else if (up_space == EVAS_3D_SPACE_PARENT)
{
evas_vec3_set(&up, ux, uy, uz);
}
else if (up_space == EVAS_3D_SPACE_WORLD)
{
ERR("TODO:");
return;
}
else
{
ERR("Invalid coordinate space.");
return;
}
/* From now on, everything takes place in parent space. */
evas_vec3_subtract(&z, &pd->position, &target);
evas_vec3_subtract(&z, &pd->position, target);
evas_vec3_normalize(&z, &z);
evas_vec3_cross_product(&x, &up, &z);
evas_vec3_cross_product(&x, up, &z);
evas_vec3_normalize(&x, &x);
evas_vec3_cross_product(&y, &z, &x);
@ -1416,6 +1419,60 @@ _evas_3d_node_look_at_set(Eo *obj, Evas_3D_Node_Data *pd,
pd->orientation.x = (z.x + x.z) * s;
pd->orientation.y = (y.z + z.y) * s;
}
}
EOLIAN static void
_evas_3d_node_look_at_set(Eo *obj, Evas_3D_Node_Data *pd,
Evas_3D_Space target_space, Evas_Real tx, Evas_Real ty, Evas_Real tz,
Evas_3D_Space up_space, Evas_Real ux, Evas_Real uy, Evas_Real uz)
{
Evas_Vec3 target;
Evas_Vec3 up;
/* Target position in parent space. */
if (target_space == EVAS_3D_SPACE_LOCAL)
{
ERR("TODO:");
return;
}
else if (target_space == EVAS_3D_SPACE_PARENT)
{
evas_vec3_set(&target, tx, ty, tz);
}
else if (target_space == EVAS_3D_SPACE_WORLD)
{
ERR("TODO:");
return;
}
else
{
ERR("Invalid coordinate space.");
return;
}
if (up_space == EVAS_3D_SPACE_LOCAL)
{
evas_vec3_set(&up, ux, uy, uz);
//ERR("TODO:");
//return;
}
else if (up_space == EVAS_3D_SPACE_PARENT)
{
evas_vec3_set(&up, ux, uy, uz);
}
else if (up_space == EVAS_3D_SPACE_WORLD)
{
ERR("TODO:");
return;
}
else
{
ERR("Invalid coordinate space.");
return;
}
_look_at_set(pd, &target, &up);
eo_do(obj, evas_3d_object_change(EVAS_3D_STATE_NODE_TRANSFORM_ORIENTATION, NULL));
}
@ -1624,4 +1681,20 @@ _evas_3d_node_bounding_sphere_get(Eo *obj EINA_UNUSED, Evas_3D_Node_Data *pd, Ev
if (r) *r = pd->bsphere.radius;
}
EOLIAN static void
_evas_3d_node_billboard_target_set(Eo *obj EINA_UNUSED, Evas_3D_Node_Data *pd,
Eo *target)
{
if (pd->billboard_target != target)
{
pd->billboard_target = target;
eo_do(obj, evas_3d_object_change(EVAS_3D_STATE_NODE_PARENT_BILLBOARD, NULL));
}
}
EOLIAN static Evas_3D_Node *
_evas_3d_node_billboard_target_get(Eo *obj EINA_UNUSED, Evas_3D_Node_Data *pd)
{
return pd->billboard_target;
}
#include "canvas/evas_3d_node.eo.c"

View File

@ -576,6 +576,35 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
int frame; /*@ The animation frame number.*/
}
}
billboard_target {
set {
/*
Set behavior of node like billboard object.
@param node The given node.
@param billboard Pointer to target node for given node.
@ingroup Evas_3D_Node
*/
}
get {
/*
Get the target node for billboard object.
@param node The given node.
@return The pointer to target node for billboard object,
or @c NULL if there're none.
@see evas_3d_node_billboard_set()
@ingroup Evas_3D_Node
*/
}
values {
Eo *target; /*@ Target node.*/
}
}
}
implements {
Eo.Base.destructor;

View File

@ -209,6 +209,7 @@ struct _Evas_3D_Node
{
Eina_List *members;
Evas_3D_Node *parent;
Evas_3D_Node *billboard_target;
Evas_Vec3 position;
Evas_Vec4 orientation;