EPhysics - Velocity

The purpose of this example is to demonstrate the EPhysics Velocity usage - The code adds a small bouncing ball on the ground and responding to users events by making it jump - applying a central impulse on it and showing its velocity and acceleration.

We'll see in this example how to get EPhysics_Body Linear and Angular velocity and acceleration.

For this example we'll have an EPhysics_World and one basic EPhysics_Body, we'll apply impulses that follows user events, it were already covered in EPhysics - Bouncing Ball

# Velocity Data Struct

While in this example we'll be working with a struct to hold some objects in our code. For clarity sake we present you the struct declaration in the following block.

struct _Velocity_Data {
Test_Data base;
EPhysics_Body *body;
double old_vx;
double old_vy;
double old_vaz;
double last_time;
};
EPhysics_Body
struct _EPhysics_Body EPhysics_Body
Body handle, represents an object on EPhysics world.
Definition: EPhysics.h:655

# Adding the Callbacks

Calling ephysics_body_event_callback_add() will register a callback to a type of physics body event.

EPHYSICS_CALLBACK_BODY_UPDATE : called after every physics iteration. In other words, will be called after each world tick.

ephysics_body_event_callback_add(sphere_body, EPHYSICS_CALLBACK_BODY_UPDATE,
ephysics_body_event_callback_add
EAPI void ephysics_body_event_callback_add(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func, const void *data)
Register a callback to a type of physics body event.
EPHYSICS_CALLBACK_BODY_UPDATE
@ EPHYSICS_CALLBACK_BODY_UPDATE
Body being updated.
Definition: EPhysics.h:2263
_update_vel_cb, velocity_data);

EPHYSICS_CALLBACK_BODY_STOPPED : called when a body is found to be stopped. In other words, when the body is not moving anymore.

ephysics_body_event_callback_add(sphere_body, EPHYSICS_CALLBACK_BODY_STOPPED,
_update_vel_cb, velocity_data);
EPHYSICS_CALLBACK_BODY_STOPPED
@ EPHYSICS_CALLBACK_BODY_STOPPED
Body is not moving any more.
Definition: EPhysics.h:2266

See _EPhysics_Callback_Body_Type for more event types.

# Velocity Function

The callback function will be called on every physics iteration to show the linear and angular velocity and acceleration.

Here we're declaring the necessary variables to calculate acelerations and delta time. And checking if its the first time to return before shows informations about the velocity.

_update_vel_cb(void *data, EPhysics_Body *body, void *event_info __UNUSED__)
{
Velocity_Data *velocity_data = data;
Eina_Bool first_call = EINA_FALSE;
double vx, vy, ax, ay, vaz, aaz;
double time_now, delta_time;
char buff[64];
if (!velocity_data->last_time)
first_call = EINA_TRUE;
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527

Get the delta time to use it soon to calculate the acceleration on every physics iteration.

time_now = ecore_time_get();
delta_time = time_now - velocity_data->last_time;
velocity_data->last_time = time_now;
ecore_time_get
double ecore_time_get(void)
Retrieves the current system time as a floating point value in seconds.
Definition: ecore_time.c:33

Note in this part we get the angular and linear velocities.

ephysics_body_angular_velocity_get(body, NULL, NULL, &vaz);
ephysics_body_linear_velocity_get(body, &vx, &vy, NULL);
ephysics_body_linear_velocity_get
EAPI void ephysics_body_linear_velocity_get(const EPhysics_Body *body, double *x, double *y, double *z)
Get body's linear velocity on x, y and z axes.
ephysics_body_angular_velocity_get
EAPI void ephysics_body_angular_velocity_get(const EPhysics_Body *body, double *x, double *y, double *z)
Get body's angular velocity on x, y and z axes.

We need to handle the velocity using delta time to have the acceleration on every tick. Check if its the first time to return before shows informations about the velocity because we don't have the old aceletations and then the calculation of this informations will be wrong.

Here we calculate the aceletarions using this formula:

(velocity - old_velocity) / delta_time;

aaz = (vaz - velocity_data->old_vaz) / delta_time;
velocity_data->old_vaz = vaz;
ax = (vx - velocity_data->old_vx) / delta_time;
velocity_data->old_vx = vx;
ay = (vy - velocity_data->old_vy) / delta_time;
velocity_data->old_vy = vy;
if (first_call) return;

Turning data into text, to pass it to edje shows on screen.

snprintf(buff, sizeof(buff), "Linear velocity: %.2f, %.2f", vx, vy);
elm_layout_text_set(velocity_data->base.layout, "linear_vel", buff);
snprintf(buff, sizeof(buff), "Linear acceleration: %.2f, %.2f", ax, ay);
elm_layout_text_set(velocity_data->base.layout, "linear_acc", buff);
elm_layout_text_set
Eina_Bool elm_layout_text_set(Eo *obj, const char *part, const char *text)
Set the text of the given part.
Definition: efl_ui_layout.c:3162
snprintf(buff, sizeof(buff), "Angular velocity: %.2f", vaz);
elm_layout_text_set(velocity_data->base.layout, "angular_vel", buff);
snprintf(buff, sizeof(buff), "Angular acceleration: %.2f", aaz);
elm_layout_text_set(velocity_data->base.layout, "angular_acc", buff);
}

Here we finish the example. The full source code can be found at test_velocity.c.