From 81786a748ab48d1d2eac32edfd13418adbe2605b Mon Sep 17 00:00:00 2001 From: Leandro Dorileo Date: Wed, 12 Sep 2012 21:49:47 +0000 Subject: [PATCH] ephysics: fix issues with world destructor Makes sure the body is removed from the world before deleting it so it will not mess with overlapping pair caches, proxies and so on. Patch by: Leandro Dorileo SVN revision: 76562 --- legacy/ephysics/src/lib/ephysics_world.cpp | 89 +++++++++++----------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/legacy/ephysics/src/lib/ephysics_world.cpp b/legacy/ephysics/src/lib/ephysics_world.cpp index 507f85f0c8..5fa3470088 100644 --- a/legacy/ephysics/src/lib/ephysics_world.cpp +++ b/legacy/ephysics/src/lib/ephysics_world.cpp @@ -203,6 +203,50 @@ _ephysics_world_tick_cb(btDynamicsWorld *dynamics_world, btScalar timeStep __UNU NULL); } +static void +_ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body) +{ + btSoftBody *soft_body; + + world->dynamics_world->removeRigidBody(ephysics_body_rigid_body_get(body)); + + soft_body = ephysics_body_soft_body_get(body); + if (soft_body) + { + world->dynamics_world->removeSoftBody(soft_body); + --world->soft_body_ref; + } + + world->bodies = eina_inlist_remove(world->bodies, EINA_INLIST_GET(body)); + ephysics_orphan_body_del(body); +} + +Eina_Bool +ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body) +{ + EPhysics_Body *bd; + + if (world->walking) + { + world->to_delete = eina_list_append(world->to_delete, body); + return EINA_FALSE; + } + + _ephysics_world_body_del(world, body); + + /* Activate all the bodies after a body is deleted. + Otherwise it can lead to scenarios when a body 1, below body 2 is deleted + and body 2 will stay freezed in the air. Gravity won't start to + act over it until it's activated again. */ + EINA_INLIST_FOREACH(world->bodies, bd) + { + btRigidBody *rigid_body = ephysics_body_rigid_body_get(bd); + rigid_body->activate(1); + } + + return EINA_TRUE; +} + static void _ephysics_world_free(EPhysics_World *world) { @@ -224,17 +268,14 @@ _ephysics_world_free(EPhysics_World *world) while (world->bodies) { body = EINA_INLIST_CONTAINER_GET(world->bodies, EPhysics_Body); - world->bodies = eina_inlist_remove(world->bodies, world->bodies); - ephysics_orphan_body_del(body); + _ephysics_world_body_del(world, body); } EINA_LIST_FREE(world->constraints, constraint) ephysics_constraint_del((EPhysics_Constraint *)constraint); ephysics_camera_del(world->camera); - /* FIXME uncomment lines above when dynamicsworld destructor is fixed - on bullet. Right now looks like it will try to acess invalid memory.*/ - /* + delete world->dynamics_world; delete world->solver; delete world->broadphase; @@ -242,7 +283,6 @@ _ephysics_world_free(EPhysics_World *world) delete world->collision; delete world->soft_solver; delete world->world_info; - */ free(world); INF("World %p deleted.", world); @@ -359,43 +399,6 @@ ephysics_world_body_add(EPhysics_World *world, EPhysics_Body *body) return EINA_TRUE; } -Eina_Bool -ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body) -{ - btSoftBody *soft_body; - EPhysics_Body *bd; - - 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)); - - soft_body = ephysics_body_soft_body_get(body); - if (soft_body) - { - world->dynamics_world->removeSoftBody(soft_body); - --world->soft_body_ref; - } - - world->bodies = eina_inlist_remove(world->bodies, EINA_INLIST_GET(body)); - ephysics_orphan_body_del(body); - - /* Activate all the bodies after a body is deleted. - Otherwise it can lead to scenarios when a body 1, below body 2 is deleted - and body 2 will stay freezed in the air. Gravity won't start to - act over it until it's activated again. */ - EINA_INLIST_FOREACH(world->bodies, bd) - { - btRigidBody *rigid_body = ephysics_body_rigid_body_get(bd); - rigid_body->activate(1); - } - - return EINA_TRUE; -} - Eina_Bool ephysics_world_soft_body_add(EPhysics_World *world, EPhysics_Body *body) {