forked from enlightenment/efl
EPhysics: add forces API
Implement functions to make it possible to control forces acting over a body. SVN revision: 75476
This commit is contained in:
parent
4bccde902a
commit
218004c9e3
|
@ -2185,7 +2185,7 @@ EAPI void ephysics_body_torque_impulse_apply(EPhysics_Body *body, double roll);
|
|||
* or can be used to lead to both behaviors with
|
||||
* @ref ephysics_body_impulse_apply().
|
||||
*
|
||||
* It will resulte in a central impulse with impulse (@p x, @p y) and a
|
||||
* It will result in a central impulse with impulse (@p x, @p y) and a
|
||||
* torque impulse that will be calculated as a cross product on impulse
|
||||
* and relative position.
|
||||
*
|
||||
|
@ -2300,7 +2300,7 @@ EAPI double ephysics_body_rotation_get(const EPhysics_Body *body);
|
|||
* @note The unit used for rotation is degrees.
|
||||
*
|
||||
* @param body The physics body.
|
||||
* @param The amount of degrees @p body should be rotated.
|
||||
* @param rotation The amount of degrees @p body should be rotated.
|
||||
*
|
||||
* @see ephysics_body_rotation_get()
|
||||
*
|
||||
|
@ -2346,6 +2346,143 @@ EAPI void ephysics_body_data_set(EPhysics_Body *body, void *data);
|
|||
*/
|
||||
EAPI void *ephysics_body_data_get(const EPhysics_Body *body);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Apply a force on the center of a body.
|
||||
*
|
||||
* Applying a force to a body will lead it to change its velocity.
|
||||
*
|
||||
* Force is the product of mass and acceleration. So, keeping the mass
|
||||
* fixed, when force is applied acceleration will change, and consequently,
|
||||
* velocity will gradually be changes.
|
||||
*
|
||||
* Force = mass * acceleration
|
||||
*
|
||||
* Final velocity = initial velocity + acceleration * time
|
||||
*
|
||||
* While a force is applied, it will be acting over a body. It can be canceled
|
||||
* by applying an inverse force, or just calling
|
||||
* @ref ephysics_body_forces_clear().
|
||||
*
|
||||
* This force will be applied on body's center, so it won't implies in
|
||||
* changing angular acceleration. For that, it is possible to apply a torque
|
||||
* with @ref ephysics_body_torque_apply().
|
||||
*
|
||||
* If the force shouldn't be applied on body's center, it can be applied on
|
||||
* a relative point with @ref ephysics_body_force_apply().
|
||||
*
|
||||
* @note Force is measured in kg * p / s / s.
|
||||
*
|
||||
* @param body The physics body which over the force will be applied.
|
||||
* @param x The axis x component of force.
|
||||
* @param y The axis y component of force.
|
||||
*
|
||||
* @see ephysics_body_torque_apply().
|
||||
* @see ephysics_body_force_apply().
|
||||
* @see ephysics_body_forces_get().
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_central_force_apply(EPhysics_Body *body, double x, double y);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Apply a torque over a body.
|
||||
*
|
||||
* A torque will be applied over the @p body to change the angular acceleration
|
||||
* of this body. It will leads to a change on angular velocity over time.
|
||||
* And the body will rotate around Z axis considering this angular velocity.
|
||||
*
|
||||
* @param body The physics body that will receive the torque.
|
||||
* @param torque Torque to change angular acceleration of the body around Z
|
||||
* axis (rotate on x - y plane).
|
||||
* Negative values will accelerate it on anti clock rotation.
|
||||
*
|
||||
* @see ephysics_body_central_force_apply().
|
||||
* @see ephysics_body_force_apply().
|
||||
* @see ephysics_body_forces_get().
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_torque_apply(EPhysics_Body *body, double torque);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Apply a force over a body.
|
||||
*
|
||||
* A force will be applied over the body to change it's linear and angular
|
||||
* accelerations.
|
||||
*
|
||||
* It can be applied in the center of the body, avoiding affecting angular
|
||||
* acceleration, with @ref ephysics_body_central_force_apply(),
|
||||
* it can be applied only to change angular acceleration, with
|
||||
* @ref ephysics_body_torque_apply(), or can be used to lead to both
|
||||
* behaviors with @ref ephysics_body_force_apply().
|
||||
*
|
||||
* It will result in a central force with force (@p x, @p y) and a
|
||||
* torque that will be calculated as a cross product on force
|
||||
* and relative position.
|
||||
*
|
||||
* @param body The physics body that will receive the impulse.
|
||||
* @param x The axis x component of force.
|
||||
* @param y The axis y component of force.
|
||||
* @param pos_x The axis x component of the relative position to apply force.
|
||||
* @param pos_y The axis y component of the relative position to apply force.
|
||||
*
|
||||
* @note Force is measured in kg * p / s / s and position in p (pixels, or
|
||||
* Evas coordinates).
|
||||
*
|
||||
* @see ephysics_body_central_force_apply().
|
||||
* @see ephysics_body_torque_apply().
|
||||
* @see ephysics_body_forces_get().
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_force_apply(EPhysics_Body *body, double x, double y, Evas_Coord pos_x, Evas_Coord pos_y);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get physics body forces.
|
||||
*
|
||||
* Get all the forces applied over a body.
|
||||
*
|
||||
* @param body The physics body.
|
||||
* @param x The axis x component of total force.
|
||||
* @param y The axis y component of total force.
|
||||
* @param torque The torque.
|
||||
*
|
||||
* @see ephysics_body_force_apply() for more details.
|
||||
* @see ephysics_body_central_force_apply().
|
||||
* @see ephysics_body_torque_apply().
|
||||
* @see ephysics_body_forces_clear().
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_forces_get(const EPhysics_Body *body, double *x, double *y, double *torque);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Clear all the forces applied to a body.
|
||||
*
|
||||
* It will remove all the forces previously applied. So linear acceleration
|
||||
* and angular acceleration will be set to 0.
|
||||
*
|
||||
* It won't interfere with world's gravity, the body will continue to be
|
||||
* accelerated considering gravity.
|
||||
*
|
||||
* It won't affect damping.
|
||||
*
|
||||
* @param body The physics body that will have applied forces set to 0.
|
||||
*
|
||||
* @see ephysics_body_central_force_apply().
|
||||
* @see ephysics_body_torque_apply().
|
||||
* @see ephysics_body_force_apply().
|
||||
* @see ephysics_body_forces_get().
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_forces_clear(EPhysics_Body *body);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,15 @@ struct _EPhysics_Body_Collision {
|
|||
Evas_Coord y;
|
||||
};
|
||||
|
||||
static void
|
||||
_ephysics_body_forces_update(EPhysics_Body *body)
|
||||
{
|
||||
body->force.x = body->rigid_body->getTotalForce().getX();
|
||||
body->force.y = body->rigid_body->getTotalForce().getY();
|
||||
body->force.torque = body->rigid_body->getTotalTorque().getZ();
|
||||
body->rigid_body->clearForces();
|
||||
}
|
||||
|
||||
static inline void
|
||||
_ephysics_body_sleeping_threshold_set(EPhysics_Body *body, double linear_threshold, double angular_threshold, double rate)
|
||||
{
|
||||
|
@ -463,6 +472,16 @@ _ephysics_body_outside_render_area_check(EPhysics_Body *body)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_body_forces_apply(EPhysics_Body *body)
|
||||
{
|
||||
double rate = ephysics_world_rate_get(body->world);
|
||||
body->rigid_body->activate(1);
|
||||
body->rigid_body->applyCentralForce(btVector3(body->force.x / rate,
|
||||
body->force.y / rate, 0));
|
||||
body->rigid_body->applyTorque(btVector3(0, 0, body->force.torque));
|
||||
}
|
||||
|
||||
void
|
||||
ephysics_body_recalc(EPhysics_Body *body, double rate)
|
||||
{
|
||||
|
@ -1386,6 +1405,91 @@ ephysics_body_data_get(const EPhysics_Body *body)
|
|||
return body->data;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_central_force_apply(EPhysics_Body *body, double x, double y)
|
||||
{
|
||||
double rate;
|
||||
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't apply force to a null body.");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_force_apply(EPhysics_Body *body, double x, double y, Evas_Coord pos_x, Evas_Coord pos_y)
|
||||
{
|
||||
double rate;
|
||||
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't apply force to a null body.");
|
||||
return;
|
||||
}
|
||||
|
||||
rate = ephysics_world_rate_get(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);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_torque_apply(EPhysics_Body *body, double torque)
|
||||
{
|
||||
double rate;
|
||||
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't apply force to a null body.");
|
||||
return;
|
||||
}
|
||||
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
ephysics_body_forces_apply(body);
|
||||
body->rigid_body->applyTorque(btVector3(0, 0, -torque));
|
||||
_ephysics_body_forces_update(body);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_forces_get(const EPhysics_Body *body, double *x, double *y, double *torque)
|
||||
{
|
||||
double rate;
|
||||
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't get forces from a null body.");
|
||||
return;
|
||||
}
|
||||
|
||||
rate = ephysics_world_rate_get(body->world);
|
||||
|
||||
if (x) *x = body->force.x * rate;
|
||||
if (y) *y = body->force.y * rate;
|
||||
if (torque) *torque = -body->force.torque;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_forces_clear(EPhysics_Body *body)
|
||||
{
|
||||
if (!body)
|
||||
{
|
||||
ERR("Can't clear forces of a null body.");
|
||||
return;
|
||||
}
|
||||
|
||||
body->force.x = 0;
|
||||
body->force.y = 0;
|
||||
body->force.torque = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,11 @@ struct _EPhysics_Body {
|
|||
Eina_List *collision_groups;
|
||||
Eina_List *to_delete;
|
||||
double mass;
|
||||
struct {
|
||||
double x;
|
||||
double y;
|
||||
double torque;
|
||||
} force;
|
||||
Eina_Bool active:1;
|
||||
Eina_Bool deleted:1;
|
||||
};
|
||||
|
@ -101,6 +106,7 @@ void ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact
|
|||
btRigidBody *ephysics_body_rigid_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);
|
||||
|
||||
/* Camera */
|
||||
EPhysics_Camera *ephysics_camera_add(EPhysics_World *world);
|
||||
|
|
|
@ -245,12 +245,16 @@ _simulate_worlds(void *data)
|
|||
EINA_INLIST_FOREACH(lworlds, 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;
|
||||
|
|
Loading…
Reference in New Issue