EPhysics: restacking per layer

This patch fixes issues with restacking bodies in different evas
layers.


Patch by: Leandro Dorileo <dorileo@profusion.mobi>



SVN revision: 78681
This commit is contained in:
Leandro Dorileo 2012-10-30 18:31:52 +00:00 committed by Bruno Dilly
parent 36fbbb75d7
commit c6f4ab7643
1 changed files with 89 additions and 28 deletions

View File

@ -237,6 +237,8 @@ _ephysics_body_soft_body_slices_init(EPhysics_Body *body)
slice->evas_obj = evas_object_image_filled_add(evas); slice->evas_obj = evas_object_image_filled_add(evas);
evas_object_image_source_set(slice->evas_obj, evas_object_image_source_set(slice->evas_obj,
body->soft_data->base_obj); body->soft_data->base_obj);
evas_object_layer_set(slice->evas_obj,
evas_object_layer_get(body->soft_data->base_obj));
evas_object_resize(slice->evas_obj, 1, 1); evas_object_resize(slice->evas_obj, 1, 1);
evas_object_show(slice->evas_obj); evas_object_show(slice->evas_obj);
evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE); evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE);
@ -321,6 +323,7 @@ _ephysics_body_soft_body_evas_add(EPhysics_Body *body)
evas_object_resize(obj, w, h); evas_object_resize(obj, w, h);
evas_object_data_set(obj, BODY, body); evas_object_data_set(obj, BODY, body);
evas_object_show(obj); evas_object_show(obj);
evas_object_layer_set(obj, evas_object_layer_get(body->evas_obj));
body->evas_obj = obj; body->evas_obj = obj;
_ephysics_body_soft_body_slices_init(body); _ephysics_body_soft_body_slices_init(body);
@ -368,33 +371,84 @@ _ephysics_body_evas_stacking_sort_cb(const void *d1, const void *d2)
return 0; return 0;
} }
static void
_ephysics_body_evas_objects_restack_free(void *data)
{
Eina_List *l, *stack_list = (Eina_List *)data;
void *ldata;
EINA_LIST_FOREACH(stack_list, l, ldata)
free(ldata);
eina_list_free(stack_list);
}
static EPhysics_Body_Evas_Stacking *
_ephysics_body_evas_stacking_new(Evas_Object *obj, float index)
{
EPhysics_Body_Evas_Stacking *stacking;
stacking = (EPhysics_Body_Evas_Stacking *)calloc(
1, sizeof(EPhysics_Body_Evas_Stacking));
if (!stacking)
{
ERR("Could not allocate ephysics soft body evas stacking data.");
return NULL;
}
stacking->evas = obj;
stacking->stacking = index;
return stacking;
}
void void
ephysics_body_evas_objects_restack(EPhysics_World *world) ephysics_body_evas_objects_restack(EPhysics_World *world)
{ {
void *data, *slice_data; void *data, *slice_data, *stack_data;
EPhysics_Body *body; EPhysics_Body *body;
btTransform trans; btTransform trans;
EPhysics_Body_Evas_Stacking *stacking; EPhysics_Body_Evas_Stacking *stacking;
EPhysics_Body_Soft_Body_Slice *slice; EPhysics_Body_Soft_Body_Slice *slice;
Eina_List *l, *slices, *bodies, *stack_list = NULL; Eina_List *l, *slices, *bodies, *stack_list = NULL;
Evas_Object *prev_obj = NULL; Evas_Object *prev_obj = NULL;
Eina_Hash *hash;
Eina_Iterator *it;
int layer;
Eina_Bool previously_added;
bodies = ephysics_world_bodies_get(world); bodies = ephysics_world_bodies_get(world);
if (!eina_list_count(bodies))
return;
hash = eina_hash_int32_new(_ephysics_body_evas_objects_restack_free);
EINA_LIST_FOREACH(bodies, l, data) EINA_LIST_FOREACH(bodies, l, data)
{ {
body = (EPhysics_Body *)data; body = (EPhysics_Body *)data;
if (body->deleted) continue; if (body->deleted) continue;
previously_added = EINA_FALSE;
if (body->type == EPHYSICS_BODY_TYPE_RIGID) if (body->type == EPHYSICS_BODY_TYPE_RIGID)
{ {
if (!body->evas_obj) continue; if (!body->evas_obj) continue;
trans = _ephysics_body_transform_get(body); trans = _ephysics_body_transform_get(body);
stacking = (EPhysics_Body_Evas_Stacking *)calloc( stacking = _ephysics_body_evas_stacking_new(body->evas_obj,
1, sizeof(EPhysics_Body_Evas_Stacking)); trans.getOrigin().z());
if (!stacking) goto error; if (!stacking) goto error;
stacking->stacking = trans.getOrigin().z();
stacking->evas = body->evas_obj; layer = evas_object_layer_get(stacking->evas);
stack_list = (Eina_List *)eina_hash_find(hash, &layer);
if (stack_list)
previously_added = EINA_TRUE;
stack_list = eina_list_append(stack_list, stacking); stack_list = eina_list_append(stack_list, stacking);
if (!previously_added)
eina_hash_add(hash, &layer, stack_list);
continue; continue;
} }
@ -402,46 +456,53 @@ ephysics_body_evas_objects_restack(EPhysics_World *world)
EINA_LIST_FOREACH(body->soft_data->slices, slices, slice_data) EINA_LIST_FOREACH(body->soft_data->slices, slices, slice_data)
{ {
previously_added = EINA_FALSE;
slice = (EPhysics_Body_Soft_Body_Slice *)slice_data; slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
stacking = (EPhysics_Body_Evas_Stacking *)calloc(
1, sizeof(EPhysics_Body_Evas_Stacking)); stacking = _ephysics_body_evas_stacking_new(slice->evas_obj,
slice->stacking);
if (!stacking) goto error; if (!stacking) goto error;
stacking->stacking = slice->stacking;
stacking->evas = slice->evas_obj; layer = evas_object_layer_get(stacking->evas);
stack_list = (Eina_List *)eina_hash_find(hash, &layer);
if (stack_list)
previously_added = EINA_TRUE;
stack_list = eina_list_append(stack_list, stacking); stack_list = eina_list_append(stack_list, stacking);
if (!previously_added)
eina_hash_add(hash, &layer, stack_list);
} }
} }
stack_list = eina_list_sort(stack_list, eina_list_count(stack_list),
_ephysics_body_evas_stacking_sort_cb);
EINA_LIST_FREE(stack_list, data) it = eina_hash_iterator_data_new(hash);
while (eina_iterator_next(it, &data))
{ {
stacking = (EPhysics_Body_Evas_Stacking *)data; stack_list = (Eina_List *)data;
stack_list = eina_list_sort(stack_list, eina_list_count(stack_list),
_ephysics_body_evas_stacking_sort_cb);
prev_obj = NULL;
if (prev_obj && evas_object_layer_get(prev_obj) != EINA_LIST_FOREACH(stack_list, l, stack_data)
evas_object_layer_get(stacking->evas))
{ {
INF("The world %p has bodies with associated evas objects on" stacking = (EPhysics_Body_Evas_Stacking *)stack_data;
" different layers, skipping the restaking for %p and %p",
world, prev_obj, stacking->evas); if (prev_obj)
free(stacking); evas_object_stack_below(stacking->evas, prev_obj);
continue;
prev_obj = stacking->evas;
} }
if (prev_obj)
evas_object_stack_below(stacking->evas, prev_obj);
prev_obj = stacking->evas;
free(stacking);
} }
eina_iterator_free(it);
eina_hash_free(hash);
return; return;
error: error:
ERR("Could not allocate evas stacking data memory."); ERR("Could not allocate evas stacking data memory.");
EINA_LIST_FREE(stack_list, data) eina_hash_free(hash);
free(data);
} }
static void static void