1006 lines
35 KiB
C
1006 lines
35 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include<stdio.h>
|
|
#include<string.h>
|
|
#include<Eina.h>
|
|
#include<Elementary.h>
|
|
#include<EPhysics.h>
|
|
|
|
#define SANDBOX_THEME "ephysics_sandbox"
|
|
#define WIDTH (1280)
|
|
#define HEIGHT (720)
|
|
#define DEPTH (100)
|
|
#define INITIAL_MASS (15)
|
|
|
|
static const char *materials[] =
|
|
{
|
|
"Custom", "Concrete", "Iron", "Plastic", "Polystyrene", "Rubber", "Wood"
|
|
};
|
|
|
|
typedef struct _World_Data World_Data;
|
|
typedef struct _Body_Data Body_Data;
|
|
|
|
struct _World_Data {
|
|
EPhysics_Body *top, *bottom, *left, *right;
|
|
Evas_Object *win, *tb, *nf;
|
|
EPhysics_World *world;
|
|
Body_Data *bd1, *bd2;
|
|
};
|
|
|
|
struct _Body_Data {
|
|
World_Data *wd;
|
|
EPhysics_Body *body;
|
|
struct {
|
|
struct {
|
|
Evas_Object *x, *y, *relx, *rely;
|
|
}impulse;
|
|
struct {
|
|
Evas_Object *x, *y, *relx, *rely, *torque;
|
|
}force;
|
|
struct {
|
|
Evas_Object *x, *y, *angular;
|
|
}velocity;
|
|
Evas_Object *hardness;
|
|
}controls;
|
|
};
|
|
|
|
|
|
/*** Sandbox Callbacks ***/
|
|
static void
|
|
_body_del(void *data __UNUSED__, EPhysics_Body *body __UNUSED__,
|
|
void *event_info)
|
|
{
|
|
if (event_info) evas_object_del(event_info);
|
|
}
|
|
|
|
static void
|
|
_world_gravity_x_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
EPhysics_World *world = data;
|
|
double gravity_y, gravity_z;
|
|
|
|
ephysics_world_gravity_get(world, NULL, &gravity_y, &gravity_z);
|
|
ephysics_world_gravity_set(world, elm_slider_value_get(obj), gravity_y,
|
|
gravity_z);
|
|
}
|
|
|
|
static void
|
|
_world_gravity_y_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
EPhysics_World *world = data;
|
|
double gravity_x, gravity_z;
|
|
|
|
ephysics_world_gravity_get(world, &gravity_x, NULL, &gravity_z);
|
|
ephysics_world_gravity_set(world, gravity_x, elm_slider_value_get(obj),
|
|
gravity_z);
|
|
}
|
|
|
|
static void
|
|
_world_rate_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
EPhysics_World *world = data;
|
|
ephysics_world_rate_set(world, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_world_max_sleeping_time_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
EPhysics_World *world = data;
|
|
ephysics_world_max_sleeping_time_set(world, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_world_friction_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
World_Data *wd = data;
|
|
ephysics_body_friction_set(wd->top, elm_slider_value_get(obj));
|
|
ephysics_body_friction_set(wd->bottom, elm_slider_value_get(obj));
|
|
ephysics_body_friction_set(wd->left, elm_slider_value_get(obj));
|
|
ephysics_body_friction_set(wd->right, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_world_restitution_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
World_Data *wd = data;
|
|
ephysics_body_restitution_set(wd->top, elm_slider_value_get(obj));
|
|
ephysics_body_restitution_set(wd->bottom, elm_slider_value_get(obj));
|
|
ephysics_body_restitution_set(wd->left, elm_slider_value_get(obj));
|
|
ephysics_body_restitution_set(wd->right, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_type_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
double mass, friction, restitution, lin_damping, ang_damping;
|
|
double lin_sleeping, ang_sleeping;
|
|
EPhysics_Body_Material material;
|
|
EPhysics_Quaternion rotation;
|
|
Evas_Object *body_image;
|
|
EPhysics_World *world;
|
|
Body_Data *bd = data;
|
|
EPhysics_Body *body = bd->body;
|
|
|
|
mass = ephysics_body_mass_get(body);
|
|
ephysics_body_rotation_get(body, &rotation);
|
|
friction = ephysics_body_friction_get(body);
|
|
restitution = ephysics_body_restitution_get(body);
|
|
ephysics_body_damping_get(body, &lin_damping, &ang_damping);
|
|
ephysics_body_sleeping_threshold_get(body, &lin_sleeping, &ang_sleeping);
|
|
material = ephysics_body_material_get(body);
|
|
|
|
world = ephysics_body_world_get(body);
|
|
body_image = ephysics_body_evas_object_unset(body);
|
|
|
|
ephysics_body_del(body);
|
|
|
|
if (elm_radio_value_get(obj))
|
|
{
|
|
body = ephysics_body_soft_circle_add(world);
|
|
ephysics_body_soft_body_hardness_set(
|
|
body, elm_slider_value_get(bd->controls.hardness));
|
|
elm_object_disabled_set(bd->controls.hardness, EINA_FALSE);
|
|
}
|
|
else
|
|
{
|
|
body = ephysics_body_circle_add(world);
|
|
elm_object_disabled_set(bd->controls.hardness, EINA_TRUE);
|
|
}
|
|
|
|
ephysics_body_evas_object_set(body, body_image, EINA_TRUE);
|
|
ephysics_body_mass_set(body, mass);
|
|
ephysics_body_rotation_set(body, &rotation);
|
|
ephysics_body_friction_set(body, friction);
|
|
ephysics_body_restitution_set(body, restitution);
|
|
ephysics_body_damping_set(body, lin_damping, ang_damping);
|
|
ephysics_body_sleeping_threshold_set(body, lin_sleeping, ang_sleeping);
|
|
ephysics_body_material_set(body, material);
|
|
|
|
ephysics_body_force_apply(body,
|
|
elm_slider_value_get(bd->controls.force.x),
|
|
elm_slider_value_get(bd->controls.force.y), 0,
|
|
elm_slider_value_get(bd->controls.force.relx),
|
|
elm_slider_value_get(bd->controls.force.rely), 0);
|
|
ephysics_body_torque_apply(body, 0, 0,
|
|
elm_slider_value_get(bd->controls.force.torque));
|
|
|
|
bd->body = body;
|
|
}
|
|
|
|
static void
|
|
_material_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = evas_object_data_get(obj, "bd");
|
|
Evas_Object *win = bd->wd->win;
|
|
EPhysics_Body *body = bd->body;
|
|
EPhysics_Body_Material material = (EPhysics_Body_Material) data;
|
|
Evas_Object *body_image;
|
|
int x, y, w, h;
|
|
|
|
elm_object_text_set(obj, materials[material]);
|
|
ephysics_body_material_set(body, material);
|
|
|
|
elm_slider_value_set(evas_object_data_get(obj, "mass"),
|
|
ephysics_body_mass_get(body));
|
|
elm_slider_value_set(evas_object_data_get(obj, "density"),
|
|
ephysics_body_density_get(body));
|
|
elm_slider_value_set(evas_object_data_get(obj, "friction"),
|
|
ephysics_body_friction_get(body));
|
|
elm_slider_value_set(evas_object_data_get(obj, "restitution"),
|
|
ephysics_body_restitution_get(body));
|
|
|
|
body_image = ephysics_body_evas_object_unset(body);
|
|
evas_object_geometry_get(body_image, &x, &y, &w, &h);
|
|
evas_object_del(body_image);
|
|
|
|
body_image = elm_image_add(win);
|
|
elm_image_file_set(
|
|
body_image, PACKAGE_DATA_DIR "/" SANDBOX_THEME ".edj",
|
|
materials[material]);
|
|
evas_object_resize(body_image, w, h);
|
|
evas_object_move(body_image, x, y);
|
|
evas_object_show(body_image);
|
|
ephysics_body_evas_object_set(body, body_image, EINA_FALSE);
|
|
}
|
|
|
|
static void
|
|
_mass_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double mass = elm_slider_value_get(obj);
|
|
ephysics_body_mass_set(bd->body, mass);
|
|
elm_slider_value_set(evas_object_data_get(obj, "density"),
|
|
mass / ephysics_body_volume_get(bd->body));
|
|
}
|
|
|
|
static void
|
|
_density_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_density_set(bd->body, elm_slider_value_get(obj));
|
|
elm_slider_value_set(evas_object_data_get(obj, "mass"),
|
|
ephysics_body_mass_get(bd->body));
|
|
}
|
|
|
|
static void
|
|
_rotation_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
EPhysics_Quaternion quat;
|
|
Body_Data *bd = data;
|
|
ephysics_quaternion_euler_set(&quat, 0, 0, elm_slider_value_get(obj));
|
|
ephysics_body_rotation_set(bd->body, &quat);
|
|
}
|
|
|
|
static void
|
|
_friction_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_friction_set(bd->body, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_restitution_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_restitution_set(bd->body, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_linear_damping_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double ang_damping;
|
|
ephysics_body_damping_get(bd->body, NULL, &ang_damping);
|
|
ephysics_body_damping_set(bd->body, elm_slider_value_get(obj), ang_damping);
|
|
}
|
|
|
|
static void
|
|
_angular_damping_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double lin_damping;
|
|
ephysics_body_damping_get(bd->body, &lin_damping, NULL);
|
|
ephysics_body_damping_set(bd->body, lin_damping, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_lin_sleeping_threshold_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double ang_sleeping;
|
|
ephysics_body_sleeping_threshold_get(bd->body, NULL, &ang_sleeping);
|
|
ephysics_body_sleeping_threshold_set(bd->body, elm_slider_value_get(obj),
|
|
ang_sleeping);
|
|
}
|
|
|
|
static void
|
|
_ang_sleeping_threshold_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double lin_sleeping;
|
|
ephysics_body_sleeping_threshold_get(bd->body, &lin_sleeping, NULL);
|
|
ephysics_body_sleeping_threshold_set(bd->body, lin_sleeping,
|
|
elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_torque_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_torque_apply(bd->body, 0, 0, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_impulse_x_x_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Evas_Coord rel_x, rel_y;
|
|
Body_Data *bd = data;
|
|
double y;
|
|
|
|
y = elm_slider_value_get(evas_object_data_get(obj, "y"));
|
|
rel_x = elm_slider_value_get(evas_object_data_get(obj, "relx"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(obj, "rely"));
|
|
ephysics_body_impulse_apply(bd->body, elm_slider_value_get(obj), y, 0,
|
|
rel_x, rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_impulse_x_rel_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
Evas_Coord rel_y;
|
|
double x, y;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
y = elm_slider_value_get(evas_object_data_get(aux, "y"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(aux, "rely"));
|
|
ephysics_body_impulse_apply(bd->body, x, y, 0,
|
|
elm_slider_value_get(obj), rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_impulse_y_y_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
Evas_Coord rel_x, rel_y;
|
|
double x;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
rel_x = elm_slider_value_get(evas_object_data_get(aux, "relx"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(aux, "rely"));
|
|
ephysics_body_impulse_apply(bd->body, x, elm_slider_value_get(obj), 0,
|
|
rel_x, rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_impulse_y_rel_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
Evas_Coord rel_x;
|
|
double x, y;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
y = elm_slider_value_get(evas_object_data_get(aux, "y"));
|
|
rel_x = elm_slider_value_get(evas_object_data_get(aux, "relx"));
|
|
ephysics_body_impulse_apply(bd->body, x, y, 0,
|
|
rel_x, 0, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_force_x_x_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Evas_Coord rel_x, rel_y;
|
|
Body_Data *bd = data;
|
|
double y;
|
|
|
|
y = elm_slider_value_get(evas_object_data_get(obj, "y"));
|
|
rel_x = elm_slider_value_get(evas_object_data_get(obj, "relx"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(obj, "rely"));
|
|
ephysics_body_force_apply(bd->body, elm_slider_value_get(obj), y, 0,
|
|
rel_x, rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_force_x_rel_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
Evas_Coord rel_y;
|
|
double x, y;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
y = elm_slider_value_get(evas_object_data_get(aux, "y"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(aux, "rely"));
|
|
ephysics_body_force_apply(bd->body, x, y, 0,
|
|
elm_slider_value_get(obj), rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_force_y_y_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Evas_Coord rel_x, rel_y;
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
double x;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
rel_x = elm_slider_value_get(evas_object_data_get(aux, "relx"));
|
|
rel_y = elm_slider_value_get(evas_object_data_get(aux, "rely"));
|
|
ephysics_body_force_apply(bd->body, x, elm_slider_value_get(obj), 0,
|
|
rel_x, rel_y, 0);
|
|
}
|
|
|
|
static void
|
|
_force_y_rel_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
Evas_Object *aux;
|
|
Evas_Coord rel_x;
|
|
double x, y;
|
|
|
|
aux = evas_object_data_get(obj, "x");
|
|
x = elm_slider_value_get(aux);
|
|
y = elm_slider_value_get(evas_object_data_get(aux, "y"));
|
|
rel_x = elm_slider_value_get(evas_object_data_get(aux, "relx"));
|
|
ephysics_body_force_apply(bd->body, x, y, 0,
|
|
rel_x, elm_slider_value_get(obj), 0);
|
|
}
|
|
|
|
static void
|
|
_linear_velocity_x_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double ylinear;
|
|
ylinear = elm_slider_value_get(evas_object_data_get(obj, "y"));
|
|
ephysics_body_linear_velocity_set(bd->body, elm_slider_value_get(obj),
|
|
ylinear, 0);
|
|
}
|
|
|
|
static void
|
|
_linear_velocity_y_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
double xlinear;
|
|
xlinear = elm_slider_value_get(evas_object_data_get(obj, "x"));
|
|
ephysics_body_linear_velocity_set(bd->body, xlinear,
|
|
elm_slider_value_get(obj), 0);
|
|
}
|
|
|
|
static void
|
|
_angular_velocity_set_cb(void *data, Evas_Object *obj,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_angular_velocity_set(bd->body, 0, 0,
|
|
elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_hardness_set_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
Body_Data *bd = data;
|
|
ephysics_body_soft_body_hardness_set(bd->body, elm_slider_value_get(obj));
|
|
}
|
|
|
|
static void
|
|
_simulate_body(Body_Data *bd, Evas_Coord x, Evas_Coord y)
|
|
{
|
|
ephysics_body_stop(bd->body);
|
|
ephysics_body_geometry_set(bd->body, x, y, -15, 70, 70, 30);
|
|
ephysics_body_linear_velocity_set(bd->body,
|
|
elm_slider_value_get(
|
|
bd->controls.velocity.x),
|
|
elm_slider_value_get(
|
|
bd->controls.velocity.y), 0);
|
|
ephysics_body_angular_velocity_set(bd->body, 0, 0,
|
|
elm_slider_value_get(
|
|
bd->controls.velocity.angular));
|
|
ephysics_body_impulse_apply(bd->body,
|
|
elm_slider_value_get(bd->controls.impulse.x),
|
|
elm_slider_value_get(bd->controls.impulse.y), 0,
|
|
elm_slider_value_get(bd->controls.impulse.relx),
|
|
elm_slider_value_get(bd->controls.impulse.rely),
|
|
0);
|
|
}
|
|
|
|
static void
|
|
_simulate(World_Data *wd)
|
|
{
|
|
_simulate_body(wd->bd1, (int) WIDTH / 5, (int) HEIGHT / 5);
|
|
_simulate_body(wd->bd2, (int) WIDTH / 2, (int) HEIGHT / 5);
|
|
}
|
|
|
|
static void
|
|
_simulate_cb(void *data, Evas_Object *obj __UNUSED__,
|
|
void *event_info __UNUSED__)
|
|
{
|
|
_simulate(data);
|
|
}
|
|
|
|
static void
|
|
_promote(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
|
{
|
|
elm_naviframe_item_promote(data);
|
|
}
|
|
|
|
/*** Sandbox Widgets ***/
|
|
static void
|
|
_label_add(Evas_Object *bxparent, const char *subcategory, float align)
|
|
{
|
|
Evas_Object *label;
|
|
|
|
label = elm_label_add(bxparent);
|
|
elm_object_text_set(label, subcategory);
|
|
evas_object_size_hint_weight_set(label, 0.0, 0.0);
|
|
evas_object_size_hint_align_set(label, align, 0.5);
|
|
elm_box_pack_end(bxparent, label);
|
|
evas_object_show(label);
|
|
}
|
|
|
|
static Evas_Object *
|
|
_material_selector_add(Body_Data *bd, Evas_Object *bxparent)
|
|
{
|
|
Evas_Object *box, *hv;
|
|
|
|
box = elm_box_add(bxparent);
|
|
elm_box_horizontal_set(box, EINA_TRUE);
|
|
elm_box_homogeneous_set(box, EINA_TRUE);
|
|
elm_box_padding_set(box, 25, 0);
|
|
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0.0);
|
|
evas_object_show(box);
|
|
elm_box_pack_end(bxparent, box);
|
|
|
|
_label_add(box, "Body Material", 1);
|
|
|
|
hv = elm_hoversel_add(box);
|
|
elm_hoversel_hover_parent_set(hv, bd->wd->nf);
|
|
elm_object_text_set(hv, materials[EPHYSICS_BODY_MATERIAL_CUSTOM]);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_CUSTOM],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_CUSTOM);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_CONCRETE],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_CONCRETE);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_IRON],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_IRON);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_PLASTIC],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_PLASTIC);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_POLYSTYRENE],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_POLYSTYRENE);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_RUBBER],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_RUBBER);
|
|
elm_hoversel_item_add(hv, materials[EPHYSICS_BODY_MATERIAL_WOOD],
|
|
NULL, ELM_ICON_NONE, _material_set_cb,
|
|
(void *) EPHYSICS_BODY_MATERIAL_WOOD);
|
|
|
|
evas_object_size_hint_align_set(hv, 0.5, 0.5);
|
|
elm_box_pack_end(box, hv);
|
|
evas_object_show(hv);
|
|
evas_object_data_set(hv, "bd", bd);
|
|
|
|
return hv;
|
|
}
|
|
|
|
static void
|
|
_type_radio_add(Body_Data *bd, Evas_Object *bxparent)
|
|
{
|
|
Evas_Object *dbx, *rbx, *rd, *rdg;
|
|
|
|
dbx = elm_box_add(bxparent);
|
|
elm_box_horizontal_set(dbx, EINA_TRUE);
|
|
evas_object_size_hint_weight_set(dbx, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(dbx, EVAS_HINT_FILL, 0.0);
|
|
elm_box_homogeneous_set(dbx, EINA_TRUE);
|
|
elm_box_align_set(dbx, 1, 0.5);
|
|
elm_box_pack_end(bxparent, dbx);
|
|
evas_object_show(dbx);
|
|
|
|
_label_add(dbx, "Body Type", 1);
|
|
|
|
rbx = elm_box_add(bxparent);
|
|
elm_box_horizontal_set(rbx, EINA_TRUE);
|
|
evas_object_size_hint_weight_set(rbx, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(rbx, EVAS_HINT_FILL, 0.0);
|
|
elm_box_padding_set(rbx, 25, 0);
|
|
elm_box_align_set(rbx, 0.5, 0.5);
|
|
elm_box_pack_end(dbx, rbx);
|
|
evas_object_show(rbx);
|
|
|
|
rd = elm_radio_add(bxparent);
|
|
elm_radio_state_value_set(rd, 0);
|
|
elm_object_text_set(rd, "Solid");
|
|
evas_object_size_hint_align_set(rd, 1, 0.5);
|
|
evas_object_size_hint_weight_set(rd, 0, EVAS_HINT_EXPAND);
|
|
elm_box_pack_end(rbx, rd);
|
|
evas_object_show(rd);
|
|
rdg = rd;
|
|
evas_object_smart_callback_add(rd, "changed", _type_set_cb, bd);
|
|
|
|
rd = elm_radio_add(bxparent);
|
|
elm_radio_state_value_set(rd, 1);
|
|
elm_radio_group_add(rd, rdg);
|
|
elm_object_text_set(rd, "Soft");
|
|
evas_object_size_hint_align_set(rd, 1, 0.5);
|
|
evas_object_size_hint_weight_set(rd, 0, EVAS_HINT_EXPAND);
|
|
elm_box_pack_end(rbx, rd);
|
|
evas_object_show(rd);
|
|
evas_object_smart_callback_add(rd, "changed", _type_set_cb, bd);
|
|
}
|
|
|
|
static Evas_Object *
|
|
_slider_add(Evas_Object *bxparent, const char *subcategory, const char *itemlb,
|
|
float min, float max, float initial)
|
|
{
|
|
Evas_Object *sl, *dbx;
|
|
|
|
dbx = elm_box_add(bxparent);
|
|
elm_box_horizontal_set(dbx, EINA_TRUE);
|
|
evas_object_size_hint_weight_set(dbx, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(dbx, EVAS_HINT_FILL, 0.0);
|
|
elm_box_homogeneous_set(dbx, EINA_TRUE);
|
|
elm_box_align_set(dbx, 0, 0.5);
|
|
elm_box_pack_end(bxparent, dbx);
|
|
evas_object_show(dbx);
|
|
|
|
_label_add(dbx, subcategory, 1);
|
|
|
|
sl = elm_slider_add(bxparent);
|
|
elm_slider_unit_format_set(sl, itemlb);
|
|
elm_slider_min_max_set(sl, min, max);
|
|
elm_slider_value_set(sl, initial);
|
|
elm_slider_span_size_set(sl, 100);
|
|
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(sl, 0, 0.5);
|
|
elm_box_pack_end(dbx, sl);
|
|
evas_object_show(sl);
|
|
|
|
return sl;
|
|
}
|
|
|
|
static Evas_Object *
|
|
_category_add(Evas_Object *bxparent, const char *label, Eina_Bool collapse)
|
|
{
|
|
Evas_Object *cfr, *cbx;
|
|
|
|
cfr = elm_frame_add(bxparent);
|
|
elm_frame_autocollapse_set(cfr, collapse);
|
|
elm_frame_collapse_set(cfr, collapse);
|
|
elm_object_text_set(cfr, label);
|
|
evas_object_size_hint_weight_set(cfr, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_fill_set(cfr, EVAS_HINT_FILL, 0.0);
|
|
elm_box_pack_end(bxparent, cfr);
|
|
evas_object_show(cfr);
|
|
|
|
cbx = elm_box_add(bxparent);
|
|
elm_box_horizontal_set(cbx, EINA_FALSE);
|
|
evas_object_size_hint_weight_set(cbx, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(cbx, EVAS_HINT_FILL, 0.0);
|
|
elm_object_content_set(cfr, cbx);
|
|
evas_object_show(cbx);
|
|
|
|
return cbx;
|
|
}
|
|
|
|
/*** Sandbox Pages ***/
|
|
static void
|
|
_menu_page_add(Evas_Object *win, Evas_Object **scroller_box,
|
|
Evas_Object **content_box)
|
|
{
|
|
Evas_Object *scbx, *bx, *sc;
|
|
|
|
scbx = elm_box_add(win);
|
|
evas_object_size_hint_weight_set(scbx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
|
evas_object_size_hint_align_set(scbx, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
|
evas_object_show(scbx);
|
|
|
|
sc = elm_scroller_add(win);
|
|
elm_scroller_bounce_set(sc, EINA_FALSE, EINA_TRUE);
|
|
elm_scroller_policy_set(sc, ELM_SCROLLER_POLICY_OFF,
|
|
ELM_SCROLLER_POLICY_AUTO);
|
|
evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
|
evas_object_size_hint_fill_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
|
elm_box_pack_end(scbx, sc);
|
|
evas_object_show(sc);
|
|
|
|
bx = elm_box_add(win);
|
|
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0);
|
|
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0);
|
|
evas_object_show(bx);
|
|
elm_object_content_set(sc, bx);
|
|
|
|
*scroller_box = scbx;
|
|
*content_box = bx;
|
|
}
|
|
|
|
static void
|
|
_menu_body_page_add(World_Data *wd, Body_Data *bd, const char *pg_label)
|
|
{
|
|
Evas_Object *bx, *bxbody, *scbxbody, *widget, *aux_widget, *material_widget;
|
|
Elm_Object_Item *it;
|
|
|
|
_menu_page_add(wd->win, &scbxbody, &bxbody);
|
|
bx = _category_add(bxbody, "", EINA_FALSE);
|
|
_type_radio_add(bd, bx);
|
|
material_widget = _material_selector_add(bd, bx);
|
|
|
|
bx = _category_add(bxbody, "Properties", EINA_TRUE);
|
|
aux_widget = _slider_add(bx, "Mass (kg)", "%1.3f", 0, 99999, INITIAL_MASS);
|
|
evas_object_data_set(material_widget, "mass", aux_widget);
|
|
widget = _slider_add(bx, "Density (kg/m³)", "%1.3f", 0, 9999, 0);
|
|
evas_object_data_set(aux_widget, "density", widget);
|
|
evas_object_data_set(material_widget, "density", widget);
|
|
evas_object_smart_callback_add(aux_widget, "delay,changed", _mass_set_cb,
|
|
bd);
|
|
evas_object_data_set(widget, "mass", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _density_set_cb,
|
|
bd);
|
|
widget = _slider_add(bx, "Rotation (rad)", "%1.3f", -3.1415, 3.1415, 0);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _rotation_set_cb,
|
|
bd);
|
|
widget = _slider_add(bx, "Friction", "%1.3f", 0, 1, 0.5);
|
|
evas_object_data_set(material_widget, "friction", widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _friction_set_cb,
|
|
bd);
|
|
widget = _slider_add(bx, "Restitution", "%1.3f", 0, 1, 0);
|
|
evas_object_data_set(material_widget, "restitution", widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_restitution_set_cb, bd);
|
|
_label_add(bx, "Damping", 0.5);
|
|
widget = _slider_add(bx, "Linear", "%1.3f", 0, 1, 0);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_linear_damping_set_cb, bd);
|
|
widget = _slider_add(bx, "Angular", "%1.3f", 0, 1, 0);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_angular_damping_set_cb, bd);
|
|
_label_add(bx, "Sleeping Threshold", 0.5);
|
|
widget = _slider_add(bx, "Linear (p/s)", "%1.2f",
|
|
0, 250, 24);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_lin_sleeping_threshold_set_cb, bd);
|
|
widget = _slider_add(bx, "Angular (º/s)", "%1.2f",
|
|
0, 360, 57.29);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_ang_sleeping_threshold_set_cb, bd);
|
|
|
|
bx = _category_add(bxbody, "Actions", EINA_TRUE);
|
|
_label_add(bx, "Impulse X", 0.5);
|
|
aux_widget = _slider_add(bx, "X (kg * p/s)", "%1.3f",
|
|
-9999, 9999, 0);
|
|
bd->controls.impulse.x = aux_widget;
|
|
widget = _slider_add(bx, "Rel Position X", "%1.2f",
|
|
-360, 360, 0);
|
|
bd->controls.impulse.relx = widget;
|
|
evas_object_data_set(aux_widget, "relx", widget);
|
|
_label_add(bx, "Impulse Y", 0.5);
|
|
widget = _slider_add(bx, "Y (kg * p/s)", "%1.3f", -9999, 9999, 0);
|
|
bd->controls.impulse.y = widget;
|
|
evas_object_data_set(aux_widget, "y", widget);
|
|
widget = _slider_add(bx, "Rel Position Y", "%1.2f", -360, 360, 0);
|
|
bd->controls.impulse.rely = widget;
|
|
evas_object_data_set(aux_widget, "rely", widget);
|
|
evas_object_smart_callback_add(aux_widget, "delay,changed",
|
|
_impulse_x_x_set_cb, bd);
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_impulse_x_rel_set_cb, bd);
|
|
widget = evas_object_data_get(aux_widget, "y");
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_impulse_y_y_set_cb, bd);
|
|
widget = evas_object_data_get(aux_widget, "relx");
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_impulse_y_rel_set_cb, bd);
|
|
|
|
_label_add(bx, "Force X", 0.5);
|
|
aux_widget = _slider_add(bx, "X (kg * p/s/s)", "%1.3f", -1999, 1999, 0);
|
|
bd->controls.force.x = aux_widget;
|
|
widget = _slider_add(bx, "Rel Position X", "%1.2f", -360, 360, 0);
|
|
bd->controls.force.relx = widget;
|
|
evas_object_data_set(aux_widget, "relx", widget);
|
|
_label_add(bx, "Force Y", 0.5);
|
|
widget = _slider_add(bx, "Y (kg * p/s/s)", "%1.3f", -1999, 1999, 0);
|
|
bd->controls.force.y = widget;
|
|
evas_object_data_set(aux_widget, "y", widget);
|
|
widget = _slider_add(bx, "Rel Position Y", "%1.2f", -360, 360, 0);
|
|
bd->controls.force.rely = widget;
|
|
evas_object_data_set(aux_widget, "rely", widget);
|
|
evas_object_smart_callback_add(aux_widget, "delay,changed",
|
|
_force_x_x_set_cb, bd);
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_force_x_rel_set_cb, bd);
|
|
widget = evas_object_data_get(aux_widget, "y");
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_force_y_y_set_cb, bd);
|
|
widget = evas_object_data_get(aux_widget, "relx");
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_force_y_rel_set_cb, bd);
|
|
widget = _slider_add(bx, "Torque", "%1.3f", -100, 100, 0);
|
|
bd->controls.force.torque = widget;
|
|
evas_object_smart_callback_add(widget, "delay,changed", _torque_set_cb, bd);
|
|
|
|
_label_add(bx, "Linear Velocity", 0.5);
|
|
aux_widget = _slider_add(bx, "X (p/s)", "%1.2f", -1499, 1499, 0);
|
|
bd->controls.velocity.x = aux_widget;
|
|
widget = _slider_add(bx, "Y (p/s)", "%1.2f", -1499, 1499, 0);
|
|
bd->controls.velocity.y = widget;
|
|
evas_object_data_set(aux_widget, "y", widget);
|
|
evas_object_smart_callback_add(aux_widget, "delay,changed",
|
|
_linear_velocity_x_set_cb, bd);
|
|
evas_object_data_set(widget, "x", aux_widget);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_linear_velocity_y_set_cb, bd);
|
|
|
|
widget = _slider_add(bx, "Angular Velocity (º/s)", "%1.2f", -360, 360, 0);
|
|
bd->controls.velocity.angular = widget;
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_angular_velocity_set_cb, bd);
|
|
|
|
bx = _category_add(bxbody, "Soft Body", EINA_TRUE);
|
|
widget = _slider_add(bx, "Hardness (%)", "%1.2f%", 0, 100, 100);
|
|
bd->controls.hardness = widget;
|
|
elm_object_disabled_set(widget, EINA_TRUE);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _hardness_set_cb,
|
|
bd);
|
|
|
|
it = elm_naviframe_item_insert_before(wd->nf,
|
|
evas_object_data_get(wd->nf, "world"),
|
|
NULL, NULL, NULL, scbxbody, NULL);
|
|
elm_naviframe_item_title_visible_set(it, EINA_FALSE);
|
|
it = elm_toolbar_item_append(wd->tb, NULL, pg_label, _promote, it);
|
|
}
|
|
|
|
static void
|
|
_menu_world_page_add(World_Data *wd)
|
|
{
|
|
Evas_Object *bx, *scbx, *bxparent, *widget;
|
|
Elm_Object_Item *it;
|
|
|
|
_menu_page_add(wd->win, &scbx, &bxparent);
|
|
|
|
bx = _category_add(bxparent, "World", EINA_FALSE);
|
|
_label_add(bx, "Gravity (px/s²)", 0.5);
|
|
widget = _slider_add(bx, "X:", "%1.2f", -1000, 1000, 0);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _world_gravity_x_cb,
|
|
wd->world);
|
|
widget = _slider_add(bx, "Y:", "%1.2f", -1000, 1000, 294);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_world_gravity_y_cb, wd->world);
|
|
widget = _slider_add(bx, "Rate (px/m)", "%1.0f", 1, 100, 30);
|
|
evas_object_smart_callback_add(widget, "delay,changed", _world_rate_cb,
|
|
wd->world);
|
|
widget = _slider_add(bx, "Max Sleeping Time (s)", "%1.0f", 0, 50, 2);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_world_max_sleeping_time_cb, wd->world);
|
|
|
|
bx = _category_add(bxparent, "Boundaries", EINA_FALSE);
|
|
widget = _slider_add(bx, "Friction", "%1.3f", 0, 1, 0.5);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_world_friction_cb, wd);
|
|
widget = _slider_add(bx, "Restitution", "%1.3f", 0, 1, 0);
|
|
evas_object_smart_callback_add(widget, "delay,changed",
|
|
_world_restitution_cb, wd);
|
|
|
|
it = elm_naviframe_item_push(wd->nf, NULL, NULL, NULL, scbx, NULL);
|
|
evas_object_data_set(wd->nf, "world", it);
|
|
elm_naviframe_item_title_visible_set(it, EINA_FALSE);
|
|
it = elm_toolbar_item_append(wd->tb, NULL, "World", _promote, it);
|
|
}
|
|
|
|
static void
|
|
_menu_create(World_Data *wd)
|
|
{
|
|
Evas_Object *mainbx, *dbx, *btn, *bg, *layout;
|
|
|
|
bg = elm_bg_add(wd->win);
|
|
elm_win_resize_object_add(wd->win, bg);
|
|
evas_object_size_hint_min_set(bg, WIDTH, HEIGHT);
|
|
evas_object_size_hint_max_set(bg, WIDTH, HEIGHT);
|
|
|
|
layout = elm_layout_add(wd->win);
|
|
elm_layout_file_set(layout, PACKAGE_DATA_DIR "/" SANDBOX_THEME ".edj",
|
|
"sandbox");
|
|
evas_object_resize(layout, WIDTH, HEIGHT);
|
|
evas_object_show(layout);
|
|
|
|
mainbx = elm_box_add(wd->win);
|
|
evas_object_size_hint_fill_set(mainbx, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
|
elm_object_part_content_set(layout, "swallow", mainbx);
|
|
evas_object_show(mainbx);
|
|
|
|
dbx = elm_box_add(mainbx);
|
|
elm_box_horizontal_set(dbx, EINA_TRUE);
|
|
evas_object_size_hint_weight_set(dbx, EVAS_HINT_EXPAND, 0.0);
|
|
evas_object_size_hint_align_set(dbx, EVAS_HINT_FILL, 0.0);
|
|
elm_box_align_set(dbx, 0, 0.5);
|
|
elm_box_pack_end(mainbx, dbx);
|
|
evas_object_show(dbx);
|
|
|
|
wd->tb = elm_toolbar_add(wd->win);
|
|
evas_object_size_hint_weight_set(wd->tb, EVAS_HINT_EXPAND, 0);
|
|
evas_object_size_hint_fill_set(wd->tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
|
elm_toolbar_select_mode_set(wd->tb, ELM_OBJECT_SELECT_MODE_ALWAYS);
|
|
elm_box_pack_end(dbx, wd->tb);
|
|
evas_object_show(wd->tb);
|
|
|
|
btn = elm_button_add(wd->win);
|
|
elm_object_text_set(btn, "Restart");
|
|
evas_object_size_hint_min_set(btn, 100, 30);
|
|
evas_object_size_hint_align_set(btn, 1, 0.5);
|
|
elm_box_pack_end(dbx, btn);
|
|
evas_object_show(btn);
|
|
evas_object_smart_callback_add(btn, "clicked", _simulate_cb, wd);
|
|
|
|
|
|
wd->nf = elm_naviframe_add(wd->win);
|
|
evas_object_size_hint_weight_set(wd->nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
|
evas_object_size_hint_fill_set(wd->nf, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
|
elm_box_pack_end(mainbx, wd->nf);
|
|
evas_object_show(wd->nf);
|
|
}
|
|
|
|
static EPhysics_Body *
|
|
_body_add(Evas_Object *win, EPhysics_World *world, int x, int y)
|
|
{
|
|
Evas_Object *body_image;
|
|
EPhysics_Body *body;
|
|
|
|
body_image = elm_image_add(win);
|
|
elm_image_file_set(
|
|
body_image, PACKAGE_DATA_DIR "/" SANDBOX_THEME ".edj", "Custom");
|
|
evas_object_resize(body_image, 70, 70);
|
|
evas_object_move(body_image, x, y);
|
|
evas_object_show(body_image);
|
|
|
|
body = ephysics_body_circle_add(world);
|
|
ephysics_body_evas_object_set(body, body_image, EINA_TRUE);
|
|
ephysics_body_mass_set(body, INITIAL_MASS);
|
|
ephysics_body_event_callback_add(body, EPHYSICS_CALLBACK_BODY_DEL,
|
|
_body_del, NULL);
|
|
|
|
return body;
|
|
}
|
|
|
|
EAPI int
|
|
elm_main()
|
|
{
|
|
EPhysics_World *world;
|
|
Body_Data bd1, bd2;
|
|
Evas_Object *win;
|
|
World_Data wd;
|
|
|
|
if (!ephysics_init())
|
|
{
|
|
fprintf(stderr, "Failed to init ephysics\n");
|
|
elm_shutdown();
|
|
return -1;
|
|
}
|
|
|
|
elm_theme_extension_add(NULL, PACKAGE_DATA_DIR "/" SANDBOX_THEME ".edj");
|
|
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
|
|
|
win = elm_win_add(NULL, "Sandbox", ELM_WIN_BASIC);
|
|
elm_win_title_set(win, "EPhysics Sandbox");
|
|
elm_win_autodel_set(win, EINA_TRUE);
|
|
evas_object_show(win);
|
|
|
|
world = ephysics_world_new();
|
|
ephysics_world_simulation_set(world, 1/100.f, 10);
|
|
ephysics_world_render_geometry_set(world, 80, 80, -50,
|
|
(int) WIDTH * 0.7 - 160, HEIGHT - 160,
|
|
DEPTH);
|
|
wd.top = ephysics_body_top_boundary_add(world);
|
|
wd.bottom = ephysics_body_bottom_boundary_add(world);
|
|
wd.left = ephysics_body_left_boundary_add(world);
|
|
wd.right = ephysics_body_right_boundary_add(world);
|
|
|
|
wd.world = world;
|
|
wd.win = win;
|
|
wd.bd1 = &bd1;
|
|
wd.bd2 = &bd2;
|
|
bd1.wd = &wd;
|
|
bd2.wd = &wd;
|
|
|
|
_menu_create(&wd);
|
|
_menu_world_page_add(&wd);
|
|
_menu_body_page_add(&wd, &bd1, "Body 1");
|
|
_menu_body_page_add(&wd, &bd2, "Body 2");
|
|
|
|
bd1.body = _body_add(win, world, WIDTH / 5, HEIGHT / 5);
|
|
bd2.body = _body_add(win, world, WIDTH / 2, HEIGHT / 5);
|
|
|
|
_simulate(&wd);
|
|
|
|
elm_run();
|
|
|
|
ephysics_shutdown();
|
|
elm_shutdown();
|
|
return 0;
|
|
}
|
|
ELM_MAIN()
|