forked from enlightenment/efl
ephysics: fix soft body slicing
Also, fix evas_object_set on cases when it shouldn't use evas object geometry. SVN revision: 78483
This commit is contained in:
parent
5d3d4978ad
commit
8d4e7bdd62
|
@ -17,9 +17,11 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SOFT_DATA "soft_data"
|
#define BODY "body"
|
||||||
|
|
||||||
typedef struct _EPhysics_Body_Callback EPhysics_Body_Callback;
|
typedef struct _EPhysics_Body_Callback EPhysics_Body_Callback;
|
||||||
|
typedef struct _EPhysics_Body_Evas_Stacking EPhysics_Body_Evas_Stacking;
|
||||||
|
typedef struct _EPhysics_Body_Soft_Body_Slice EPhysics_Body_Soft_Body_Slice;
|
||||||
|
|
||||||
struct _EPhysics_Body_Callback {
|
struct _EPhysics_Body_Callback {
|
||||||
EINA_INLIST;
|
EINA_INLIST;
|
||||||
|
@ -36,30 +38,28 @@ struct _EPhysics_Body_Collision {
|
||||||
Evas_Coord z;
|
Evas_Coord z;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _EPhysics_Body_Evas_Stacking {
|
struct _EPhysics_Body_Evas_Stacking {
|
||||||
Evas_Object *evas;
|
Evas_Object *evas;
|
||||||
float stacking;
|
float stacking;
|
||||||
} EPhysics_Body_Evas_Stacking;
|
};
|
||||||
|
|
||||||
typedef struct _EPhysics_Body_Soft_Body_Slice
|
struct _EPhysics_Body_Soft_Body_Slice
|
||||||
{
|
{
|
||||||
Evas_Object *evas_obj;
|
Evas_Object *evas_obj;
|
||||||
int index;
|
int index;
|
||||||
Evas_Coord x0;
|
struct {
|
||||||
Evas_Coord x1;
|
double x;
|
||||||
Evas_Coord x2;
|
double y;
|
||||||
Evas_Coord y0;
|
} p[3];
|
||||||
Evas_Coord y1;
|
|
||||||
Evas_Coord y2;
|
|
||||||
float stacking;
|
float stacking;
|
||||||
} EPhysics_Body_Soft_Body_Slice;
|
};
|
||||||
|
|
||||||
typedef struct _EPhysics_Body_Soft_Body_Data
|
struct _EPhysics_Body_Soft_Body_Data
|
||||||
{
|
{
|
||||||
Evas_Object *base_obj;
|
Evas_Object *base_obj;
|
||||||
EPhysics_Body *body;
|
EPhysics_Body *body;
|
||||||
Eina_List *slices;
|
Eina_List *slices;
|
||||||
} EPhysics_Body_Soft_Body_Data;
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
_ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
||||||
|
@ -67,12 +67,11 @@ _ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
double rate;
|
double rate;
|
||||||
void *list_data;
|
void *list_data;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
Evas_Coord wy, wh, y0, y1, y2, x0, x1, x2, z0, z1, z2, bw, bh;
|
Evas_Coord wy, wh, y0, y1, y2, x0, x1, x2, z0, z1, z2, bw, bh, w, h;
|
||||||
Evas_Map *map;
|
Evas_Map *map;
|
||||||
btVector3 p0, p1, p2;
|
btVector3 p0, p1, p2;
|
||||||
btSoftBody::tFaceArray faces;
|
btSoftBody::tFaceArray faces;
|
||||||
EPhysics_Body_Soft_Body_Slice *slice;
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
EPhysics_Body_Soft_Body_Data *soft_data;
|
|
||||||
EPhysics_Body *body;
|
EPhysics_Body *body;
|
||||||
btVector3 b0, b1;
|
btVector3 b0, b1;
|
||||||
int lr, lg, lb, ar, ag, ab;
|
int lr, lg, lb, ar, ag, ab;
|
||||||
|
@ -82,14 +81,13 @@ _ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
int px, py, pz, foc;
|
int px, py, pz, foc;
|
||||||
Eina_Bool perspective = EINA_FALSE;
|
Eina_Bool perspective = EINA_FALSE;
|
||||||
|
|
||||||
soft_data = (EPhysics_Body_Soft_Body_Data *)evas_object_data_get(obj,
|
body = (EPhysics_Body *) evas_object_data_get(obj, BODY);
|
||||||
SOFT_DATA);
|
|
||||||
body = soft_data->body;
|
|
||||||
camera = ephysics_world_camera_get(body->world);
|
camera = ephysics_world_camera_get(body->world);
|
||||||
rate = ephysics_world_rate_get(body->world);
|
rate = ephysics_world_rate_get(body->world);
|
||||||
|
|
||||||
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
||||||
NULL);
|
NULL);
|
||||||
|
evas_object_geometry_get(body->soft_data->base_obj, NULL, NULL, &w, &h);
|
||||||
|
|
||||||
if ((body->light_apply) ||
|
if ((body->light_apply) ||
|
||||||
(ephysics_world_light_all_bodies_get(body->world)))
|
(ephysics_world_light_all_bodies_get(body->world)))
|
||||||
|
@ -106,7 +104,7 @@ _ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
perspective = EINA_TRUE;
|
perspective = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EINA_LIST_FOREACH(soft_data->slices, l, list_data)
|
EINA_LIST_FOREACH(body->soft_data->slices, l, list_data)
|
||||||
{
|
{
|
||||||
slice = (EPhysics_Body_Soft_Body_Slice *)list_data;
|
slice = (EPhysics_Body_Soft_Body_Slice *)list_data;
|
||||||
|
|
||||||
|
@ -115,27 +113,31 @@ _ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
p1 = faces[slice->index].m_n[1]->m_x;
|
p1 = faces[slice->index].m_n[1]->m_x;
|
||||||
p2 = faces[slice->index].m_n[2]->m_x;
|
p2 = faces[slice->index].m_n[2]->m_x;
|
||||||
|
|
||||||
y0 = wh + wy - (p0.y() * rate);
|
slice->stacking = p0.z() + p1.z() + p2.z();
|
||||||
y1 = wh + wy - (p1.y() * rate);
|
|
||||||
y2 = wh + wy - (p2.y() * rate);
|
map = evas_map_new(4);
|
||||||
|
|
||||||
|
evas_map_point_image_uv_set(map, 0, slice->p[0].x * w,
|
||||||
|
slice->p[0].y * h);
|
||||||
|
evas_map_point_image_uv_set(map, 1, slice->p[1].x * w,
|
||||||
|
slice->p[1].y * h);
|
||||||
|
evas_map_point_image_uv_set(map, 2, slice->p[2].x * w,
|
||||||
|
slice->p[2].y * h);
|
||||||
|
evas_map_point_image_uv_set(map, 3, slice->p[2].x * w,
|
||||||
|
slice->p[2].y * h);
|
||||||
|
|
||||||
x0 = p0.x() * rate;
|
x0 = p0.x() * rate;
|
||||||
x1 = p1.x() * rate;
|
x1 = p1.x() * rate;
|
||||||
x2 = p2.x() * rate;
|
x2 = p2.x() * rate;
|
||||||
|
|
||||||
|
y0 = wh + wy - (p0.y() * rate);
|
||||||
|
y1 = wh + wy - (p1.y() * rate);
|
||||||
|
y2 = wh + wy - (p2.y() * rate);
|
||||||
|
|
||||||
z0 = p0.z() * rate;
|
z0 = p0.z() * rate;
|
||||||
z1 = p1.z() * rate;
|
z1 = p1.z() * rate;
|
||||||
z2 = p2.z() * rate;
|
z2 = p2.z() * rate;
|
||||||
|
|
||||||
slice->stacking = p0.z() + p1.z() + p2.z();
|
|
||||||
|
|
||||||
map = evas_map_new(4);
|
|
||||||
|
|
||||||
evas_map_point_image_uv_set(map, 0, slice->x0, slice->y0);
|
|
||||||
evas_map_point_image_uv_set(map, 1, slice->x1, slice->y1);
|
|
||||||
evas_map_point_image_uv_set(map, 2, slice->x2, slice->y2);
|
|
||||||
evas_map_point_image_uv_set(map, 3, slice->x2, slice->y2);
|
|
||||||
|
|
||||||
evas_map_point_coord_set(map, 0, x0, y0, z0);
|
evas_map_point_coord_set(map, 0, x0, y0, z0);
|
||||||
evas_map_point_coord_set(map, 1, x1, y1, z1);
|
evas_map_point_coord_set(map, 1, x1, y1, z1);
|
||||||
evas_map_point_coord_set(map, 2, x2, y2, z2);
|
evas_map_point_coord_set(map, 2, x2, y2, z2);
|
||||||
|
@ -174,88 +176,89 @@ _ephysics_body_soft_body_slices_apply(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
evas_object_resize(obj, bw, bh);
|
evas_object_resize(obj, bw, bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
_ephysics_body_soft_body_slice_calc(double val, double delta, double max)
|
||||||
|
{
|
||||||
|
double ret = val + delta / max;
|
||||||
|
if (ret < 0)
|
||||||
|
ret = 0;
|
||||||
|
else if (ret > 1)
|
||||||
|
ret = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static EPhysics_Body_Soft_Body_Slice *
|
static EPhysics_Body_Soft_Body_Slice *
|
||||||
_ephysics_body_soft_body_slice_new(int index, Evas_Object *evas_obj)
|
_ephysics_body_soft_body_slice_new(EPhysics_Body *body, double delta, double max, int index)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Soft_Body_Slice *slice;
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
|
btSoftBody::tFaceArray faces;
|
||||||
|
|
||||||
if (!evas_obj) return NULL;
|
slice = (EPhysics_Body_Soft_Body_Slice *)calloc(
|
||||||
|
1, sizeof(EPhysics_Body_Soft_Body_Slice));
|
||||||
slice = (EPhysics_Body_Soft_Body_Slice *)malloc(
|
|
||||||
sizeof(EPhysics_Body_Soft_Body_Slice));
|
|
||||||
if (!slice)
|
if (!slice)
|
||||||
{
|
{
|
||||||
ERR("Couldn't allocate EPhysics_Soft_Body_Slice memory.");
|
ERR("Couldn't allocate EPhysics_Soft_Body_Slice memory.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
faces = body->soft_body->m_faces;
|
||||||
|
|
||||||
slice->index = index;
|
slice->index = index;
|
||||||
slice->evas_obj = evas_obj;
|
slice->p[0].x = _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[0]->m_x.x(), delta, max);
|
||||||
|
slice->p[0].y = 1 - _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[0]->m_x.y(), delta, max);
|
||||||
|
slice->p[1].x = _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[1]->m_x.x(), delta, max);
|
||||||
|
slice->p[1].y = 1 - _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[1]->m_x.y(), delta, max);
|
||||||
|
slice->p[2].x = _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[2]->m_x.x(), delta, max);
|
||||||
|
slice->p[2].y = 1 - _ephysics_body_soft_body_slice_calc(
|
||||||
|
faces[slice->index].m_n[2]->m_x.y(), delta, max);
|
||||||
|
|
||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static void
|
||||||
_ephysics_body_soft_body_slices_init(EPhysics_Body *body, EPhysics_Body_Soft_Body_Data *soft_data)
|
_ephysics_body_soft_body_slices_init(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Soft_Body_Slice *slice = NULL;
|
EPhysics_Body_Soft_Body_Slice *slice = NULL;
|
||||||
Evas_Coord x, y, w, h, wy, wh;
|
Evas_Coord x, y, w, h, wy, wh;
|
||||||
btSoftBody::tFaceArray faces;
|
|
||||||
btVector3 p0, p1, p2;
|
btVector3 p0, p1, p2;
|
||||||
double rate;
|
void *slice_data;
|
||||||
|
Eina_List *l;
|
||||||
Evas *evas;
|
Evas *evas;
|
||||||
|
|
||||||
evas = evas_object_evas_get(body->evas_obj);
|
evas = evas_object_evas_get(body->evas_obj);
|
||||||
|
|
||||||
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, NULL, &wh,
|
||||||
NULL);
|
NULL);
|
||||||
rate = ephysics_world_rate_get(body->world);
|
|
||||||
|
|
||||||
for (int i = 0; i < body->slices; i++)
|
EINA_LIST_FOREACH(body->soft_data->slices, l, slice_data)
|
||||||
{
|
{
|
||||||
slice = _ephysics_body_soft_body_slice_new(
|
slice = (EPhysics_Body_Soft_Body_Slice *) slice_data;
|
||||||
body->points_deform[i], evas_object_image_filled_add(evas));
|
slice->evas_obj = evas_object_image_filled_add(evas);
|
||||||
|
evas_object_image_source_set(slice->evas_obj,
|
||||||
|
body->soft_data->base_obj);
|
||||||
|
|
||||||
if (!slice) return EINA_FALSE;
|
evas_object_geometry_get(body->soft_data->base_obj, &x, &y, &w, &h);
|
||||||
|
|
||||||
evas_object_image_source_set(slice->evas_obj, soft_data->base_obj);
|
|
||||||
|
|
||||||
evas_object_geometry_get(soft_data->base_obj, &x, &y, &w, &h);
|
|
||||||
evas_object_resize(slice->evas_obj, w, h);
|
evas_object_resize(slice->evas_obj, w, h);
|
||||||
evas_object_move(slice->evas_obj, x, y);
|
evas_object_move(slice->evas_obj, x, y);
|
||||||
evas_object_show(slice->evas_obj);
|
evas_object_show(slice->evas_obj);
|
||||||
evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE);
|
evas_object_image_smooth_scale_set(slice->evas_obj, EINA_TRUE);
|
||||||
|
|
||||||
faces = body->soft_body->m_faces;
|
|
||||||
p0 = faces[slice->index].m_n[0]->m_x;
|
|
||||||
p1 = faces[slice->index].m_n[1]->m_x;
|
|
||||||
p2 = faces[slice->index].m_n[2]->m_x;
|
|
||||||
|
|
||||||
slice->x0 = p0.x() * rate - x;
|
|
||||||
slice->x1 = p1.x() * rate - x;
|
|
||||||
slice->x2 = p2.x() * rate - x;
|
|
||||||
slice->y0 = wh + wy - (p0.y() * rate) - y;
|
|
||||||
slice->y1 = wh + wy - (p1.y() * rate) - y;
|
|
||||||
slice->y2 = wh + wy - (p2.y() * rate) - y;
|
|
||||||
|
|
||||||
soft_data->slices = eina_list_append(soft_data->slices, slice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slice)
|
if (slice)
|
||||||
evas_object_stack_above(body->evas_obj, slice->evas_obj);
|
evas_object_stack_above(body->evas_obj, slice->evas_obj);
|
||||||
|
|
||||||
_ephysics_body_soft_body_slices_apply(NULL, NULL, body->evas_obj, NULL);
|
_ephysics_body_soft_body_slices_apply(NULL, NULL, body->evas_obj, NULL);
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_soft_body_evas_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
_ephysics_body_soft_body_data_free(EPhysics_Body_Soft_Body_Data *soft_data)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Soft_Body_Data *soft_data;
|
|
||||||
void *ldata;
|
|
||||||
EPhysics_Body_Soft_Body_Slice *slice;
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
|
void *ldata;
|
||||||
soft_data = (EPhysics_Body_Soft_Body_Data *)evas_object_data_del(obj,
|
|
||||||
SOFT_DATA);
|
|
||||||
|
|
||||||
EINA_LIST_FREE(soft_data->slices, ldata)
|
EINA_LIST_FREE(soft_data->slices, ldata)
|
||||||
{
|
{
|
||||||
|
@ -263,65 +266,75 @@ _ephysics_body_soft_body_evas_del_cb(void *data __UNUSED__, Evas *e __UNUSED__,
|
||||||
evas_object_del(slice->evas_obj);
|
evas_object_del(slice->evas_obj);
|
||||||
free(slice);
|
free(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(soft_data);
|
free(soft_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_soft_body_slices_clean(EPhysics_Body_Soft_Body_Data *soft_data)
|
||||||
|
{
|
||||||
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
|
void *slice_data;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(soft_data->slices, l, slice_data)
|
||||||
|
{
|
||||||
|
slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
|
||||||
|
evas_object_del(slice->evas_obj);
|
||||||
|
slice->evas_obj = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_soft_body_evas_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
||||||
|
{
|
||||||
|
EPhysics_Body *body;
|
||||||
|
body = (EPhysics_Body *) evas_object_data_del(obj, BODY);
|
||||||
|
_ephysics_body_soft_body_data_free(body->soft_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EPhysics_Body_Soft_Body_Data *
|
||||||
|
_ephysics_body_soft_body_data_new(EPhysics_Body *body)
|
||||||
|
{
|
||||||
|
EPhysics_Body_Soft_Body_Data *soft_data;
|
||||||
|
|
||||||
|
soft_data = (EPhysics_Body_Soft_Body_Data *)calloc(
|
||||||
|
1, sizeof(EPhysics_Body_Soft_Body_Data));
|
||||||
|
|
||||||
|
if (!soft_data)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate soft body data struct.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
soft_data->body = body;
|
||||||
|
|
||||||
|
return soft_data;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ephysics_body_soft_body_evas_add(EPhysics_Body *body)
|
_ephysics_body_soft_body_evas_add(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
Evas_Object *obj;
|
Evas_Object *obj;
|
||||||
Evas_Coord x, y, w, h;
|
Evas_Coord x, y, w, h;
|
||||||
EPhysics_Body_Soft_Body_Data *soft_data;
|
|
||||||
|
|
||||||
soft_data = (EPhysics_Body_Soft_Body_Data *)malloc(
|
|
||||||
sizeof(EPhysics_Body_Soft_Body_Data));
|
|
||||||
if (!soft_data)
|
|
||||||
{
|
|
||||||
ERR("Could not allocate soft body data struct.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
soft_data->body = body;
|
|
||||||
soft_data->slices = NULL;
|
|
||||||
soft_data->base_obj = body->evas_obj;
|
|
||||||
|
|
||||||
|
body->soft_data->base_obj = body->evas_obj;
|
||||||
evas_object_geometry_get(body->evas_obj, &x, &y, &w, &h);
|
evas_object_geometry_get(body->evas_obj, &x, &y, &w, &h);
|
||||||
|
|
||||||
obj = evas_object_rectangle_add(evas_object_evas_get(body->evas_obj));
|
obj = evas_object_rectangle_add(evas_object_evas_get(body->evas_obj));
|
||||||
evas_object_color_set(obj, 0, 0, 0, 0);
|
evas_object_color_set(obj, 0, 0, 0, 0);
|
||||||
evas_object_move(obj, x, y);
|
evas_object_move(obj, x, y);
|
||||||
evas_object_resize(obj, w, h);
|
evas_object_resize(obj, w, h);
|
||||||
evas_object_data_set(obj, SOFT_DATA, soft_data);
|
evas_object_data_set(obj, BODY, body);
|
||||||
evas_object_show(obj);
|
evas_object_show(obj);
|
||||||
|
|
||||||
body->evas_obj = obj;
|
body->evas_obj = obj;
|
||||||
|
_ephysics_body_soft_body_slices_init(body);
|
||||||
if (!_ephysics_body_soft_body_slices_init(body, soft_data))
|
evas_object_move(body->soft_data->base_obj, 0, -h);
|
||||||
goto error;
|
|
||||||
|
|
||||||
evas_object_move(soft_data->base_obj, 0, -h);
|
|
||||||
|
|
||||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
|
||||||
_ephysics_body_soft_body_slices_apply, NULL);
|
_ephysics_body_soft_body_slices_apply, NULL);
|
||||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
|
||||||
_ephysics_body_soft_body_evas_del_cb, NULL);
|
_ephysics_body_soft_body_evas_del_cb, NULL);
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
free(soft_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Evas_Object *
|
|
||||||
_ephysics_body_soft_body_evas_base_obj_get(Evas_Object *obj)
|
|
||||||
{
|
|
||||||
EPhysics_Body_Soft_Body_Data *soft_data;
|
|
||||||
|
|
||||||
soft_data = (EPhysics_Body_Soft_Body_Data *)evas_object_data_get(obj,
|
|
||||||
SOFT_DATA);
|
|
||||||
return soft_data->base_obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static btTransform
|
static btTransform
|
||||||
|
@ -367,7 +380,6 @@ ephysics_body_evas_objects_restack(EPhysics_World *world)
|
||||||
EPhysics_Body *body;
|
EPhysics_Body *body;
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
EPhysics_Body_Evas_Stacking *stacking;
|
EPhysics_Body_Evas_Stacking *stacking;
|
||||||
EPhysics_Body_Soft_Body_Data *soft_data;
|
|
||||||
EPhysics_Body_Soft_Body_Slice *slice;
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
Eina_List *l, *slices, *bodies, *stack_list = NULL;
|
Eina_List *l, *slices, *bodies, *stack_list = NULL;
|
||||||
Evas_Object *prev_obj = NULL;
|
Evas_Object *prev_obj = NULL;
|
||||||
|
@ -380,8 +392,8 @@ ephysics_body_evas_objects_restack(EPhysics_World *world)
|
||||||
{
|
{
|
||||||
if (!body->evas_obj) continue;
|
if (!body->evas_obj) continue;
|
||||||
trans = _ephysics_body_transform_get(body);
|
trans = _ephysics_body_transform_get(body);
|
||||||
stacking = (EPhysics_Body_Evas_Stacking *)calloc(1,
|
stacking = (EPhysics_Body_Evas_Stacking *)calloc(
|
||||||
sizeof(EPhysics_Body_Evas_Stacking));
|
1, sizeof(EPhysics_Body_Evas_Stacking));
|
||||||
if (!stacking) goto error;
|
if (!stacking) goto error;
|
||||||
stacking->stacking = trans.getOrigin().z();
|
stacking->stacking = trans.getOrigin().z();
|
||||||
stacking->evas = body->evas_obj;
|
stacking->evas = body->evas_obj;
|
||||||
|
@ -389,16 +401,13 @@ ephysics_body_evas_objects_restack(EPhysics_World *world)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
soft_data = (EPhysics_Body_Soft_Body_Data *)evas_object_data_get(
|
if (!body->soft_data) continue;
|
||||||
body->evas_obj, SOFT_DATA);
|
|
||||||
|
|
||||||
if (!soft_data) continue;
|
EINA_LIST_FOREACH(body->soft_data->slices, slices, slice_data)
|
||||||
|
|
||||||
EINA_LIST_FOREACH(soft_data->slices, slices, slice_data)
|
|
||||||
{
|
{
|
||||||
slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
|
slice = (EPhysics_Body_Soft_Body_Slice *)slice_data;
|
||||||
stacking = (EPhysics_Body_Evas_Stacking *)calloc(1,
|
stacking = (EPhysics_Body_Evas_Stacking *)calloc(
|
||||||
sizeof(EPhysics_Body_Evas_Stacking));
|
1, sizeof(EPhysics_Body_Evas_Stacking));
|
||||||
if (!stacking) goto error;
|
if (!stacking) goto error;
|
||||||
stacking->stacking = slice->stacking;
|
stacking->stacking = slice->stacking;
|
||||||
stacking->evas = slice->evas_obj;
|
stacking->evas = slice->evas_obj;
|
||||||
|
@ -1448,10 +1457,11 @@ _ephysics_body_soft_body_add(EPhysics_World *world, btCollisionShape *collision_
|
||||||
_ephysics_body_soft_body_default_config(body, soft_body);
|
_ephysics_body_soft_body_default_config(body, soft_body);
|
||||||
|
|
||||||
body->rigid_body->setCollisionFlags(
|
body->rigid_body->setCollisionFlags(
|
||||||
btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||||
|
|
||||||
_ephysics_body_soft_body_constraints_rebuild(body);
|
_ephysics_body_soft_body_constraints_rebuild(body);
|
||||||
ephysics_world_soft_body_add(world, body);
|
ephysics_world_soft_body_add(world, body);
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,6 +1554,26 @@ ephysics_body_cloth_anchor_del(EPhysics_Body *body)
|
||||||
body->soft_body->m_anchors.resize(0);
|
body->soft_body->m_anchors.resize(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ephysics_body_slices_add(EPhysics_Body *body, double delta, double max)
|
||||||
|
{
|
||||||
|
EPhysics_Body_Soft_Body_Slice *slice;
|
||||||
|
btSoftBody::tFaceArray faces;
|
||||||
|
|
||||||
|
for (int i = 0; i < body->slices; i++)
|
||||||
|
{
|
||||||
|
faces = body->soft_body->m_faces;
|
||||||
|
|
||||||
|
slice = _ephysics_body_soft_body_slice_new(body, delta, max,
|
||||||
|
body->points_deform[i]);
|
||||||
|
if (!slice) return EINA_FALSE;
|
||||||
|
|
||||||
|
body->soft_data->slices = eina_list_append(body->soft_data->slices,
|
||||||
|
slice);
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI EPhysics_Body *
|
EAPI EPhysics_Body *
|
||||||
ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
|
ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
|
||||||
{
|
{
|
||||||
|
@ -1596,13 +1626,31 @@ ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
|
||||||
for (int i = 0; i < body->slices; i++)
|
for (int i = 0; i < body->slices; i++)
|
||||||
body->points_deform[i] = i;
|
body->points_deform[i] = i;
|
||||||
|
|
||||||
|
body->soft_data = _ephysics_body_soft_body_data_new(body);
|
||||||
|
if (!body->soft_data)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create soft data.");
|
||||||
|
goto no_soft_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ephysics_body_slices_add(body, -1, 1))
|
||||||
|
{
|
||||||
|
ERR("Couldn't create slices.");
|
||||||
|
goto no_slices;
|
||||||
|
}
|
||||||
|
|
||||||
body->cloth_columns = columns;
|
body->cloth_columns = columns;
|
||||||
body->cloth_rows = rows;
|
body->cloth_rows = rows;
|
||||||
body->type = EPHYSICS_BODY_TYPE_CLOTH;
|
body->type = EPHYSICS_BODY_TYPE_CLOTH;
|
||||||
|
|
||||||
ephysics_world_soft_body_add(world, body);
|
ephysics_world_soft_body_add(world, body);
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
|
|
||||||
|
no_slices:
|
||||||
|
free(body->soft_data);
|
||||||
|
no_soft_data:
|
||||||
|
free(body->points_deform);
|
||||||
no_deform:
|
no_deform:
|
||||||
free(body);
|
free(body);
|
||||||
no_body:
|
no_body:
|
||||||
|
@ -1788,15 +1836,32 @@ ephysics_body_soft_circle_add(EPhysics_World *world)
|
||||||
for (int i = 0; i < body->slices; i++)
|
for (int i = 0; i < body->slices; i++)
|
||||||
body->points_deform[i] = points[i];
|
body->points_deform[i] = points[i];
|
||||||
|
|
||||||
|
body->soft_data = _ephysics_body_soft_body_data_new(body);
|
||||||
|
if (!body->soft_data)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create soft data.");
|
||||||
|
goto no_soft_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ephysics_body_slices_add(body, 0.55, 1.1))
|
||||||
|
{
|
||||||
|
ERR("Couldn't create slices.");
|
||||||
|
goto no_slices;
|
||||||
|
}
|
||||||
|
|
||||||
ephysics_world_lock_release(world);
|
ephysics_world_lock_release(world);
|
||||||
return body;
|
return body;
|
||||||
|
|
||||||
|
no_slices:
|
||||||
|
free(body->soft_data);
|
||||||
|
no_soft_data:
|
||||||
|
free(body->points_deform);
|
||||||
|
no_deform:
|
||||||
|
ephysics_world_body_del(world, body);
|
||||||
no_body:
|
no_body:
|
||||||
delete soft_body;
|
delete soft_body;
|
||||||
no_soft_body:
|
no_soft_body:
|
||||||
delete shape;
|
delete shape;
|
||||||
no_deform:
|
|
||||||
ephysics_world_body_del(world, body);
|
|
||||||
no_collision_shape:
|
no_collision_shape:
|
||||||
ephysics_world_lock_release(world);
|
ephysics_world_lock_release(world);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1878,15 +1943,32 @@ ephysics_body_soft_box_add(EPhysics_World *world)
|
||||||
for (int i = 0; i < body->slices; i++)
|
for (int i = 0; i < body->slices; i++)
|
||||||
body->points_deform[i] = points[i];
|
body->points_deform[i] = points[i];
|
||||||
|
|
||||||
|
body->soft_data = _ephysics_body_soft_body_data_new(body);
|
||||||
|
if (!body->soft_data)
|
||||||
|
{
|
||||||
|
ERR("Couldn't create soft data.");
|
||||||
|
goto no_soft_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ephysics_body_slices_add(body, 0.55, 1.1))
|
||||||
|
{
|
||||||
|
ERR("Couldn't create slices.");
|
||||||
|
goto no_slices;
|
||||||
|
}
|
||||||
|
|
||||||
ephysics_world_lock_release(world);
|
ephysics_world_lock_release(world);
|
||||||
return body;
|
return body;
|
||||||
|
|
||||||
|
no_slices:
|
||||||
|
free(body->soft_data);
|
||||||
|
no_soft_data:
|
||||||
|
free(body->points_deform);
|
||||||
|
no_deform:
|
||||||
|
ephysics_world_body_del(world, body);
|
||||||
no_body:
|
no_body:
|
||||||
delete soft_body;
|
delete soft_body;
|
||||||
no_soft_body:
|
no_soft_body:
|
||||||
delete shape;
|
delete shape;
|
||||||
no_deform:
|
|
||||||
ephysics_world_body_del(world, body);
|
|
||||||
no_collision_shape:
|
no_collision_shape:
|
||||||
ephysics_world_lock_release(world);
|
ephysics_world_lock_release(world);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2221,32 +2303,30 @@ ephysics_body_evas_object_set(EPhysics_Body *body, Evas_Object *evas_obj, Eina_B
|
||||||
_ephysics_body_evas_obj_del_cb);
|
_ephysics_body_evas_obj_del_cb);
|
||||||
evas_object_event_callback_del(body->evas_obj, EVAS_CALLBACK_RESIZE,
|
evas_object_event_callback_del(body->evas_obj, EVAS_CALLBACK_RESIZE,
|
||||||
_ephysics_body_evas_obj_resize_cb);
|
_ephysics_body_evas_obj_resize_cb);
|
||||||
|
if (body->soft_data)
|
||||||
|
_ephysics_body_soft_body_slices_clean(body->soft_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
body->evas_obj = evas_obj;
|
body->evas_obj = evas_obj;
|
||||||
|
evas_object_geometry_get(body->evas_obj, &obj_x, &obj_y, &obj_w, &obj_h);
|
||||||
|
|
||||||
|
if (body->soft_body)
|
||||||
|
{
|
||||||
|
_ephysics_body_soft_body_evas_add(body);
|
||||||
|
evas_obj = body->evas_obj;
|
||||||
|
}
|
||||||
|
|
||||||
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL,
|
evas_object_event_callback_add(evas_obj, EVAS_CALLBACK_DEL,
|
||||||
_ephysics_body_evas_obj_del_cb, body);
|
_ephysics_body_evas_obj_del_cb, body);
|
||||||
|
|
||||||
if (!use_obj_pos)
|
if (!use_obj_pos)
|
||||||
return evas_obj;
|
return evas_obj;
|
||||||
|
|
||||||
evas_object_geometry_get(body->evas_obj, &obj_x, &obj_y, &obj_w, &obj_h);
|
|
||||||
rate = ephysics_world_rate_get(body->world);
|
rate = ephysics_world_rate_get(body->world);
|
||||||
ephysics_world_lock_take(body->world);
|
ephysics_world_lock_take(body->world);
|
||||||
_ephysics_body_geometry_set(body, obj_x, obj_y, - rate / 2,
|
_ephysics_body_geometry_set(body, obj_x, obj_y, - rate / 2,
|
||||||
obj_w, obj_h, rate, rate);
|
obj_w, obj_h, rate, rate);
|
||||||
|
|
||||||
if (body->soft_body)
|
|
||||||
{
|
|
||||||
evas_object_event_callback_del(evas_obj, EVAS_CALLBACK_DEL,
|
|
||||||
_ephysics_body_evas_obj_del_cb);
|
|
||||||
|
|
||||||
_ephysics_body_soft_body_evas_add(body);
|
|
||||||
evas_obj = body->evas_obj;
|
|
||||||
|
|
||||||
evas_object_event_callback_add(body->evas_obj, EVAS_CALLBACK_DEL,
|
|
||||||
_ephysics_body_evas_obj_del_cb, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
ephysics_world_lock_release(body->world);
|
ephysics_world_lock_release(body->world);
|
||||||
evas_object_event_callback_add(body->evas_obj, EVAS_CALLBACK_RESIZE,
|
evas_object_event_callback_add(body->evas_obj, EVAS_CALLBACK_RESIZE,
|
||||||
|
@ -2281,7 +2361,7 @@ ephysics_body_evas_object_unset(EPhysics_Body *body)
|
||||||
if (body->type != EPHYSICS_BODY_TYPE_RIGID)
|
if (body->type != EPHYSICS_BODY_TYPE_RIGID)
|
||||||
{
|
{
|
||||||
wrapper = obj;
|
wrapper = obj;
|
||||||
obj = _ephysics_body_soft_body_evas_base_obj_get(obj);
|
obj = body->soft_data->base_obj;
|
||||||
evas_object_del(wrapper);
|
evas_object_del(wrapper);
|
||||||
ephysics_body_geometry_get(body, &x, &y, NULL, NULL, NULL, NULL);
|
ephysics_body_geometry_get(body, &x, &y, NULL, NULL, NULL, NULL);
|
||||||
evas_object_move(obj, x, y);
|
evas_object_move(obj, x, y);
|
||||||
|
|
|
@ -49,6 +49,7 @@ extern "C" {
|
||||||
#define RAD_TO_DEG 57.29582 /* 2 * pi radians == 360 degree */
|
#define RAD_TO_DEG 57.29582 /* 2 * pi radians == 360 degree */
|
||||||
|
|
||||||
typedef struct _EPhysics_Point EPhysics_Point;
|
typedef struct _EPhysics_Point EPhysics_Point;
|
||||||
|
typedef struct _EPhysics_Body_Soft_Body_Data EPhysics_Body_Soft_Body_Data;
|
||||||
|
|
||||||
typedef enum _EPhysics_World_Boundary
|
typedef enum _EPhysics_World_Boundary
|
||||||
{
|
{
|
||||||
|
@ -113,6 +114,7 @@ struct _EPhysics_Body {
|
||||||
int cloth_columns;
|
int cloth_columns;
|
||||||
int cloth_rows;
|
int cloth_rows;
|
||||||
int material_index;
|
int material_index;
|
||||||
|
EPhysics_Body_Soft_Body_Data *soft_data;
|
||||||
struct {
|
struct {
|
||||||
int triangle;
|
int triangle;
|
||||||
double mass[3];
|
double mass[3];
|
||||||
|
|
Loading…
Reference in New Issue