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;
double old_vx;
double old_vy;
double old_vaz;
double last_time;
};

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.

_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.

_update_vel_cb, velocity_data);

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;

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;

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);

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);
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.