EPhysics: properly handle body delete

SVN revision: 75141
This commit is contained in:
Bruno Dilly 2012-08-10 21:03:39 +00:00
parent 0bd1f327a4
commit 2d2844d05e
3 changed files with 42 additions and 19 deletions

View File

@ -289,9 +289,8 @@ _ephysics_body_outside_render_area_check(EPhysics_Body *body)
((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);
DBG("Body %p out of render area", body);
ephysics_body_del(body);
}
}
@ -415,7 +414,7 @@ ephysics_body_circle_add(EPhysics_World *world)
return NULL;
}
if (!ephysics_world_body_add(body->world, body, body->rigid_body))
if (!ephysics_world_body_add(body->world, body))
{
ERR("Couldn't add body to world's bodies list");
_ephysics_body_del(body);
@ -447,7 +446,7 @@ ephysics_body_box_add(EPhysics_World *world)
return NULL;
}
if (!ephysics_world_body_add(body->world, body, body->rigid_body))
if (!ephysics_world_body_add(body->world, body))
{
ERR("Couldn't add body to world's bodies list");
_ephysics_body_del(body);
@ -557,6 +556,7 @@ ephysics_orphan_body_del(EPhysics_Body *body)
}
_ephysics_body_del(body);
INF("Body %p deleted.", body);
}
EAPI void
@ -568,10 +568,9 @@ ephysics_body_del(EPhysics_Body *body)
return;
}
ephysics_world_body_del(body->world, body, body->rigid_body);
ephysics_orphan_body_del(body);
INF("Body %p deleted.", body);
if (body->deleted) return;
body->deleted = EINA_TRUE;
ephysics_world_body_del(body->world, body);
}
EAPI void

View File

@ -62,16 +62,17 @@ struct _EPhysics_Body {
void *data;
Eina_Inlist *callbacks;
double mass;
Eina_Bool active:1;
Eina_List *collision_groups;
Eina_Bool active:1;
Eina_Bool deleted:1;
};
extern int _ephysics_log_dom;
int ephysics_world_init(void);
int ephysics_world_shutdown(void);
Eina_Bool ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body, btRigidBody *rigid_body);
void ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body, btRigidBody *rigid_body);
Eina_Bool ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body);
Eina_Bool ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body);
void ephysics_world_constraint_add(EPhysics_World *world, btTypedConstraint *bt_constraint);
void ephysics_world_constraint_del(EPhysics_World *world, btTypedConstraint *bt_constraint);
void ephysics_body_world_boundaries_resize(EPhysics_World *world);

View File

@ -32,7 +32,9 @@ struct _EPhysics_World {
Evas_Coord x, y, w, h;
Eina_Inlist *callbacks;
Eina_Inlist *bodies;
Eina_List *to_delete;
int max_sub_steps;
int walking;
double last_update;
double rate;
double fixed_time_step;
@ -56,7 +58,8 @@ static int _worlds_walking = 0;
struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
{
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,
btBroadphaseProxy* proxy1) const
{
btCollisionObject *coll0 = (btCollisionObject *)proxy0->m_clientObject;
btCollisionObject *coll1 = (btCollisionObject *)proxy1->m_clientObject;
@ -168,7 +171,7 @@ _simulate_worlds(void *data)
Eina_Inlist *lworlds = (Eina_Inlist *) data;
EPhysics_World *world;
double time_now;
void *wrld;
void *wrld, *bd;
ephysics_init();
_worlds_walking++;
@ -179,6 +182,8 @@ _simulate_worlds(void *data)
if (!world->running)
continue;
world->walking++;
time_now = ecore_time_get();
delta = time_now - world->last_update;
world->last_update = time_now;
@ -186,6 +191,13 @@ _simulate_worlds(void *data)
gDeactivationTime = world->max_sleeping_time;
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
world->fixed_time_step);
world->walking--;
if (!world->walking)
{
EINA_LIST_FREE(world->to_delete, bd)
ephysics_world_body_del(world, (EPhysics_Body*)bd);
}
}
_worlds_walking--;
@ -238,7 +250,7 @@ _ephysics_world_boundary_del_cb(void *data, EPhysics_Body *body, void *event_inf
}
Eina_Bool
ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body, btRigidBody *rigid_body)
ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body)
{
world->bodies = eina_inlist_append(world->bodies,
EINA_INLIST_GET(body));
@ -247,16 +259,27 @@ ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body, btRigidBody
ERR("Couldn't add body to bodies list.");
return EINA_FALSE;
}
world->dynamics_world->addRigidBody(rigid_body);
world->dynamics_world->addRigidBody(ephysics_body_rigid_body_get(body));
return EINA_TRUE;
}
void
ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body, btRigidBody *rigid_body)
Eina_Bool
ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
{
world->dynamics_world->removeRigidBody(rigid_body);
if (world->walking)
{
world->to_delete = eina_list_append(world->to_delete, body);
return EINA_FALSE;
}
world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body));
world->bodies = eina_inlist_remove(world->bodies,
EINA_INLIST_GET(body));
ephysics_orphan_body_del(body);
return EINA_TRUE;
}
void