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);
|
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);
|
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
|
void
|
||||||
ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
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)
|
if (!callback_called)
|
||||||
_ephysics_body_evas_object_default_update(body);
|
_ephysics_body_evas_object_default_update(body);
|
||||||
|
|
||||||
|
if (ephysics_world_bodies_outside_autodel_get(body->world))
|
||||||
|
_ephysics_body_outside_render_area_check(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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_body_world_boundaries_resize(EPhysics_World *world);
|
||||||
void ephysics_world_boundary_set(EPhysics_World *world, EPhysics_World_Boundary boundary, EPhysics_Body *body);
|
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);
|
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_body_evas_object_update_select(EPhysics_Body *body);
|
||||||
void ephysics_orphan_body_del(EPhysics_Body *body);
|
void ephysics_orphan_body_del(EPhysics_Body *body);
|
||||||
|
|
|
@ -35,6 +35,11 @@ struct _EPhysics_World {
|
||||||
double rate;
|
double rate;
|
||||||
Eina_Bool running:1;
|
Eina_Bool running:1;
|
||||||
Eina_Bool active: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;
|
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;
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue