ephysics_logo.c

# ephysics_logo.c

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Elementary.h>
#include <EPhysics.h>
#include <Evas.h>
#define WIDTH (512)
#define HEIGHT (384)
#define DEPTH (100)
#define FLOOR_Y (HEIGHT - 80)
#define SH_THRESHOLD (250)
#define SH_OFFSET_X (- 16)
#define OFFSET_X (90)
#define PADDING_X_1 (16)
#define PADDING_X_2 (12)
#define PADDING_X_3 (22)
#define E_THRESHOLD (WIDTH + 560)
#define LAYER_SHADOW (10)
#define LAYER_LETTER (20)
#define CENTER(total, item) (((total) - (item)) / 2)
#define LIMIT(val, op, ref) (((val) op (ref)) ? (val) : (ref));
#define PROP_GET(pos, min, max) (((min) + ((max) - (min)) * (pos)) / (max))
static void
_update_box_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info)
{
Evas_Object *image = event_info;
Evas_Object *shadow = evas_object_data_get(image, "shadow");
Evas_Object *light = evas_object_data_get(image, "light");
int x, y, w, h, floor_distance, alpha = 0;
/* modify the evas object according to the body */
ephysics_body_evas_object_update(body);
evas_object_geometry_get(image, &x, &y, &w, &h);
floor_distance = FLOOR_Y - h;
/* Bodies penetrates the ground slightly before bouncing. */
/* This is to be expected in realtime physics engines. */
// TODO BUG: should we move the object up by the difference????
//y = LIMIT(y, <=, floor_distance);
/* We should show the shadow when we're close enough to ground */
if (y > SH_THRESHOLD)
{
int sh_w, sh_h;
double pos_x;
evas_object_image_size_get(shadow, &sh_w, &sh_h);
/* shadow is darker with bigger y */
alpha = 255 * (y - SH_THRESHOLD) / (floor_distance - SH_THRESHOLD);
/* and with bigger x -- it's proportional to x / WIDTH, but varies
* from 100 to 255.
*/
pos_x = (double) x / (WIDTH - w);
alpha = alpha * PROP_GET(pos_x, 100, 255);
/* box shadow is not resized, just moved */
evas_object_move(shadow, x + CENTER(w, sh_w) + SH_OFFSET_X,
FLOOR_Y - sh_h + 2);
}
evas_object_color_set(shadow, alpha, alpha, alpha, alpha);
evas_object_move(light, x, y);
/* it's lighter with bigger y */
alpha = (y <= 0) ? 0 : y * 255 / floor_distance;
/* and with bigger x */
alpha = alpha * (x - OFFSET_X + 80) / (WIDTH - OFFSET_X);
evas_object_color_set(light, alpha, alpha, alpha, alpha);
}
static void
_update_circle_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info)
{
Evas_Object *image = event_info;
Evas_Object *shadow = evas_object_data_get(image, "shadow");
Evas_Object *light = evas_object_data_get(image, "light");
int x, y, w, h, sh_w, sh_h, alpha = 0;
const Evas_Map *map;
/* modify the evas object according to the body */
ephysics_body_evas_object_update(body);
evas_object_geometry_get(image, &x, &y, &w, &h);
evas_object_move(light, x, y);
alpha = x * 255 / (WIDTH - w);
evas_object_color_set(light, alpha, alpha, alpha, alpha);
/* use the same map from image to the light (rotate it) */
map = evas_object_map_get(image);
evas_object_map_set(light, map);
evas_object_map_enable_set(light, EINA_TRUE);
evas_object_image_size_get(shadow, &sh_w, &sh_h);
evas_object_move(shadow, x + CENTER(w, sh_w) + SH_OFFSET_X,
FLOOR_Y - sh_h + 2);
alpha = 127 + alpha / 2;
evas_object_color_set(shadow, alpha, alpha, alpha, alpha);
if (x > E_THRESHOLD)
ephysics_body_move(body, -w - 1, y, -15);
}
static void
_letter_add(Evas *evas, const char *letter, Evas_Object **image, Evas_Object **light, Evas_Object **shadow)
{
int w, h, sh_w, sh_h;
char buf[1024];
snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_shadow-%s.png", letter);
*shadow = evas_object_image_filled_add(evas);
evas_object_image_file_set(*shadow, buf, NULL);
evas_object_image_size_get(*shadow, &sh_w, &sh_h);
evas_object_resize(*shadow, sh_w, sh_h);
evas_object_color_set(*shadow, 0, 0, 0, 0);
evas_object_layer_set(*shadow, LAYER_SHADOW);
evas_object_show(*shadow);
snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_letter-%s.png", letter);
*image = evas_object_image_filled_add(evas);
evas_object_image_file_set(*image, buf, NULL);
evas_object_image_size_get(*image, &w, &h);
evas_object_resize(*image, w, h);
evas_object_layer_set(*image, LAYER_LETTER);
evas_object_show(*image);
snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_light-%s.png", letter);
*light = evas_object_image_filled_add(evas);
evas_object_image_file_set(*light, buf, NULL);
evas_object_resize(*light, w, h);
evas_object_layer_set(*light, LAYER_LETTER);
evas_object_show(*light);
/* allow easy access to shadow and light from the letter image */
evas_object_data_set(*image, "shadow", *shadow);
evas_object_data_set(*image, "light", *light);
}
static void
_letter_body_setup_common(EPhysics_Body *body, Evas_Object *view)
{
ephysics_body_evas_object_set(body, view, EINA_TRUE);
ephysics_body_mass_set(body, 1.2);
ephysics_body_restitution_set(body, 0.6);
ephysics_body_angular_movement_enable_set(body, EINA_FALSE, EINA_FALSE,
EINA_FALSE);
}
static EPhysics_Body *
_letter_body_box_add(EPhysics_World *world, Evas_Object *image)
{
EPhysics_Body *body = ephysics_body_box_add(world);
_letter_body_setup_common(body, image);
ephysics_body_event_callback_add
(body, EPHYSICS_CALLBACK_BODY_UPDATE, _update_box_cb, NULL);
return body;
}
static EPhysics_Body *
_letter_body_circle_add(EPhysics_World *world, Evas_Object *image)
{
EPhysics_Body *body = ephysics_body_cylinder_add(world);
_letter_body_setup_common(body, image);
ephysics_body_event_callback_add
(body, EPHYSICS_CALLBACK_BODY_UPDATE, _update_circle_cb, NULL);
return body;
}
EAPI_MAIN int
elm_main(int argc __UNUSED__, char **argv __UNUSED__)
{
Evas_Object *win, *bg, *image, *light, *shadow;
EPhysics_Body *ground_body, *letter_body;
EPhysics_World *world;
unsigned int i = 0;
int x, w, h, sh_w;
Evas *evas;
struct letter_desc {
const char *letter;
int padding;
} falling_letters[] = {
{"P", PADDING_X_1},
{"H", PADDING_X_1},
{"Y", PADDING_X_3},
{"S1", PADDING_X_2},
{"I", PADDING_X_2},
{"C", PADDING_X_3},
{"S2", 0}
};
if (!ephysics_init())
return - 1;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_add(NULL, "main", ELM_WIN_SPLASH);
elm_win_title_set(win, "EPhysics Logo");
elm_win_autodel_set(win, EINA_TRUE);
evas_object_show(win);
bg = elm_bg_add(win);
elm_bg_file_set(bg, PACKAGE_DATA_DIR "/logo_background.png", NULL);
elm_win_resize_object_add(win, bg);
evas_object_size_hint_min_set(bg, WIDTH, HEIGHT);
evas_object_size_hint_max_set(bg, WIDTH, HEIGHT);
evas_object_show(bg);
world = ephysics_world_new();
ephysics_world_render_geometry_set(world, 0, 0, -50, WIDTH, HEIGHT, DEPTH);
ground_body = ephysics_body_box_add(world);
ephysics_body_mass_set(ground_body, EPHYSICS_BODY_MASS_STATIC);
ephysics_body_geometry_set(ground_body, -100, FLOOR_Y, -15, WIDTH + 800, 10,
30);
ephysics_body_restitution_set(ground_body, 0.65);
ephysics_body_friction_set(ground_body, 0.8);
evas = evas_object_evas_get(win);
x = OFFSET_X;
for (i = 0; i < EINA_C_ARRAY_LENGTH(falling_letters); i++)
{
_letter_add(evas, falling_letters[i].letter, &image, &light, &shadow);
evas_object_image_size_get(shadow, &sh_w, NULL);
evas_object_image_size_get(image, &w, &h);
/* place image and light on top, above what the viewport can show */
evas_object_move(image, x, -h * (i + 1) - 50);
evas_object_move(light, x, -h * (i + 1) - 50);
/* place shadow below the hit-line: FLOOR_Y, centered at image */
evas_object_move(shadow, x + CENTER(w, sh_w), FLOOR_Y);
x += falling_letters[i].padding + w;
letter_body = _letter_body_box_add(world, image);
ephysics_body_friction_set(letter_body, 0.4);
}
/* E is a circle that comes rolling on the floor */
_letter_add(evas, "E", &image, &light, &shadow);
evas_object_color_set(shadow, 255, 255, 255, 255);
evas_object_image_size_get(shadow, &sh_w, NULL);
evas_object_image_size_get(image, &w, &h);
/* place image and light so they are above the floor,
* and to the left of viewport
*/
evas_object_move(image, -w - 1, FLOOR_Y - h + 1);
evas_object_move(light, -w - 1, FLOOR_Y - h + 1);
/* place the shadow below the hit-line: FLOOR_Y, centered at image */
evas_object_move(shadow, -w - 1 + CENTER(w, sh_w), FLOOR_Y);
letter_body = _letter_body_circle_add(world, image);
ephysics_body_friction_set(letter_body, 1);
ephysics_body_mass_set(letter_body, 1);
ephysics_body_angular_movement_enable_set(letter_body, EINA_FALSE,
EINA_FALSE, EINA_TRUE);
/* make the "E" logo get into the viewport by applying an horizontal force */
ephysics_body_central_impulse_apply(letter_body, 390, 0, 0);
elm_run();
ephysics_world_del(world);
ephysics_shutdown();
elm_shutdown();
return 0;
}
ELM_MAIN()
EPhysics.h
These routines are used for EPhysics library interaction.
ephysics_body_angular_movement_enable_set
EAPI void ephysics_body_angular_movement_enable_set(EPhysics_Body *body, Eina_Bool enable_x, Eina_Bool enable_y, Eina_Bool enable_z)
Enable or disable body's rotation on z axis.
ephysics_body_evas_object_set
EAPI void ephysics_body_evas_object_set(EPhysics_Body *body, Evas_Object *evas_obj, Eina_Bool use_obj_pos)
Set an evas object to a physics body.
EPHYSICS_BODY_MASS_STATIC
#define EPHYSICS_BODY_MASS_STATIC
Mass amount used to makes a body static.
Definition: EPhysics.h:2043
ephysics_body_evas_object_update
EAPI void ephysics_body_evas_object_update(EPhysics_Body *body)
Update the evas object associated to the body.
ephysics_body_restitution_set
EAPI void ephysics_body_restitution_set(EPhysics_Body *body, double restitution)
Set body's coefficient of restitution.
ephysics_body_geometry_set
EAPI void ephysics_body_geometry_set(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z, Evas_Coord w, Evas_Coord h, Evas_Coord d)
Set physics body geometry.
ephysics_body_central_impulse_apply
EAPI void ephysics_body_central_impulse_apply(EPhysics_Body *body, double x, double y, double z)
Apply an impulse on the center of a body.
ephysics_body_friction_set
EAPI void ephysics_body_friction_set(EPhysics_Body *body, double friction)
Set body's friction.
ephysics_body_mass_set
EAPI void ephysics_body_mass_set(EPhysics_Body *body, double mass)
Set body's mass.
ephysics_body_cylinder_add
EAPI EPhysics_Body * ephysics_body_cylinder_add(EPhysics_World *world)
Create a new cylinder physics body.
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_body_move
EAPI void ephysics_body_move(EPhysics_Body *body, Evas_Coord x, Evas_Coord y, Evas_Coord z)
Set physics body position.
EPhysics_Body
struct _EPhysics_Body EPhysics_Body
Body handle, represents an object on EPhysics world.
Definition: EPhysics.h:655
ephysics_body_box_add
EAPI EPhysics_Body * ephysics_body_box_add(EPhysics_World *world)
Create a new box physics body.
EPHYSICS_CALLBACK_BODY_UPDATE
@ EPHYSICS_CALLBACK_BODY_UPDATE
Body being updated.
Definition: EPhysics.h:2263
ephysics_world_new
EAPI EPhysics_World * ephysics_world_new(void)
Create a new physics world.
EPhysics_World
struct _EPhysics_World EPhysics_World
World handle, most basic type of EPhysics.
Definition: EPhysics.h:901
ephysics_world_del
EAPI void ephysics_world_del(EPhysics_World *world)
Deletes a physics world.
ephysics_world_render_geometry_set
EAPI void ephysics_world_render_geometry_set(EPhysics_World *world, Evas_Coord x, Evas_Coord y, Evas_Coord z, Evas_Coord w, Evas_Coord h, Evas_Coord d)
Set dimensions of rendered area to be take on account by default updates.
ephysics_shutdown
EAPI int ephysics_shutdown(void)
Shutdown EPhysics.
ephysics_init
EAPI int ephysics_init(void)
Initialize EPhysics.
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_C_ARRAY_LENGTH
#define EINA_C_ARRAY_LENGTH(arr)
Macro to return the array length of a standard c array.
Definition: eina_types.h:621
elm_bg_file_set
Eina_Bool elm_bg_file_set(Eo *obj, const char *file, const char *group)
Sets the file (image or edje collection) to give life for the background.
Definition: efl_ui_bg.c:188
elm_bg_add
Evas_Object * elm_bg_add(Evas_Object *parent)
Adds a new background to the parent.
Definition: efl_ui_bg.c:304
ELM_MAIN
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition: elm_general.h:556
elm_policy_set
Eina_Bool elm_policy_set(unsigned int policy, int value)
Set a new policy's value (for a given policy group/identifier).
Definition: elm_main.c:1380
elm_shutdown
int elm_shutdown(void)
Shut down Elementary.
Definition: elm_main.c:467
elm_run
void elm_run(void)
Run Elementary's main loop.
Definition: elm_main.c:1357
ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
@ ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
quit when the application's last window is closed
Definition: elm_general.h:248
ELM_POLICY_QUIT
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition: elm_general.h:227
elm_win_title_set
void elm_win_title_set(Evas_Object *obj, const char *title)
Set the title of the window.
Definition: efl_ui_win.c:8636
elm_win_resize_object_add
void elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
Add subobj as a resize object of window obj.
Definition: efl_ui_win.c:8992
elm_win_autodel_set
void elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
Set the window's autodel state.
Definition: efl_ui_win.c:6189
elm_win_add
Evas_Object * elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
Adds a window object.
Definition: efl_ui_win.c:9544
ELM_WIN_SPLASH
@ ELM_WIN_SPLASH
Splash window for a starting up application.
Definition: elm_win_legacy.h:77
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition: Evas_Common.h:163
evas_object_show
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
evas_object_geometry_get
EVAS_API void evas_object_geometry_get(const Evas_Object *eo_obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
Retrieves the position and (rectangular) size of the given Evas object.
Definition: evas_object_main.c:1335
evas_object_color_set
EVAS_API void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a)
Sets the general/main color of the given Evas object to the given one.
Definition: evas_object_main.c:2024
evas_object_data_get
EVAS_API void * evas_object_data_get(const Evas_Object *obj, const char *key)
Return an attached data pointer on an Evas object by its given string key.
Definition: evas_data.c:12
evas_object_data_set
EVAS_API void evas_object_data_set(Evas_Object *eo_obj, const char *key, const void *data)
Set an attached data pointer to an object with a given string key.
Definition: evas_data.c:5
evas_object_map_get
EVAS_API const Evas_Map * evas_object_map_get(const Evas_Object *eo_obj)
Get current object transformation map.
Definition: evas_map.c:649
evas_object_move
EVAS_API void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
Move the given Evas object to the given location inside its canvas' viewport.
Definition: evas_object_main.c:1171
evas_object_layer_set
EVAS_API void evas_object_layer_set(Evas_Object *obj, short l)
Sets the layer of its canvas that the given object will be part of.
Definition: evas_layer.c:212
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition: Evas_Common.h:185
evas_object_size_hint_max_set
EVAS_API void evas_object_size_hint_max_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Sets the hints for an object's maximum size.
Definition: evas_object_main.c:2596
evas_object_resize
EVAS_API void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition: evas_object_main.c:1236
evas_object_map_set
EVAS_API void evas_object_map_set(Evas_Object *eo_obj, const Evas_Map *map)
Set current object transformation map.
Definition: evas_map.c:532
evas_object_evas_get
EVAS_API Evas * evas_object_evas_get(const Eo *eo_obj)
Get the Evas to which this object belongs to.
Definition: evas_object_main.c:2662
evas_object_size_hint_min_set
EVAS_API void evas_object_size_hint_min_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Sets the hints for an object's minimum size.
Definition: evas_object_main.c:2611
evas_object_map_enable_set
EVAS_API void evas_object_map_enable_set(Eo *eo_obj, Eina_Bool enabled)
Enable or disable the map that is set.
Definition: evas_map.c:516
evas_object_image_size_get
EVAS_API void evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
Retrieves the size of the given image object.
Definition: evas_image_legacy.c:159
evas_object_image_filled_add
EVAS_API Evas_Object * evas_object_image_filled_add(Evas *eo_e)
Creates a new image object that automatically scales its bound image to the object's area,...
Definition: evas_image_legacy.c:35
evas_object_image_file_set
EVAS_API void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
Set the source file from where an image object must fetch the real image data (it may be an Eet file,...
Definition: evas_image_legacy.c:194