tutorial_ephysics_rotating_forever(3)

NAME
tutorial_ephysics_rotating_forever - EPhysics - Rotating Forever The purpose of this example is to demonstrate the EPhysics Rotate usage - The code applies different ways to rotate an EPhysics_Body, such as torque, torque impulse and rotation set.

For this example we'll have an EPhysics_World with gravity setted to zero, and four basic EPhysics_Bodys.

The basic concepts like - defining an EPhysics_World, render geometry, physics limiting boundaries, add an EPhysics_Body, associate it to evas objects, change restitution, friction and impulse properties, were already covered in EPhysics - Bouncing Ball

Rotating

For the first body we'll apply a torque impulse to make it rotate around Z axis (rotate on x-y plane). Will make the body rolls on clockwise rotation, if the value is negative, the impulse will be on counter clockwise.

   ephysics_body_torque_impulse_apply(body, 0, 0, 1);

 For the second body we'll use an offset to apply the force, the three last parameters are responsible to set a relative position to apply the force.In other words, the force applied with an offset will make the body rotates and move around the other cubes.

   ephysics_body_impulse_apply(body, 30, 0, 0, 0, -10, 0);

 For the third body we'll use a timer to rotate the body and a callback to delete it.

   timer = ecore_timer_add(1, _rotate_cb, body);
   ephysics_body_event_callback_add(body,
                                    EPHYSICS_CALLBACK_BODY_DEL,
                                    _del_cb, timer);

_del_cb(void *data, EPhysics_Body *body __UNUSED__, void *event_info __UNUSED__)
{
   ecore_timer_del(data);
}

 In the function we'll get the body rotation on z axis in degrees and handle it increasing 5 degrees on its position on z axis on each tick of the timer.

_rotate_cb(void *data)
{
   EPhysics_Quaternion *quat_prev, quat_delta, quat;
   EPhysics_Body *body = data;
   quat_prev = ephysics_body_rotation_get(body, NULL);
   ephysics_quaternion_set(&quat_delta, 0, 0, -0.15, 0.98);
   ephysics_quaternion_normalize(&quat_delta);
   ephysics_body_rotation_set(
      body, ephysics_quaternion_multiply(&quat_delta, quat_prev, &quat));
   free(quat_prev);
   return EINA_TRUE;
}

 For the forth body we'll use 2 timers, but before that, we'll apply an initial torque, changing the body angular acceleration and a callback to delete the timers we'll add.

   ephysics_body_torque_apply(body, 0, 0, 2);
   ephysics_body_event_callback_add(body,
                                    EPHYSICS_CALLBACK_BODY_DEL,

 Just the callback function to delete the timers.

_del_torque_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
   Ecore_Timer *timer;
   timer = evas_object_data_get(obj, "increase_timer");
   if (timer)
     ecore_timer_del(timer);
   timer = evas_object_data_get(obj, "stop_timer");
   if (timer)
     ecore_timer_del(timer);
}

 As we commented we'll use 2 timers, one to increase the torque and another to stop the torque, cleaning the forces related to the body.

   timer = ecore_timer_add(3, _increase_torque_cb, body);
   evas_object_data_set(cube, "increase_timer", timer);
   timer = ecore_timer_add(5, _stop_torque_cb, body);
   evas_object_data_set(cube, "stop_timer", timer);

 In the increase function we'll apply a torque over the body, changing its angular acceleration, it will leads to a change on angular velocity over time. We're using a timer to increase the angular acceleration on each tick of the timer.

_increase_torque_cb(void *data)
{
   EPhysics_Body *body = data;
   Evas_Object *obj;
   ephysics_body_torque_apply(body, 0, 0, 2);
   obj = ephysics_body_evas_object_get(body);
   evas_object_data_set(obj, "increase_timer", NULL);
   return EINA_FALSE;
}

 In the stop function we'll clear all the forces applied to the body, setting its linear and angular acceleration to zero. We're using this timer to 'control' the body velocity, since we are increasing it by another timer. Note that we set the acceleration to zero not the velocity.

_stop_torque_cb(void *data)
{
   EPhysics_Body *body = data;
   Evas_Object *obj;
   ephysics_body_forces_clear(body);
   obj = ephysics_body_evas_object_get(body);
   evas_object_data_set(obj, "stop_timer", NULL);
   return EINA_FALSE;
}

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