forked from enlightenment/efl
EPhysics: support autodel of bodies outside render area
Now it's possible to request a world to delete bodies outside render area, so we can save some resources and avoid issues with world stopped event. SVN revision: 73245
This commit is contained in:
parent
23523c9b70
commit
9d0b63143b
|
@ -621,6 +621,150 @@ EAPI void ephysics_world_linear_slop_set(EPhysics_World *world, double linear_sl
|
|||
*/
|
||||
EAPI double ephysics_world_linear_slop_get(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set world autodeleting bodies mode when they're outside of render area
|
||||
* by the top.
|
||||
*
|
||||
* It's useful when you don't care about bodies leaving the render
|
||||
* area set with @ref ephysics_world_render_area_set(), and don't think
|
||||
* they could / should return. So you can safely delete them and save resources.
|
||||
*
|
||||
* Also, it's useful if you have only a bottom border set with
|
||||
* @ref ephysics_body_top_boundary_add() and gravity set,
|
||||
* and want to listen for @ref EPHYSICS_CALLBACK_WORLD_STOPPED event.
|
||||
* If a body goes out of the render area, they will be acting by gravity
|
||||
* and won't collide to anything, so they could be moving forever and
|
||||
* world would never stop. For this case, enabling autodel for left and right
|
||||
* borders seems to be a good idea.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param autodel If @c EINA_TRUE delete bodies when they are outside render
|
||||
* area, otherwise, don't delete.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_top_autodel_get().
|
||||
* @see ephysics_world_bodies_outside_bottom_autodel_set().
|
||||
* @see ephysics_world_bodies_outside_left_autodel_set().
|
||||
* @see ephysics_world_bodies_outside_right_autodel_set().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_bodies_outside_top_autodel_set(EPhysics_World *world, Eina_Bool autodel);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get world autodeleting bodies mode when they're outside of render area by
|
||||
* the top.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @return @c EINA_TRUE if bodies will be deleted or @c EINA_FALSE if they
|
||||
* won't, or on error.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_top_autodel_set() for details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_bodies_outside_top_autodel_get(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set world autodeleting bodies mode when they're outside of render area
|
||||
* by the bottom.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param autodel If @c EINA_TRUE delete bodies when they are outside render
|
||||
* area, otherwise, don't delete.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_top_autodel_set() for more details.
|
||||
* @see ephysics_world_bodies_outside_bottom_autodel_get().
|
||||
* @see ephysics_world_bodies_outside_left_autodel_set().
|
||||
* @see ephysics_world_bodies_outside_right_autodel_set().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_bodies_outside_bottom_autodel_set(EPhysics_World *world, Eina_Bool autodel);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get world autodeleting bodies mode when they're outside of render area by
|
||||
* the bottom.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @return @c EINA_TRUE if bodies will be deleted or @c EINA_FALSE if they
|
||||
* won't, or on error.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_bottom_autodel_set() for details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_bodies_outside_bottom_autodel_get(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set world autodeleting bodies mode when they're outside of render area
|
||||
* by the right.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param autodel If @c EINA_TRUE delete bodies when they are outside render
|
||||
* area, otherwise, don't delete.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_top_autodel_set() for more details.
|
||||
* @see ephysics_world_bodies_outside_right_autodel_get().
|
||||
* @see ephysics_world_bodies_outside_bottom_autodel_set().
|
||||
* @see ephysics_world_bodies_outside_left_autodel_set().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_bodies_outside_right_autodel_set(EPhysics_World *world, Eina_Bool autodel);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get world autodeleting bodies mode when they're outside of render area by
|
||||
* the right.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @return @c EINA_TRUE if bodies will be deleted or @c EINA_FALSE if they
|
||||
* won't, or on error.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_right_autodel_set() for details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_bodies_outside_right_autodel_get(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set world autodeleting bodies mode when they're outside of render area
|
||||
* by the left.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param autodel If @c EINA_TRUE delete bodies when they are outside render
|
||||
* area, otherwise, don't delete.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_top_autodel_set() for more details.
|
||||
* @see ephysics_world_bodies_outside_left_autodel_get().
|
||||
* @see ephysics_world_bodies_outside_bottom_autodel_set().
|
||||
* @see ephysics_world_bodies_outside_right_autodel_set().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_bodies_outside_left_autodel_set(EPhysics_World *world, Eina_Bool autodel);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get world autodeleting bodies mode when they're outside of render area by
|
||||
* the left.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @return @c EINA_TRUE if bodies will be deleted or @c EINA_FALSE if they
|
||||
* won't, or on error.
|
||||
*
|
||||
* @see ephysics_world_bodies_outside_left_autodel_set() for details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_bodies_outside_left_autodel_get(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -186,6 +186,30 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
|||
evas_map_free(map);
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_body_outside_render_area_check(EPhysics_Body *body)
|
||||
{
|
||||
int wx, wy, ww, wh, bx, by, bw, bh;
|
||||
|
||||
ephysics_world_render_geometry_get(body->world, &wx, &wy, &ww, &wh);
|
||||
ephysics_body_geometry_get(body, &bx, &by, &bw, &bh);
|
||||
|
||||
// FIXME: check what should be done regarding rotated bodies
|
||||
if (((ephysics_world_bodies_outside_top_autodel_get(body->world)) &&
|
||||
(by + bh < wy)) ||
|
||||
((ephysics_world_bodies_outside_bottom_autodel_get(body->world)) &&
|
||||
(by > wy + wh)) ||
|
||||
((ephysics_world_bodies_outside_left_autodel_get(body->world)) &&
|
||||
(bx + bh < wx)) ||
|
||||
((ephysics_world_bodies_outside_right_autodel_get(body->world)) &&
|
||||
(bx > wx + ww)))
|
||||
{
|
||||
ephysics_world_body_del(body->world, body, body->rigid_body);
|
||||
ephysics_orphan_body_del(body);
|
||||
DBG("Body %p deleted. Out of render area", body);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
||||
{
|
||||
|
@ -205,6 +229,9 @@ ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
|||
|
||||
if (!callback_called)
|
||||
_ephysics_body_evas_object_default_update(body);
|
||||
|
||||
if (ephysics_world_bodies_outside_autodel_get(body->world))
|
||||
_ephysics_body_outside_render_area_check(body);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -62,6 +62,7 @@ void ephysics_world_constraint_del(EPhysics_World *world, btTypedConstraint *bt_
|
|||
void ephysics_body_world_boundaries_resize(EPhysics_World *world);
|
||||
void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary boundary, EPhysics_Body *body);
|
||||
EPhysics_Body *ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary boundary);
|
||||
Eina_Bool ephysics_world_bodies_outside_autodel_get(EPhysics_World *world);
|
||||
|
||||
void ephysics_body_evas_object_update_select(EPhysics_Body *body);
|
||||
void ephysics_orphan_body_del(EPhysics_Body *body);
|
||||
|
|
|
@ -35,6 +35,11 @@ struct _EPhysics_World {
|
|||
double rate;
|
||||
Eina_Bool running:1;
|
||||
Eina_Bool active:1;
|
||||
Eina_Bool outside_autodel:1;
|
||||
Eina_Bool outside_top:1;
|
||||
Eina_Bool outside_bottom:1;
|
||||
Eina_Bool outside_left:1;
|
||||
Eina_Bool outside_right:1;
|
||||
};
|
||||
|
||||
static int _ephysics_world_init_count = 0;
|
||||
|
@ -692,6 +697,122 @@ ephysics_world_linear_slop_get(EPhysics_World *world)
|
|||
return world->dynamics_world->getSolverInfo().m_linearSlop;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_bodies_outside_top_autodel_set(EPhysics_World *world, Eina_Bool autodel)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't set autodelete mode, world is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
world->outside_top = !!autodel;
|
||||
world->outside_autodel = world->outside_top || world->outside_bottom ||
|
||||
world->outside_left || world->outside_right;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_bodies_outside_top_autodel_get(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't get autodelete mode, world is null.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->outside_top;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_bodies_outside_bottom_autodel_set(EPhysics_World *world, Eina_Bool autodel)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't set autodelete mode, world is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
world->outside_bottom = !!autodel;
|
||||
world->outside_autodel = world->outside_top || world->outside_bottom ||
|
||||
world->outside_left || world->outside_right;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_bodies_outside_bottom_autodel_get(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't get autodelete mode, world is null.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->outside_bottom;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_bodies_outside_left_autodel_set(EPhysics_World *world, Eina_Bool autodel)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't set autodelete mode, world is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
world->outside_left = !!autodel;
|
||||
world->outside_autodel = world->outside_top || world->outside_bottom ||
|
||||
world->outside_left || world->outside_right;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_bodies_outside_left_autodel_get(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't get autodelete mode, world is null.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->outside_left;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_bodies_outside_right_autodel_set(EPhysics_World *world, Eina_Bool autodel)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't set autodelete mode, world is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
world->outside_right = !!autodel;
|
||||
world->outside_autodel = world->outside_top || world->outside_bottom ||
|
||||
world->outside_left || world->outside_right;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_bodies_outside_right_autodel_get(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't get autodelete mode, world is null.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->outside_right;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
ephysics_world_bodies_outside_autodel_get(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't get autodelete mode, world is null.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->outside_autodel;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue