forked from enlightenment/efl
ephysics: use multiple threads
Use a mainloop thread and one thread per world dedicated to simulation. It's using ecore threads, out of the pool. For now there are still some locks when trying to change physics elements properties while a simulation is going on, but soon it will have a queue of properties to be applied after a simulation step, so it won't lock. SVN revision: 77455
This commit is contained in:
parent
cfdd39c2d7
commit
9668304291
|
@ -602,7 +602,7 @@ EAPI void ephysics_world_render_geometry_get(const EPhysics_World *world, Evas_C
|
|||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_serialize(const EPhysics_World *world, const char *path);
|
||||
EAPI Eina_Bool ephysics_world_serialize(EPhysics_World *world, const char *path);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
|
|
@ -141,15 +141,18 @@ ephysics_body_collision_group_add(EPhysics_Body *body, const char *group)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
group_str = eina_stringshare_add(group);
|
||||
if (eina_list_data_find(body->collision_groups, group_str))
|
||||
{
|
||||
INF("Body already added to group: %s", group);
|
||||
eina_stringshare_del(group_str);
|
||||
ephysics_world_lock_release(body->world);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
body->collision_groups = eina_list_append(body->collision_groups, group_str);
|
||||
ephysics_world_lock_release(body->world);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -164,17 +167,20 @@ ephysics_body_collision_group_del(EPhysics_Body *body, const char *group)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
group_str = eina_stringshare_add(group);
|
||||
if (!eina_list_data_find(body->collision_groups, group_str))
|
||||
{
|
||||
INF("Body isn't part of group: %s", group);
|
||||
eina_stringshare_del(group_str);
|
||||
ephysics_world_lock_release(body->world);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
body->collision_groups = eina_list_remove(body->collision_groups, group_str);
|
||||
eina_stringshare_del(group_str);
|
||||
eina_stringshare_del(group_str);
|
||||
ephysics_world_lock_release(body->world);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -341,6 +347,24 @@ _ephysics_body_soft_body_constraints_rebuild(EPhysics_Body *body)
|
|||
_ephysics_body_soft_body_points_distance_get(body, body->distances);
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_body_mass_set(EPhysics_Body *body, double mass)
|
||||
{
|
||||
btVector3 inertia(0, 0, 0);
|
||||
|
||||
if (body->soft_body)
|
||||
body->soft_body->setTotalMass(mass);
|
||||
else
|
||||
{
|
||||
body->collision_shape->calculateLocalInertia(mass, inertia);
|
||||
body->rigid_body->setMassProps(mass, inertia);
|
||||
body->rigid_body->updateInertiaTensor();
|
||||
}
|
||||
|
||||
body->mass = mass;
|
||||
DBG("Body %p mass changed to %lf.", body, mass);
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
|
||||
{
|
||||
|
@ -360,7 +384,7 @@ _ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
|
|||
body->collision_shape->setLocalScaling(btVector3(sx, sy, 1));
|
||||
|
||||
if(!body->rigid_body->isStaticObject())
|
||||
ephysics_body_mass_set(body, ephysics_body_mass_get(body));
|
||||
_ephysics_body_mass_set(body, ephysics_body_mass_get(body));
|
||||
}
|
||||
|
||||
body->w = w;
|
||||
|
@ -429,7 +453,7 @@ _ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Eva
|
|||
body->rigid_body->proceedToTransform(trans);
|
||||
|
||||
if (!body->rigid_body->isStaticObject())
|
||||
ephysics_body_mass_set(body, ephysics_body_mass_get(body));
|
||||
_ephysics_body_mass_set(body, ephysics_body_mass_get(body));
|
||||
}
|
||||
|
||||
body->rigid_body->getMotionState()->setWorldTransform(trans);
|
||||
|
@ -480,7 +504,9 @@ _ephysics_body_evas_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *o
|
|||
return;
|
||||
|
||||
DBG("Resizing body %p to w=%i, h=%i", body, w, h);
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_resize(body, w, h);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -708,11 +734,20 @@ ephysics_body_soft_body_get(const EPhysics_Body *body)
|
|||
return body->soft_body;
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_body_soft_body_hardness_set(EPhysics_Body *body, double hardness)
|
||||
{
|
||||
btSoftBody *soft_body = body->soft_body;
|
||||
soft_body->m_cfg.kAHR = (hardness / 100) * 0.6;
|
||||
soft_body->m_materials[0]->m_kVST = (hardness / 100);
|
||||
soft_body->m_materials[0]->m_kLST = (hardness / 100);
|
||||
soft_body->m_materials[0]->m_kAST = (hardness / 100);
|
||||
DBG("Soft body %p hardness set to %lf.", body, hardness);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_soft_body_hardness_set(EPhysics_Body *body, double hardness)
|
||||
{
|
||||
btSoftBody *soft_body;
|
||||
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't set soft body's hardness, body is null.");
|
||||
|
@ -731,12 +766,9 @@ ephysics_body_soft_body_hardness_set(EPhysics_Body *body, double hardness)
|
|||
return;
|
||||
}
|
||||
|
||||
soft_body = body->soft_body;
|
||||
soft_body->m_cfg.kAHR = (hardness / 100) * 0.6;
|
||||
soft_body->m_materials[0]->m_kVST = (hardness / 100);
|
||||
soft_body->m_materials[0]->m_kLST = (hardness / 100);
|
||||
soft_body->m_materials[0]->m_kAST = (hardness / 100);
|
||||
DBG("Soft body hardness set.");
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_soft_body_hardness_set(body, hardness);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -775,7 +807,7 @@ _ephysics_body_soft_add(EPhysics_World *world, btCollisionShape *collision_shape
|
|||
body->soft_body->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
|
||||
body->soft_body->m_cfg.collisions += btSoftBody::fCollision::VF_SS;
|
||||
|
||||
ephysics_body_soft_body_hardness_set(body, 100);
|
||||
_ephysics_body_soft_body_hardness_set(body, 100);
|
||||
|
||||
body->rigid_body->setCollisionFlags(
|
||||
btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
|
@ -799,6 +831,7 @@ ephysics_body_soft_circle_add(EPhysics_World *world)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(world);
|
||||
shape = new btCylinderShapeZ(btVector3(0.25, 0.25, 0.25));
|
||||
if (!shape)
|
||||
{
|
||||
|
@ -836,6 +869,7 @@ ephysics_body_soft_circle_add(EPhysics_World *world)
|
|||
body->points_deform[3][1] = 3;
|
||||
body->points_deform[3][2] = 76;
|
||||
|
||||
ephysics_world_lock_release(world);
|
||||
return body;
|
||||
|
||||
no_body:
|
||||
|
@ -843,6 +877,7 @@ no_body:
|
|||
no_soft_body:
|
||||
delete shape;
|
||||
no_collision_shape:
|
||||
ephysics_world_lock_release(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -850,6 +885,7 @@ EAPI EPhysics_Body *
|
|||
ephysics_body_circle_add(EPhysics_World *world)
|
||||
{
|
||||
btCollisionShape *collision_shape;
|
||||
EPhysics_Body *body;
|
||||
|
||||
if (!world)
|
||||
{
|
||||
|
@ -864,7 +900,10 @@ ephysics_body_circle_add(EPhysics_World *world)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _ephysics_body_add(world, collision_shape, "circle", 0.5, 0.5);
|
||||
ephysics_world_lock_take(world);
|
||||
body = _ephysics_body_add(world, collision_shape, "circle", 0.5, 0.5);
|
||||
ephysics_world_lock_release(world);
|
||||
return body;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
|
@ -881,6 +920,7 @@ ephysics_body_soft_box_add(EPhysics_World *world)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(world);
|
||||
shape = new btBoxShape(btVector3(0.25, 0.25, 0.25));
|
||||
if (!shape)
|
||||
{
|
||||
|
@ -918,6 +958,7 @@ ephysics_body_soft_box_add(EPhysics_World *world)
|
|||
body->points_deform[3][1] = 62;
|
||||
body->points_deform[3][2] = 8;
|
||||
|
||||
ephysics_world_lock_release(world);
|
||||
return body;
|
||||
|
||||
no_body:
|
||||
|
@ -925,6 +966,7 @@ no_body:
|
|||
no_soft_body:
|
||||
delete shape;
|
||||
no_collision_shape:
|
||||
ephysics_world_lock_release(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -932,6 +974,7 @@ EAPI EPhysics_Body *
|
|||
ephysics_body_box_add(EPhysics_World *world)
|
||||
{
|
||||
btCollisionShape *collision_shape;
|
||||
EPhysics_Body *body;
|
||||
|
||||
if (!world)
|
||||
{
|
||||
|
@ -941,7 +984,10 @@ ephysics_body_box_add(EPhysics_World *world)
|
|||
|
||||
collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
|
||||
|
||||
return _ephysics_body_add(world, collision_shape, "box", 0.5, 0.5);
|
||||
ephysics_world_lock_take(world);
|
||||
body = _ephysics_body_add(world, collision_shape, "box", 0.5, 0.5);
|
||||
ephysics_world_lock_release(world);
|
||||
return body;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
|
@ -952,6 +998,7 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
|
|||
btAlignedObjectArray<btVector3> vertexes, planes;
|
||||
const Eina_Inlist *points;
|
||||
EPhysics_Point *point;
|
||||
EPhysics_Body *body;
|
||||
int array_size, i;
|
||||
btShapeHull *hull;
|
||||
btVector3 point3d;
|
||||
|
@ -1052,9 +1099,12 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return _ephysics_body_add(world, (btCollisionShape *)simplified_shape,
|
||||
ephysics_world_lock_take(world);
|
||||
body = _ephysics_body_add(world, (btCollisionShape *)simplified_shape,
|
||||
"generic", (cm_x - min_x) / range_x,
|
||||
1 - (cm_y - min_y) / range_y);
|
||||
ephysics_world_lock_release(world);
|
||||
return body;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1111,37 +1161,49 @@ _ephysics_body_boundary_add(EPhysics_World *world, EPhysics_World_Boundary bound
|
|||
EAPI EPhysics_Body *
|
||||
ephysics_body_top_boundary_add(EPhysics_World *world)
|
||||
{
|
||||
EPhysics_Body *body;
|
||||
Evas_Coord x, y, w;
|
||||
|
||||
ephysics_world_render_geometry_get(world, &x, &y, &w, NULL);
|
||||
return _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_TOP,
|
||||
0, y - 10, x + w, 10);
|
||||
body = _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_TOP,
|
||||
0, y - 10, x + w, 10);
|
||||
return body;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
ephysics_body_bottom_boundary_add(EPhysics_World *world)
|
||||
{
|
||||
Evas_Coord x, y, w, h;
|
||||
EPhysics_Body *body;
|
||||
|
||||
ephysics_world_render_geometry_get(world, &x, &y, &w, &h);
|
||||
return _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_BOTTOM,
|
||||
body = _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_BOTTOM,
|
||||
x, y + h, w, 10);
|
||||
return body;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
ephysics_body_left_boundary_add(EPhysics_World *world)
|
||||
{
|
||||
EPhysics_Body *body;
|
||||
Evas_Coord x, y, h;
|
||||
|
||||
ephysics_world_render_geometry_get(world, &x, &y, NULL, &h);
|
||||
return _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_LEFT,
|
||||
body = _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_LEFT,
|
||||
x - 10, 0, 10, y + h);
|
||||
return body;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Body *
|
||||
ephysics_body_right_boundary_add(EPhysics_World *world)
|
||||
{
|
||||
Evas_Coord x, y, w, h;
|
||||
EPhysics_Body *body;
|
||||
|
||||
ephysics_world_render_geometry_get(world, &x, &y, &w, &h);
|
||||
return _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_RIGHT,
|
||||
body = _ephysics_body_boundary_add(world, EPHYSICS_WORLD_BOUNDARY_RIGHT,
|
||||
x + w, 0, 10, y + h);
|
||||
return body;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1163,8 +1225,10 @@ ephysics_body_del(EPhysics_Body *body)
|
|||
}
|
||||
|
||||
if (body->deleted) return;
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->deleted = EINA_TRUE;
|
||||
ephysics_world_body_del(body->world, body);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1200,11 +1264,13 @@ ephysics_body_evas_object_set(EPhysics_Body *body, Evas_Object *evas_obj, Eina_B
|
|||
if (!use_obj_pos)
|
||||
return;
|
||||
|
||||
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESIZE,
|
||||
_ephysics_body_evas_obj_resize_cb, body);
|
||||
evas_object_geometry_get(body->evas_obj, &obj_x, &obj_y, &obj_w, &obj_h);
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_geometry_set(body, obj_x, obj_y, obj_w, obj_h,
|
||||
ephysics_world_rate_get(body->world));
|
||||
ephysics_world_lock_release(body->world);
|
||||
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_RESIZE,
|
||||
_ephysics_body_evas_obj_resize_cb, body);
|
||||
}
|
||||
|
||||
EAPI Evas_Object *
|
||||
|
@ -1258,8 +1324,10 @@ ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_geometry_set(body, x, y, w, h,
|
||||
ephysics_world_rate_get(body->world));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1277,7 +1345,9 @@ ephysics_body_resize(EPhysics_Body *body, Evas_Coord w, Evas_Coord h)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_resize(body, w, h);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1289,7 +1359,9 @@ ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_move(body, x, y);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1329,18 +1401,9 @@ ephysics_body_mass_set(EPhysics_Body *body, double mass)
|
|||
return;
|
||||
}
|
||||
|
||||
btVector3 inertia(0, 0, 0);
|
||||
if (body->soft_body)
|
||||
body->soft_body->setTotalMass(mass);
|
||||
else
|
||||
{
|
||||
body->collision_shape->calculateLocalInertia(mass, inertia);
|
||||
body->rigid_body->setMassProps(mass, inertia);
|
||||
body->rigid_body->updateInertiaTensor();
|
||||
}
|
||||
body->mass = mass;
|
||||
|
||||
DBG("Body %p mass changed to %lf.", body, mass);
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_mass_set(body, mass);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1394,8 +1457,10 @@ ephysics_body_angular_velocity_set(EPhysics_Body *body, double z)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setAngularVelocity(btVector3(0, 0, -z/RAD_TO_DEG));
|
||||
DBG("Angular velocity of body %p set to %lf", body, z);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1419,9 +1484,11 @@ ephysics_body_sleeping_threshold_set(EPhysics_Body *body, double linear_threshol
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
_ephysics_body_sleeping_threshold_set(body, linear_threshold,
|
||||
angular_threshold,
|
||||
ephysics_world_rate_get(body->world));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1452,8 +1519,10 @@ ephysics_body_stop(EPhysics_Body *body)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setLinearVelocity(btVector3(0, 0, 0));
|
||||
body->rigid_body->setAngularVelocity(btVector3(0, 0, 0));
|
||||
ephysics_world_lock_release(body->world);
|
||||
|
||||
DBG("Body %p stopped", body);
|
||||
}
|
||||
|
@ -1467,8 +1536,10 @@ ephysics_body_damping_set(EPhysics_Body *body, double linear_damping, double ang
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setDamping(btScalar(linear_damping),
|
||||
btScalar(angular_damping));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1594,7 +1665,10 @@ ephysics_body_restitution_set(EPhysics_Body *body, double restitution)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setRestitution(btScalar(restitution));
|
||||
DBG("Body %p restitution set to %lf", body, restitution);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1618,7 +1692,10 @@ ephysics_body_friction_set(EPhysics_Body *body, double friction)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setFriction(btScalar(friction));
|
||||
DBG("Body %p friction set to %lf", body, friction);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1658,8 +1735,10 @@ ephysics_body_central_impulse_apply(EPhysics_Body *body, double x, double y)
|
|||
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->activate(1);
|
||||
body->rigid_body->applyCentralImpulse(btVector3(x / rate, - y / rate, 0));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1675,10 +1754,12 @@ ephysics_body_impulse_apply(EPhysics_Body *body, double x, double y, Evas_Coord
|
|||
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->activate(1);
|
||||
body->rigid_body->applyImpulse(btVector3(x / rate, - y / rate, 0),
|
||||
btVector3((double) pos_x / rate,
|
||||
(double) pos_y / rate, 0));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1690,7 +1771,9 @@ ephysics_body_linear_movement_enable_set(EPhysics_Body *body, Eina_Bool enable_x
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->setLinearFactor(btVector3(!!enable_x, !!enable_y, 0));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1715,8 +1798,10 @@ ephysics_body_torque_impulse_apply(EPhysics_Body *body, double roll)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->activate(1);
|
||||
body->rigid_body->applyTorqueImpulse(btVector3(0, 0, -roll));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1728,10 +1813,12 @@ ephysics_body_rotation_on_z_axis_enable_set(EPhysics_Body *body, Eina_Bool enabl
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
if (!enable)
|
||||
body->rigid_body->setAngularFactor(btVector3(0, 0, 0));
|
||||
else
|
||||
body->rigid_body->setAngularFactor(btVector3(0, 0, 1));
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
@ -1777,6 +1864,7 @@ ephysics_body_rotation_set(EPhysics_Body *body, double rotation)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
body->rigid_body->activate(1);
|
||||
body->rigid_body->getMotionState()->getWorldTransform(trans);
|
||||
quat.setEuler(0, 0, -rotation / RAD_TO_DEG);
|
||||
|
@ -1789,6 +1877,7 @@ ephysics_body_rotation_set(EPhysics_Body *body, double rotation)
|
|||
body->rigid_body->getMotionState()->setWorldTransform(trans);
|
||||
|
||||
DBG("Body %p rotation set to %lf", body, rotation);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1826,10 +1915,12 @@ ephysics_body_central_force_apply(EPhysics_Body *body, double x, double y)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
ephysics_body_forces_apply(body);
|
||||
body->rigid_body->applyCentralForce(btVector3(x / rate, - y / rate, 0));
|
||||
_ephysics_body_forces_update(body);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1844,11 +1935,13 @@ ephysics_body_force_apply(EPhysics_Body *body, double x, double y, Evas_Coord po
|
|||
}
|
||||
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
ephysics_world_lock_take(body->world);
|
||||
ephysics_body_forces_apply(body);
|
||||
body->rigid_body->applyForce(btVector3(x / rate, - y / rate, 0),
|
||||
btVector3((double) pos_x / rate,
|
||||
(double) pos_y / rate, 0));
|
||||
_ephysics_body_forces_update(body);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1860,9 +1953,11 @@ ephysics_body_torque_apply(EPhysics_Body *body, double torque)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(body->world);
|
||||
ephysics_body_forces_apply(body);
|
||||
body->rigid_body->applyTorque(btVector3(0, 0, -torque));
|
||||
_ephysics_body_forces_update(body);
|
||||
ephysics_world_lock_release(body->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -56,7 +56,6 @@ _ephysics_constraint_p2p_set(EPhysics_Constraint *constraint, double rate)
|
|||
}
|
||||
|
||||
constraint->type = EPHYSICS_CONSTRAINT_P2P;
|
||||
constraint->world = ephysics_body_world_get(constraint->p2p.body1);
|
||||
ephysics_world_constraint_add(constraint->world, constraint,
|
||||
constraint->bt_constraint);
|
||||
|
||||
|
@ -127,6 +126,7 @@ ephysics_constraint_slider_add(EPhysics_Body *body)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(ephysics_body_world_get(body));
|
||||
trans.setIdentity();
|
||||
constraint->bt_constraint = new
|
||||
btGeneric6DofConstraint(*ephysics_body_rigid_body_get(body), trans,
|
||||
|
@ -145,6 +145,7 @@ ephysics_constraint_slider_add(EPhysics_Body *body)
|
|||
constraint->bt_constraint);
|
||||
|
||||
INF("Constraint added.");
|
||||
ephysics_world_lock_release(ephysics_body_world_get(body));
|
||||
return constraint;
|
||||
}
|
||||
|
||||
|
@ -163,9 +164,11 @@ ephysics_constraint_slider_linear_limit_set(EPhysics_Constraint *constraint, Eva
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(constraint->world);
|
||||
_ephysics_constraint_slider_linear_limit_set(
|
||||
constraint, left_x, under_y, right_x, above_y,
|
||||
ephysics_world_rate_get(constraint->world));
|
||||
ephysics_world_lock_release(constraint->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -219,11 +222,13 @@ ephysics_constraint_slider_angular_limit_set(EPhysics_Constraint *constraint, do
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(constraint->world);
|
||||
slider_constraint = (btGeneric6DofConstraint *)constraint->bt_constraint;
|
||||
slider_constraint->setAngularLowerLimit(btVector3(0, 0,
|
||||
-counter_clock_z/RAD_TO_DEG));
|
||||
slider_constraint->setAngularUpperLimit(btVector3(0, 0,
|
||||
clock_wise_z/RAD_TO_DEG));
|
||||
ephysics_world_lock_release(constraint->world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -284,6 +289,7 @@ ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
constraint->world = ephysics_body_world_get(body1);
|
||||
constraint->p2p.body1 = body1;
|
||||
constraint->p2p.body2 = body2;
|
||||
constraint->p2p.anchor_b1_x = anchor_b1_x;
|
||||
|
@ -291,11 +297,17 @@ ephysics_constraint_p2p_add(EPhysics_Body *body1, EPhysics_Body *body2, Evas_Coo
|
|||
constraint->p2p.anchor_b2_x = anchor_b2_x;
|
||||
constraint->p2p.anchor_b2_y = anchor_b2_y;
|
||||
|
||||
ephysics_world_lock_take(constraint->world);
|
||||
if (!_ephysics_constraint_p2p_set(
|
||||
constraint, ephysics_world_rate_get(ephysics_body_world_get(
|
||||
constraint->p2p.body1))))
|
||||
return NULL;
|
||||
{
|
||||
ephysics_world_lock_release(constraint->world);
|
||||
free(constraint);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ephysics_world_lock_release(constraint->world);
|
||||
INF("Constraint added.");
|
||||
return constraint;
|
||||
}
|
||||
|
@ -309,12 +321,14 @@ ephysics_constraint_del(EPhysics_Constraint *constraint)
|
|||
return;
|
||||
}
|
||||
|
||||
ephysics_world_lock_take(constraint->world);
|
||||
ephysics_world_constraint_del(constraint->world, constraint,
|
||||
constraint->bt_constraint);
|
||||
delete constraint->bt_constraint;
|
||||
free(constraint);
|
||||
|
||||
INF("Constraint deleted.");
|
||||
ephysics_world_lock_release(constraint->world);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ btSoftBody *ephysics_body_soft_body_get(const EPhysics_Body *body);
|
|||
void ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active);
|
||||
void ephysics_body_recalc(EPhysics_Body *body, double rate);
|
||||
void ephysics_body_forces_apply(EPhysics_Body *body);
|
||||
void ephysics_world_lock_take(EPhysics_World *world);
|
||||
void ephysics_world_lock_release(EPhysics_World *world);
|
||||
|
||||
/* Camera */
|
||||
EPhysics_Camera *ephysics_camera_add(EPhysics_World *world);
|
||||
|
|
|
@ -12,6 +12,16 @@ extern "C" {
|
|||
|
||||
#define DEFAULT_GRAVITY btVector3(0, -9.8, 0)
|
||||
|
||||
typedef struct _Simulation_Msg Simulation_Msg;
|
||||
|
||||
struct _Simulation_Msg {
|
||||
EPhysics_Body *body_0;
|
||||
EPhysics_Body *body_1;
|
||||
btVector3 pos_a;
|
||||
btVector3 pos_b;
|
||||
Eina_Bool tick:1;
|
||||
};
|
||||
|
||||
typedef struct _EPhysics_World_Callback EPhysics_World_Callback;
|
||||
|
||||
struct _EPhysics_World_Callback {
|
||||
|
@ -41,14 +51,18 @@ struct _EPhysics_World {
|
|||
Eina_List *to_delete;
|
||||
Eina_List *cb_to_delete;
|
||||
Eina_List *constraints;
|
||||
Ecore_Thread *simulation_th;
|
||||
Ecore_Thread *cur_th;
|
||||
int max_sub_steps;
|
||||
int walking;
|
||||
int cb_walking;
|
||||
int soft_body_ref;
|
||||
int pending_ticks;
|
||||
double last_update;
|
||||
double rate;
|
||||
double fixed_time_step;
|
||||
double max_sleeping_time;
|
||||
Eina_Lock mutex;
|
||||
Eina_Condition condition;
|
||||
Eina_Bool running:1;
|
||||
Eina_Bool active:1;
|
||||
Eina_Bool deleted:1;
|
||||
|
@ -57,6 +71,7 @@ struct _EPhysics_World {
|
|||
Eina_Bool outside_bottom:1;
|
||||
Eina_Bool outside_left:1;
|
||||
Eina_Bool outside_right:1;
|
||||
Eina_Bool pending_simulation:1;
|
||||
};
|
||||
|
||||
static int _ephysics_world_init_count = 0;
|
||||
|
@ -100,6 +115,14 @@ _ephysics_world_gravity_set(EPhysics_World *world, double gx, double gy, double
|
|||
world->world_info->m_gravity = gravity;
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_world_th_cancel(EPhysics_World *world)
|
||||
{
|
||||
_worlds = eina_inlist_remove(_worlds, EINA_INLIST_GET(world));
|
||||
if (!ecore_thread_cancel(world->simulation_th))
|
||||
eina_condition_signal(&world->condition);
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_world_event_callback_call(EPhysics_World *world, EPhysics_Callback_World_Type type, void *event_info)
|
||||
{
|
||||
|
@ -144,7 +167,7 @@ _ephysics_world_event_callback_del(EPhysics_World *world, EPhysics_World_Callbac
|
|||
}
|
||||
|
||||
static void
|
||||
_ephysics_world_tick_cb(btDynamicsWorld *dynamics_world, btScalar timeStep __UNUSED__)
|
||||
_ephysics_world_tick(btDynamicsWorld *dynamics_world)
|
||||
{
|
||||
Eina_Bool world_active, camera_moved, tx, ty;
|
||||
btCollisionObjectArray objects;
|
||||
|
@ -195,13 +218,41 @@ _ephysics_world_tick_cb(btDynamicsWorld *dynamics_world, btScalar timeStep __UNU
|
|||
world, EPHYSICS_CALLBACK_WORLD_CAMERA_MOVED, world->camera);
|
||||
}
|
||||
|
||||
|
||||
if (world->active == world_active) return;
|
||||
if (world->active == world_active) goto body_del;
|
||||
world->active = world_active;
|
||||
if (world_active) return;
|
||||
if (world_active) goto body_del;
|
||||
|
||||
_ephysics_world_event_callback_call(world, EPHYSICS_CALLBACK_WORLD_STOPPED,
|
||||
NULL);
|
||||
|
||||
body_del:
|
||||
world->pending_ticks--;
|
||||
if (!world->pending_ticks)
|
||||
{
|
||||
void *bd;
|
||||
EINA_LIST_FREE(world->to_delete, bd)
|
||||
ephysics_world_body_del(world, (EPhysics_Body*)bd);
|
||||
}
|
||||
|
||||
if ((world->pending_simulation) && (!world->pending_ticks))
|
||||
{
|
||||
world->pending_simulation = EINA_FALSE;
|
||||
eina_condition_signal(&world->condition);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ephysics_world_tick_cb(btDynamicsWorld *dynamics_world, btScalar timeStep __UNUSED__)
|
||||
{
|
||||
EPhysics_World *world;
|
||||
Simulation_Msg *msg;
|
||||
|
||||
msg = (Simulation_Msg *) calloc(1, sizeof(Simulation_Msg));
|
||||
msg->tick = EINA_TRUE;
|
||||
|
||||
world = (EPhysics_World *) dynamics_world->getWorldUserInfo();
|
||||
world->pending_ticks++;
|
||||
ecore_thread_feedback(world->cur_th, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -227,7 +278,7 @@ ephysics_world_body_del(EPhysics_World *world, EPhysics_Body *body)
|
|||
{
|
||||
EPhysics_Body *bd;
|
||||
|
||||
if (world->walking)
|
||||
if (world->pending_ticks)
|
||||
{
|
||||
world->to_delete = eina_list_append(world->to_delete, body);
|
||||
return EINA_FALSE;
|
||||
|
@ -255,8 +306,6 @@ _ephysics_world_free(EPhysics_World *world)
|
|||
EPhysics_Body *body;
|
||||
void *constraint;
|
||||
|
||||
_worlds = eina_inlist_remove(_worlds, EINA_INLIST_GET(world));
|
||||
|
||||
while (world->callbacks)
|
||||
{
|
||||
cb = EINA_INLIST_CONTAINER_GET(world->callbacks,
|
||||
|
@ -286,6 +335,9 @@ _ephysics_world_free(EPhysics_World *world)
|
|||
delete world->soft_solver;
|
||||
delete world->world_info;
|
||||
|
||||
eina_condition_free(&world->condition);
|
||||
eina_lock_free(&world->mutex);
|
||||
|
||||
free(world);
|
||||
INF("World %p deleted.", world);
|
||||
}
|
||||
|
@ -294,46 +346,24 @@ static Eina_Bool
|
|||
_simulate_worlds(void *data __UNUSED__)
|
||||
{
|
||||
EPhysics_World *world;
|
||||
void *wrld, *bd;
|
||||
void *wrld;
|
||||
|
||||
ephysics_init();
|
||||
_worlds_walking++;
|
||||
EINA_INLIST_FOREACH(_worlds, world)
|
||||
{
|
||||
double time_now, delta;
|
||||
EPhysics_Body *body;
|
||||
|
||||
if (!world->running)
|
||||
continue;
|
||||
|
||||
world->walking++;
|
||||
|
||||
EINA_INLIST_FOREACH(world->bodies, body)
|
||||
ephysics_body_forces_apply(body);
|
||||
|
||||
time_now = ecore_time_get();
|
||||
delta = time_now - world->last_update;
|
||||
world->last_update = time_now;
|
||||
|
||||
gDeactivationTime = world->max_sleeping_time;
|
||||
|
||||
if (world->soft_body_ref)
|
||||
if (world->pending_ticks)
|
||||
{
|
||||
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
|
||||
world->fixed_time_step);
|
||||
world->world_info->m_sparsesdf.GarbageCollect();
|
||||
world->pending_simulation = EINA_TRUE;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
((btDiscreteDynamicsWorld *)world->dynamics_world)->stepSimulation(
|
||||
delta, world->max_sub_steps, world->fixed_time_step);
|
||||
|
||||
world->walking--;
|
||||
world->pending_simulation = EINA_FALSE;
|
||||
|
||||
if (!world->walking)
|
||||
{
|
||||
EINA_LIST_FREE(world->to_delete, bd)
|
||||
ephysics_world_body_del(world, (EPhysics_Body*)bd);
|
||||
}
|
||||
eina_condition_signal(&world->condition);
|
||||
}
|
||||
_worlds_walking--;
|
||||
|
||||
|
@ -344,7 +374,7 @@ _simulate_worlds(void *data __UNUSED__)
|
|||
}
|
||||
|
||||
EINA_LIST_FREE(_worlds_to_delete, wrld)
|
||||
_ephysics_world_free((EPhysics_World *)wrld);
|
||||
_ephysics_world_th_cancel((EPhysics_World *)wrld);
|
||||
|
||||
ephysics_shutdown();
|
||||
|
||||
|
@ -356,6 +386,8 @@ _ephysics_world_contact_processed_cb(btManifoldPoint &cp, void *b0, void *b1)
|
|||
{
|
||||
btRigidBody *rigid_body_0, *rigid_body_1;
|
||||
EPhysics_Body *body_0, *body_1;
|
||||
EPhysics_World *world;
|
||||
Simulation_Msg *msg;
|
||||
|
||||
rigid_body_0 = (btRigidBody *) b0;
|
||||
rigid_body_1 = (btRigidBody *) b1;
|
||||
|
@ -363,8 +395,14 @@ _ephysics_world_contact_processed_cb(btManifoldPoint &cp, void *b0, void *b1)
|
|||
body_0 = (EPhysics_Body *) rigid_body_0->getUserPointer();
|
||||
body_1 = (EPhysics_Body *) rigid_body_1->getUserPointer();
|
||||
|
||||
ephysics_body_contact_processed(body_0, body_1, cp.getPositionWorldOnA());
|
||||
ephysics_body_contact_processed(body_1, body_0, cp.getPositionWorldOnB());
|
||||
world = ephysics_body_world_get(body_0);
|
||||
|
||||
msg = (Simulation_Msg *) calloc(1, sizeof(Simulation_Msg));
|
||||
msg->body_0 = body_0;
|
||||
msg->body_1 = body_1;
|
||||
msg->pos_a = cp.getPositionWorldOnA();
|
||||
msg->pos_b = cp.getPositionWorldOnB();
|
||||
ecore_thread_feedback(world->cur_th, msg);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -485,6 +523,85 @@ ephysics_world_boundary_get(const EPhysics_World *world, EPhysics_World_Boundary
|
|||
return world->boundaries[boundary];
|
||||
}
|
||||
|
||||
static void
|
||||
_th_simulate(void *data, Ecore_Thread *th)
|
||||
{
|
||||
EPhysics_World *world = (EPhysics_World *) data;
|
||||
|
||||
while (1)
|
||||
{
|
||||
double time_now, delta;
|
||||
EPhysics_Body *body;
|
||||
|
||||
eina_condition_wait(&world->condition);
|
||||
if (ecore_thread_check(th))
|
||||
{
|
||||
INF("Thread canceled by main loop thread");
|
||||
eina_lock_release(&world->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
world->pending_ticks++;
|
||||
world->cur_th = th;
|
||||
|
||||
EINA_INLIST_FOREACH(world->bodies, body)
|
||||
ephysics_body_forces_apply(body);
|
||||
|
||||
time_now = ecore_time_get();
|
||||
delta = time_now - world->last_update;
|
||||
world->last_update = time_now;
|
||||
|
||||
gDeactivationTime = world->max_sleeping_time;
|
||||
|
||||
if (world->soft_body_ref)
|
||||
{
|
||||
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
|
||||
world->fixed_time_step);
|
||||
world->world_info->m_sparsesdf.GarbageCollect();
|
||||
}
|
||||
else
|
||||
((btDiscreteDynamicsWorld *)world->dynamics_world)->stepSimulation(
|
||||
delta, world->max_sub_steps, world->fixed_time_step);
|
||||
|
||||
world->pending_ticks--;
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_th_msg_cb(void *data, Ecore_Thread *th __UNUSED__, void *msg_data)
|
||||
{
|
||||
EPhysics_World *world = (EPhysics_World *) data;
|
||||
Simulation_Msg *msg = (Simulation_Msg *) msg_data;
|
||||
|
||||
if (msg->tick)
|
||||
_ephysics_world_tick(world->dynamics_world);
|
||||
else
|
||||
{
|
||||
ephysics_body_contact_processed(msg->body_0, msg->body_1, msg->pos_a);
|
||||
ephysics_body_contact_processed(msg->body_1, msg->body_0, msg->pos_b);
|
||||
}
|
||||
free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_th_end_cb(void *data, Ecore_Thread *th)
|
||||
{
|
||||
EPhysics_World *world = (EPhysics_World *) data;
|
||||
INF("World %p simulation thread %p end", world, th);
|
||||
world->simulation_th = NULL;
|
||||
_ephysics_world_free(world);
|
||||
}
|
||||
|
||||
static void
|
||||
_th_cancel_cb(void *data, Ecore_Thread *th)
|
||||
{
|
||||
EPhysics_World *world = (EPhysics_World *) data;
|
||||
INF("World %p simulation thread %p canceled", world, th);
|
||||
world->simulation_th = NULL;
|
||||
_ephysics_world_free(world);
|
||||
}
|
||||
|
||||
EAPI EPhysics_World *
|
||||
ephysics_world_new(void)
|
||||
{
|
||||
|
@ -566,6 +683,15 @@ ephysics_world_new(void)
|
|||
ERR("Couldn't add world to worlds list.");
|
||||
goto no_list;
|
||||
}
|
||||
world->simulation_th = ecore_thread_feedback_run(
|
||||
_th_simulate, _th_msg_cb, _th_end_cb, _th_cancel_cb, world, EINA_TRUE);
|
||||
if (!world->simulation_th)
|
||||
{
|
||||
ERR("Failed to create simulation thread.");
|
||||
goto no_thread;
|
||||
}
|
||||
eina_lock_new(&world->mutex);
|
||||
eina_condition_new(&world->condition, &world->mutex);
|
||||
|
||||
world->dynamics_world->getSolverInfo().m_solverMode ^=
|
||||
EPHYSICS_WORLD_SOLVER_SIMD;
|
||||
|
@ -594,6 +720,8 @@ ephysics_world_new(void)
|
|||
INF("World %p added.", world);
|
||||
return world;
|
||||
|
||||
no_thread:
|
||||
_worlds = eina_inlist_remove(_worlds, EINA_INLIST_GET(world));
|
||||
no_list:
|
||||
delete world->world_info;
|
||||
no_world_info:
|
||||
|
@ -616,7 +744,7 @@ no_camera:
|
|||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_serialize(const EPhysics_World *world, const char *path)
|
||||
ephysics_world_serialize(EPhysics_World *world, const char *path)
|
||||
{
|
||||
btDefaultSerializer *serializer;
|
||||
FILE *file;
|
||||
|
@ -627,10 +755,13 @@ ephysics_world_serialize(const EPhysics_World *world, const char *path)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
|
||||
file = fopen(path, "wb");
|
||||
if (!file)
|
||||
{
|
||||
WRN("Could not serialize, could not open file: %s", path);
|
||||
eina_lock_release(&world->mutex);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
@ -643,6 +774,7 @@ ephysics_world_serialize(const EPhysics_World *world, const char *path)
|
|||
WRN("Problems on writing to: %s.", path);
|
||||
fclose(file);
|
||||
delete serializer;
|
||||
eina_lock_release(&world->mutex);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
@ -651,44 +783,13 @@ ephysics_world_serialize(const EPhysics_World *world, const char *path)
|
|||
|
||||
INF("Serialization of world %p written to file: %s.", world, path);
|
||||
|
||||
eina_lock_release(&world->mutex);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_del(EPhysics_World *world)
|
||||
static void
|
||||
_ephysics_world_running_set(EPhysics_World *world, Eina_Bool running)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't delete world, it wasn't provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->deleted) return;
|
||||
|
||||
world->deleted = EINA_TRUE;
|
||||
_ephysics_world_event_callback_call(world, EPHYSICS_CALLBACK_WORLD_DEL,
|
||||
NULL);
|
||||
ephysics_world_running_set(world, EINA_FALSE);
|
||||
|
||||
if (_worlds_walking > 0)
|
||||
{
|
||||
_worlds_to_delete = eina_list_append(_worlds_to_delete, world);
|
||||
INF("World %p marked to delete.", world);
|
||||
return;
|
||||
}
|
||||
|
||||
_ephysics_world_free(world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_running_set(EPhysics_World *world, Eina_Bool running)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't (un)pause world, it wasn't provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!!running) == world->running) return;
|
||||
|
||||
world->running = !!running;
|
||||
|
@ -721,6 +822,50 @@ ephysics_world_running_set(EPhysics_World *world, Eina_Bool running)
|
|||
_anim_simulate = ecore_animator_add(_simulate_worlds, NULL);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_del(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't delete world, it wasn't provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->deleted) return;
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
|
||||
world->deleted = EINA_TRUE;
|
||||
_ephysics_world_event_callback_call(world, EPHYSICS_CALLBACK_WORLD_DEL,
|
||||
NULL);
|
||||
_ephysics_world_running_set(world, EINA_FALSE);
|
||||
|
||||
if (_worlds_walking > 0)
|
||||
{
|
||||
_worlds_to_delete = eina_list_append(_worlds_to_delete, world);
|
||||
INF("World %p marked to delete.", world);
|
||||
eina_lock_release(&world->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
eina_lock_release(&world->mutex);
|
||||
_ephysics_world_th_cancel(world);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_running_set(EPhysics_World *world, Eina_Bool running)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("Can't (un)pause world, it wasn't provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
_ephysics_world_running_set(world, running);
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_running_get(const EPhysics_World *world)
|
||||
{
|
||||
|
@ -742,7 +887,9 @@ ephysics_world_max_sleeping_time_set(EPhysics_World *world, double sleeping_time
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
world->max_sleeping_time = sleeping_time;
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -766,8 +913,10 @@ ephysics_world_gravity_set(EPhysics_World *world, double gx, double gy)
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
_ephysics_world_gravity_set(world, gx, gy, world->rate);
|
||||
DBG("World %p gravity set to X:%lf, Y:%lf.", world, gx, gy);
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -779,7 +928,9 @@ ephysics_world_constraint_solver_iterations_set(EPhysics_World *world, int itera
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
world->dynamics_world->getSolverInfo().m_numIterations = iterations;
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
|
@ -804,10 +955,12 @@ ephysics_world_constraint_solver_mode_enable_set(EPhysics_World *world, EPhysics
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
current_solver_mode = world->dynamics_world->getSolverInfo().m_solverMode;
|
||||
if ((enable && !(current_solver_mode & solver_mode)) ||
|
||||
(!enable && (current_solver_mode & solver_mode)))
|
||||
world->dynamics_world->getSolverInfo().m_solverMode ^= solver_mode;
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
@ -860,6 +1013,7 @@ ephysics_world_rate_set(EPhysics_World *world, double rate)
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
/* Force to recalculate sizes, velocities and accelerations with new rate */
|
||||
ephysics_world_gravity_get(world, &gx, &gy);
|
||||
_ephysics_world_gravity_set(world, gx, gy, rate);
|
||||
|
@ -871,6 +1025,7 @@ ephysics_world_rate_set(EPhysics_World *world, double rate)
|
|||
ephysics_constraint_recalc((EPhysics_Constraint *)constraint, rate);
|
||||
|
||||
world->rate = rate;
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1050,7 +1205,9 @@ ephysics_world_linear_slop_set(EPhysics_World *world, double linear_slop)
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
world->dynamics_world->getSolverInfo().m_linearSlop = btScalar(linear_slop);
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI double
|
||||
|
@ -1202,11 +1359,13 @@ ephysics_world_simulation_set(EPhysics_World *world, double fixed_time_step, int
|
|||
return;
|
||||
}
|
||||
|
||||
eina_lock_take(&world->mutex);
|
||||
world->max_sub_steps = max_sub_steps;
|
||||
world->fixed_time_step = fixed_time_step;
|
||||
|
||||
DBG("World %p simulation set to fixed time step: %lf, max substeps:%i.",
|
||||
world, fixed_time_step, max_sub_steps);
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -1222,6 +1381,18 @@ ephysics_world_simulation_get(const EPhysics_World *world, double *fixed_time_st
|
|||
if (max_sub_steps) *max_sub_steps = world->max_sub_steps;
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_world_lock_take(EPhysics_World *world)
|
||||
{
|
||||
eina_lock_take(&world->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_world_lock_release(EPhysics_World *world)
|
||||
{
|
||||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue