test_camera_track.c

ephysics_test.h

#ifndef _EPHYSICS_PRIVATE_H
#define _EPHYSICS_PRIVATE_H
#include <Edje.h>
#include <Elementary.h>
#include <Eina.h>
#include <Evas.h>
#include "EPhysics.h"
#ifdef EPHYSICS_LOG_COLOR
#undef EPHYSICS_LOG_COLOR
#endif
#define EPHYSICS_LOG_COLOR EINA_COLOR_BLUE
#ifdef ERR
# undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_ephysics_test_log_dom, __VA_ARGS__)
#ifdef DBG
# undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_ephysics_test_log_dom, __VA_ARGS__)
#ifdef INF
# undef INF
#endif
#define INF(...) EINA_LOG_DOM_INFO(_ephysics_test_log_dom, __VA_ARGS__)
#ifdef WRN
# undef WRN
#endif
#define WRN(...) EINA_LOG_DOM_WARN(_ephysics_test_log_dom, __VA_ARGS__)
#ifdef CRI
# undef CRI
#endif
#define CRI(...) EINA_LOG_DOM_CRIT(_ephysics_test_log_dom, __VA_ARGS__)
#define EPHYSICS_TEST_THEME "ephysics_test"
#define WIDTH (512)
#define HEIGHT (384)
#define DEPTH (100)
#define SHADOW_ALPHA_ID (1)
#define FLOOR_Y (344)
#define FLOOR_WIDTH (750)
#define SH_THRESHOLD (200)
#ifdef __cplusplus
extern "C" {
#endif
extern int _ephysics_test_log_dom;
typedef struct _Test_Data Test_Data;
struct _Test_Data {
Evas_Object *layout;
Eina_List *constraints;
Eina_List *evas_objs;
Eina_List *bodies;
void *data;
};
Test_Data *test_data_new(void);
void test_data_del(Test_Data *test_data);
void test_clean(Test_Data *test_data);
void test_win_add(Test_Data *test_data, const char *title, Eina_Bool autodel);
void update_object_cb(void *data, EPhysics_Body *body, void *event_info);
#ifdef __cplusplus
}
#endif
#endif

test_camera_track.c

