ephysics: support density

SVN revision: 77460
This commit is contained in:
Bruno Dilly 2012-10-04 22:39:29 +00:00
parent b52d2ed85e
commit 748cfbe2f4
3 changed files with 80 additions and 0 deletions

View File

@ -2698,6 +2698,47 @@ EAPI void ephysics_body_forces_clear(EPhysics_Body *body);
*/
EAPI void ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y);
/**
* @brief
* Set body's material density.
*
* The density of a material is its mass per unit volume. It will set the
* body mass considering its volume. While a density is set, resizing
* a body will always recalculate its mass.
*
* When a mass is explicitely set with @ref ephysics_body_mass_set(),
* the density will be unset.
*
* It's useful in cases where a specific material needs to be simulated,
* so its density can be set and ephysics will calcute the body's mass.
*
* By default, no density is set.
*
* @note The unit used for density is kilograms / meters ^ 3.
*
* @param body The body to has its material density set.
* @param density The @p body's material density, in kilograms / meters ^ 3.
*
* @see ephysics_body_density_get().
*
* @ingroup EPhysics_Body
*/
EAPI void ephysics_body_density_set(EPhysics_Body *body, double density);
/**
* @brief
* Get body's material density.
*
* @param body The physics body.
* @return the @p body material's density, in kilograms / meters ^ 3 or 0
* if no density is set.
*
* @see ephysics_body_density_set() for details.
*
* @ingroup EPhysics_Body
*/
EAPI double ephysics_body_density_get(const EPhysics_Body *body);
/**
* @}
*/

View File

@ -347,11 +347,21 @@ _ephysics_body_soft_body_constraints_rebuild(EPhysics_Body *body)
_ephysics_body_soft_body_points_distance_get(body, body->distances);
}
inline static double
_ephysics_body_volume_get(const EPhysics_Body *body)
{
btVector3 vector = body->collision_shape->getLocalScaling();
return vector.x() * vector.y() * vector.z();
}
static void
_ephysics_body_mass_set(EPhysics_Body *body, double mass)
{
btVector3 inertia(0, 0, 0);
if (body->density)
mass = body->density * _ephysics_body_volume_get(body);
if (body->soft_body)
body->soft_body->setTotalMass(mass);
else
@ -1408,6 +1418,7 @@ ephysics_body_mass_set(EPhysics_Body *body, double mass)
}
ephysics_world_lock_take(body->world);
body->density = 0;
_ephysics_body_mass_set(body, mass);
ephysics_world_lock_release(body->world);
}
@ -2012,6 +2023,33 @@ ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y)
if (y) *y = body->cm.y;
}
EAPI void
ephysics_body_density_set(EPhysics_Body *body, double density)
{
if (!body)
{
ERR("Can't set the density of a null body's material.");
return;
}
body->density = density;
ephysics_world_lock_take(body->world);
_ephysics_body_mass_set(body, 0);
ephysics_world_lock_release(body->world);
}
EAPI double
ephysics_body_density_get(const EPhysics_Body *body)
{
if (!body)
{
ERR("Can't get the density of a null body's material.");
return 0;
}
return body->density;
}
#ifdef __cplusplus
}
#endif

View File

@ -80,6 +80,7 @@ struct _EPhysics_Body {
Eina_List *collision_groups;
Eina_List *to_delete;
double mass;
double density;
struct {
double x;
double y;