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

View File

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

View File

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