test_clean(Test_Data *test_data)
{
EPhysics_Constraint *constraint;
Evas_Object *evas_obj;
EINA_LIST_FREE(test_data->constraints, constraint)
EINA_LIST_FREE(test_data->bodies, body)
EINA_LIST_FREE(test_data->evas_objs, evas_obj)
evas_object_del(evas_obj);
}
test_win_add(Test_Data *test_data, const char *title, Eina_Bool autodel)
{
Evas_Object *win, *ly;
win = elm_win_add(NULL, title, ELM_WIN_BASIC);
elm_win_title_set(win, title);
test_data->win = win;
if (autodel)
_subwin_del_cb, test_data);
ly = elm_layout_add(win);
evas_object_size_hint_min_set(ly, WIDTH, HEIGHT);
evas_object_size_hint_max_set(ly, WIDTH, HEIGHT);
elm_layout_file_set(ly, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj",
"frame");
test_data->layout = ly;
}
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ephysics_test.h"
typedef struct _Track_Data Track_Data;
struct _Track_Data {
Test_Data base;
int old_cx;
};
static void
_update_floor(Evas_Object *layout, const char *name, int delta_x, int cy, Eina_Bool ver)
{
Evas_Object *floor_obj;
int x, y, fx, fy;
floor_obj = evas_object_data_get(layout, name);
evas_object_geometry_get(floor_obj, &x, &y, NULL, NULL);
fx = x + delta_x;
if (fx < -FLOOR_WIDTH)
fx += 2 * FLOOR_WIDTH;
fy = (ver) ? FLOOR_Y - 20 - cy + 40 : y;
evas_object_move(floor_obj, fx, fy);
}
static void
_camera_moved_cb(void *data, EPhysics_World *world __UNUSED__, void *event_info)
{
EPhysics_Camera *camera = event_info;
Track_Data *track_data = data;
int cx, cy, delta_x = 0;
Eina_Bool hor, ver;
DBG("Camera moved");
ephysics_camera_tracked_body_get(camera, NULL, &hor, &ver);
ephysics_camera_position_get(camera, &cx, &cy);
if (hor)
delta_x = track_data->old_cx - cx;
_update_floor(track_data->base.layout, "floor", delta_x, cy, ver);
_update_floor(track_data->base.layout, "floor2", delta_x, cy, ver);
track_data->old_cx = cx;
}
static void
_track_apply(Track_Data *track_data)
{
EPhysics_Camera *camera;
int mode;
body = track_data->body;
camera = ephysics_world_camera_get(track_data->base.world);
mode = (int) elm_spinner_value_get(track_data->sp);
switch (mode)
{
case 1:
hor = EINA_TRUE;
break;
case 3:
hor = EINA_TRUE;
case 2:
ver = EINA_TRUE;
}
INF("Tracking mode: hor = %i, ver = %i", hor, ver);
ephysics_camera_body_track(camera, body, hor, ver);
}
static void
_tracking_mode_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
_track_apply(data);
}
static void
_world_populate(Track_Data *track_data)
{
static const char *colors[] = {"blue-cube", "purple-cube"};
Evas_Object *cube, *sphere;
int i, color, row;
for (i = 0; i < 9; i++)
{
color = i % 3 % 2;
row = i / 3;
cube = elm_image_add(track_data->base.win);
cube, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj",
colors[color]);
evas_object_move(cube, i * 70, (row + 2) * 70);
evas_object_resize(cube, 70, 70);
track_data->base.evas_objs = eina_list_append(
track_data->base.evas_objs, cube);
body = ephysics_body_box_add(track_data->base.world);
track_data->base.bodies = eina_list_append(
track_data->base.bodies, body);
}
sphere = elm_image_add(track_data->base.win);
sphere, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "green-ball");
evas_object_move(sphere, 0, 80);
evas_object_resize(sphere, 54, 54);
track_data->base.evas_objs = eina_list_append(track_data->base.evas_objs,
sphere);
body = ephysics_body_sphere_add(track_data->base.world);
track_data->body = body;
track_data->base.bodies = eina_list_append(track_data->base.bodies, body);
}
static void
_restart(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Track_Data *track_data = data;
EPhysics_Camera *camera;
Evas_Object *floor_obj;
DBG("Restart pressed");
test_clean((Test_Data *)track_data);
_world_populate(track_data);
floor_obj = evas_object_data_get(track_data->base.layout, "floor");
evas_object_move(floor_obj, - WIDTH / 2, FLOOR_Y - 20);
floor_obj = evas_object_data_get(track_data->base.layout, "floor2");
evas_object_move(floor_obj, FLOOR_WIDTH - WIDTH / 2, FLOOR_Y - 20);
camera = ephysics_world_camera_get(track_data->base.world);
track_data->old_cx = 50;
_track_apply(track_data);
}
static void
_win_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Track_Data *track_data = data;
test_clean((Test_Data *)track_data);
evas_object_del(track_data->base.layout);
ephysics_world_del(track_data->base.world);
free(track_data);
}
void
test_camera_track(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
EPhysics_Body *boundary;
Evas_Object *sp, *floor_obj;
Track_Data *track_data;
if (!ephysics_init())
return;
track_data = calloc(1, sizeof(Track_Data));
if (!track_data)
{
ERR("Failed to create test data");
return;
}
test_win_add((Test_Data *) track_data, "Camera Track", EINA_FALSE);
_win_del, track_data);
elm_layout_signal_callback_add(track_data->base.layout, "restart",
"test-theme", _restart, track_data);
sp = elm_spinner_add(track_data->base.win);
elm_spinner_special_value_add(sp, 0, "No tracking");
elm_spinner_special_value_add(sp, 1, "Horizontal tracking");
elm_spinner_special_value_add(sp, 2, "Vertical tracking");
elm_spinner_special_value_add(sp, 3, "Full tracking");
elm_object_style_set(sp, "ephysics-test");
evas_object_smart_callback_add(sp, "delay,changed", _tracking_mode_cb,
track_data);
elm_layout_content_set(track_data->base.layout, "extra_input", sp);
track_data->sp = sp;
floor_obj = elm_image_add(track_data->base.win);
floor_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "floor");
evas_object_move(floor_obj, - WIDTH / 2, FLOOR_Y - 20);
evas_object_resize(floor_obj, FLOOR_WIDTH, 224);
evas_object_show(floor_obj);
evas_object_data_set(track_data->base.layout, "floor", floor_obj);
floor_obj = elm_image_add(track_data->base.win);
floor_obj, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "floor");
evas_object_move(floor_obj, FLOOR_WIDTH - WIDTH / 2, FLOOR_Y - 20);
evas_object_resize(floor_obj, FLOOR_WIDTH, 224);
evas_object_show(floor_obj);
evas_object_data_set(track_data->base.layout, "floor2", floor_obj);
world = ephysics_world_new();
WIDTH - 100, FLOOR_Y - 40, DEPTH);
track_data->base.world = world;
_camera_moved_cb, track_data);
boundary = ephysics_body_box_add(track_data->base.world);
ephysics_body_mass_set(boundary, 0);
ephysics_body_geometry_set(boundary, 0, FLOOR_Y, -15, WIDTH * 4, 10, 30);
track_data->old_cx = 50;
_world_populate(track_data);
}