EPhysics: soft body operations on triangles list

This patch introduces API to get a list of triangles inside an
area and another to apply impulse - also - in a list of triangles.


Patch by: Leandro Dorileo <dorileo@profusion.mobi>



SVN revision: 79607
This commit is contained in:
Leandro Dorileo 2012-11-23 21:52:08 +00:00 committed by Bruno Dilly
parent 889ba8d307
commit 1a1adc1a5f
2 changed files with 160 additions and 12 deletions

View File

@ -2426,6 +2426,35 @@ EAPI int ephysics_body_soft_body_slice_index_get(EPhysics_Body *body, Evas_Objec
*/
EAPI EPhysics_Body *ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int granularity);
/**
* @brief
* Get a list of triangles indexes inside an area.
*
* Get a list of triangles indexes given an area defined by @p x, @p y, @p z, @p
* w, @p h and @p d, the z axis components are represented by @p x and @p d
* where all triangles between @p z and @p d are considered, that's triangles
* with their z component greater than @p z and smaller than @p d.
*
* @note EPhysics will not free the returned list, remember to do so.
*
* @param body The body to get triangles indexes from.
* @param x The x component.
* @param y The y component.
* @param z The z component.
* @param w The w component.
* @param h The h component.
* @param d The d component.
*
* @return NULL on errors or no triangles found, a list of triangles indexes
* otherwhise.
*
* @see ephysics_body_soft_body_triangle_index_get().
* @see ephysics_body_soft_body_slice_index_get().
*
* @ingroup EPhysics_Body
*/
EAPI Eina_List *ephysics_body_soft_body_triangles_inside_get(const EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z, Evas_Coord w, Evas_Coord h, Evas_Coord d);
/**
* @brief
* Apply an impulse on a given soft body triangle.
@ -2453,6 +2482,27 @@ EAPI EPhysics_Body *ephysics_body_soft_ellipsoid_add(EPhysics_World *world, int
*/
EAPI void ephysics_body_soft_body_triangle_impulse_apply(EPhysics_Body * body, int idx, double x, double y, double z);
/**
* @brief
* Apply impulse in a list of triangles.
*
* Apply impulse in a list of triangles all at once considering the same impulse
* values on @p x, @p y and @p z.
*
* @param body The body to apply impulse.
* @param triangles A list of triangles indexes.
* @param x The axis @p x component of impulse.
* @param y The axis @p y component of impulse.
* @param z The axis @p z component of impulse.
*
* @see ephysics_body_soft_body_triangle_impulse_apply() to see about impulse
* applying on soft bodies.
* @see ephysics_body_soft_body_triangles_inside_get().
*
* @ingroup EPhysics_Body
*/
EAPI void ephysics_body_soft_body_triangle_list_impulse_apply(EPhysics_Body *body, Eina_List *triangles, double x, double y, double z);
/**
* @brief
* Set the soft body number of position iterations.

View File

@ -2290,14 +2290,90 @@ ephysics_body_soft_body_triangle_move(EPhysics_Body *body, int idx, Evas_Coord x
ephysics_world_lock_release(body->world);
}
EAPI void
ephysics_body_soft_body_triangle_impulse_apply(EPhysics_Body * body, int idx, double x, double y, double z)
EAPI Eina_List *
ephysics_body_soft_body_triangles_inside_get(const EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z, Evas_Coord w, Evas_Coord h, Evas_Coord d)
{
Eina_List *face_list = NULL;
btSoftBody::Face *bt_face;
btSoftBody::Node *node;
int out, *idx;
btScalar nx, ny, nz, xx, yy, zz, dd, ww, hh;
Evas_Coord wy, wh;
double rate;
if (body->type == EPHYSICS_BODY_TYPE_RIGID)
{
ERR("Can't get triangle indexes, operation not permited to rigid"
" bodies.");
return NULL;
}
ephysics_world_lock_take(body->world);
rate = ephysics_world_rate_get(body->world);
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
NULL);
xx = x / rate;
yy = ((wh + wy) - y) / rate;
zz = z / rate;
dd = d / rate;
ww = w / rate;
hh = h / rate;
for (int m = 0; m < body->soft_body->m_faces.size(); m++)
{
out = 0;
bt_face = &body->soft_body->m_faces[m];
for (int n = 0; n < 3; n++)
{
node = bt_face->m_n[n];
nx = node->m_x.x();
ny = node->m_x.y();
nz = node->m_x.z();
if ((nz > zz || nz < dd) || (nx < xx || nx > xx + ww) ||
(ny > yy || ny < ny - hh))
out++;
}
if (!out)
{
idx = (int *)malloc(sizeof(int));
*idx = m;
face_list = eina_list_append(face_list, idx);
}
}
ephysics_world_lock_release(body->world);
return face_list;
}
static void
_ephysics_body_soft_body_triangle_impulse_apply(EPhysics_Body *body, int idx, double x, double y, double z)
{
btSoftBody::Face face;
btSoftBody::Node *node;
double rate;
btVector3 impulse;
rate = ephysics_world_rate_get(body->world);
impulse = btVector3(x / rate, y / rate, z / rate);
face = body->soft_body->m_faces[idx];
for (int i = 0; i < 3; i++)
{
node = face.m_n[i];
node->m_v += impulse * node->m_im;
}
DBG("Impulse applied to soft body node(%d): %lf, %lf, %lf", idx, impulse.x(),
impulse.y(), impulse.z());
}
EAPI void
ephysics_body_soft_body_triangle_impulse_apply(EPhysics_Body * body, int idx, double x, double y, double z)
{
if (body->type == EPHYSICS_BODY_TYPE_RIGID)
{
ERR("Can't apply impulse, operation not permited to rigid bodies.");
@ -2311,18 +2387,40 @@ ephysics_body_soft_body_triangle_impulse_apply(EPhysics_Body * body, int idx, do
return;
}
rate = ephysics_world_rate_get(body->world);
impulse = btVector3(x / rate, y / rate, z / rate);
ephysics_world_lock_take(body->world);
face = body->soft_body->m_faces[idx];
node = face.m_n[0];
node->m_f += impulse * node->m_im;
_ephysics_body_soft_body_triangle_impulse_apply(body, idx, x, y, z);
ephysics_world_lock_release(body->world);
}
EAPI void
ephysics_body_soft_body_triangle_list_impulse_apply(EPhysics_Body *body, Eina_List *triangles, double x, double y, double z)
{
Eina_List *l;
void *ldata;
int idx, faces_cnt;
if (body->type == EPHYSICS_BODY_TYPE_RIGID)
{
ERR("Can't apply impulse, operation not permited to rigid bodies.");
return;
}
faces_cnt = body->soft_body->m_faces.size();
ephysics_world_lock_take(body->world);
EINA_LIST_FOREACH(triangles, l, ldata)
{
idx = *(int *)ldata;
if (idx < 0 || idx >= faces_cnt)
{
INF("Could not apply impulse to triangle %d, provided body"
" triangle index ranges from 0 to %d", idx, faces_cnt);
continue;
}
_ephysics_body_soft_body_triangle_impulse_apply(body, idx, x, y, z);
DBG("Applied impulse on body %p, triangle: %d", body, idx);
}
ephysics_world_lock_release(body->world);
DBG("Impulse applied to soft body node(%d): %lf, %lf, %lf", idx, impulse.x(),
impulse.y(), impulse.z());
}
EAPI int