ephysics: add new 3d shapes

Instead of creating it from 2d shapes.
Bad news is that for some cases basically points will need to
be kind of duplicated.



SVN revision: 77783
This commit is contained in:
Bruno Dilly 2012-10-10 19:17:54 +00:00
parent 59cc6c6f2f
commit f75457d4b9
5 changed files with 71 additions and 41 deletions

View File

@ -20,11 +20,16 @@ _world_populate(Test_Data *test_data)
test_data->evas_objs = eina_list_append(test_data->evas_objs, pentagon); test_data->evas_objs = eina_list_append(test_data->evas_objs, pentagon);
pentagon_shape = ephysics_shape_new(); pentagon_shape = ephysics_shape_new();
ephysics_shape_point_add(pentagon_shape, -1, -9/33.); ephysics_shape_point_add(pentagon_shape, -1, -9/33., -1);
ephysics_shape_point_add(pentagon_shape, 0, -1); ephysics_shape_point_add(pentagon_shape, -1, -9/33., 1);
ephysics_shape_point_add(pentagon_shape, 1, -9/33.); ephysics_shape_point_add(pentagon_shape, 0, -1, -1);
ephysics_shape_point_add(pentagon_shape, -21/35., 1); ephysics_shape_point_add(pentagon_shape, 0, -1, 1);
ephysics_shape_point_add(pentagon_shape, 21/35., 1); ephysics_shape_point_add(pentagon_shape, 1, -9/33., -1);
ephysics_shape_point_add(pentagon_shape, 1, -9/33., 1);
ephysics_shape_point_add(pentagon_shape, -21/35., 1, -1);
ephysics_shape_point_add(pentagon_shape, -21/35., 1, 1);
ephysics_shape_point_add(pentagon_shape, 21/35., 1, -1);
ephysics_shape_point_add(pentagon_shape, 21/35., 1, 1);
pentagon_body = ephysics_body_shape_add(test_data->world, pentagon_shape); pentagon_body = ephysics_body_shape_add(test_data->world, pentagon_shape);
ephysics_body_evas_object_set(pentagon_body, pentagon, EINA_TRUE); ephysics_body_evas_object_set(pentagon_body, pentagon, EINA_TRUE);
@ -40,12 +45,18 @@ _world_populate(Test_Data *test_data)
test_data->evas_objs = eina_list_append(test_data->evas_objs, hexagon); test_data->evas_objs = eina_list_append(test_data->evas_objs, hexagon);
hexagon_shape = ephysics_shape_new(); hexagon_shape = ephysics_shape_new();
ephysics_shape_point_add(hexagon_shape, 0, 30); ephysics_shape_point_add(hexagon_shape, 0, 30, -10);
ephysics_shape_point_add(hexagon_shape, 18, 0); ephysics_shape_point_add(hexagon_shape, 0, 30, 10);
ephysics_shape_point_add(hexagon_shape, 52, 0); ephysics_shape_point_add(hexagon_shape, 18, 0, -10);
ephysics_shape_point_add(hexagon_shape, 70, 30); ephysics_shape_point_add(hexagon_shape, 18, 0, 10);
ephysics_shape_point_add(hexagon_shape, 52, 60); ephysics_shape_point_add(hexagon_shape, 52, 0, -10);
ephysics_shape_point_add(hexagon_shape, 18, 60); ephysics_shape_point_add(hexagon_shape, 52, 0, 10);
ephysics_shape_point_add(hexagon_shape, 70, 30, -10);
ephysics_shape_point_add(hexagon_shape, 70, 30, 10);
ephysics_shape_point_add(hexagon_shape, 52, 60, -10);
ephysics_shape_point_add(hexagon_shape, 52, 60, 10);
ephysics_shape_point_add(hexagon_shape, 18, 60, -10);
ephysics_shape_point_add(hexagon_shape, 18, 60, 10);
hexagon_body = ephysics_body_shape_add(test_data->world, hexagon_shape); hexagon_body = ephysics_body_shape_add(test_data->world, hexagon_shape);
ephysics_body_evas_object_set(hexagon_body, hexagon, EINA_TRUE); ephysics_body_evas_object_set(hexagon_body, hexagon, EINA_TRUE);

View File

@ -214,11 +214,16 @@ EAPI void ephysics_shape_del(EPhysics_Shape *shape);
* @code * @code
* EPhysics_Shape *shape = ephysics_shape_new(); * EPhysics_Shape *shape = ephysics_shape_new();
* *
* ephysics_shape_point_add(shape, 0, 24); * ephysics_shape_point_add(shape, 0, 24, -10);
* ephysics_shape_point_add(shape, 35, 0); * ephysics_shape_point_add(shape, 0, 24, 10);
* ephysics_shape_point_add(shape, 70, 24); * ephysics_shape_point_add(shape, 35, 0, -10);
* ephysics_shape_point_add(shape, 56, 66); * ephysics_shape_point_add(shape, 35, 0, 10);
* ephysics_shape_point_add(shape, 14, 66); * ephysics_shape_point_add(shape, 70, 24, -10);
* ephysics_shape_point_add(shape, 70, 24, 10);
* ephysics_shape_point_add(shape, 56, 66, -10);
* ephysics_shape_point_add(shape, 56, 66, 10);
* ephysics_shape_point_add(shape, 14, 66, -10);
* ephysics_shape_point_add(shape, 14, 66, 10);
* *
* ephysics_body_shape_add(world, shape); * ephysics_body_shape_add(world, shape);
* *
@ -228,13 +233,14 @@ EAPI void ephysics_shape_del(EPhysics_Shape *shape);
* @param shape The shape to be modified. * @param shape The shape to be modified.
* @param x Point position at x axis. * @param x Point position at x axis.
* @param y Point position at y axis. * @param y Point position at y axis.
* @param z Point position at z axis.
* @return @c EINA_TRUE on success or EINA_FALSE on error. * @return @c EINA_TRUE on success or EINA_FALSE on error.
* *
* @see ephysics_shape_new(). * @see ephysics_shape_new().
* *
* @ingroup EPhysics_Shape * @ingroup EPhysics_Shape
*/ */
EAPI Eina_Bool ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y); EAPI Eina_Bool ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y, double z);
/** /**
* @brief * @brief
@ -1765,7 +1771,7 @@ EAPI void ephysics_body_cloth_anchor_del(EPhysics_Body *body);
* @ref ephysics_shape_new(). * @ref ephysics_shape_new().
* *
* To change it's size @ref ephysics_body_geometry_set() should be used, * To change it's size @ref ephysics_body_geometry_set() should be used,
* so it can be deformed on x and y axes. * so it can be deformed on x, y and z axes.
* *
* The center of mass of this body can be get with * The center of mass of this body can be get with
* @ref ephysics_body_center_mass_get(). * @ref ephysics_body_center_mass_get().
@ -3043,14 +3049,14 @@ EAPI void ephysics_body_forces_clear(EPhysics_Body *body);
* Get the center of mass of physics body. * Get the center of mass of physics body.
* *
* It returns a value from 0 to 1 representing where is the center of the mass * It returns a value from 0 to 1 representing where is the center of the mass
* considering the height and width of the body. * considering the height, width and depth of the body.
* *
* If a body of width = 30 and height = 20 has the center of mass at * If a body of width = 30, height = 20 and depth = 20, and has the center of
* center of mass x component = 20 and y component = 10, it will return * mass at x component = 20, y component = 10 and z = 10, it will return
* @p x = 0.666 and @p y = 0.5. * @p x = 0.666, @p y = 0.5 and @z = 0.5.
* *
* For primitive shapes, like box and circle, the center of mass * For primitive shapes, like box and circle, the center of mass
* is (0.5, 0.5). * is (0.5, 0.5, 0.5).
* *
* This function can be useful when updating evas objects for bodies * This function can be useful when updating evas objects for bodies
* with custom shapes. * with custom shapes.
@ -3058,12 +3064,13 @@ EAPI void ephysics_body_forces_clear(EPhysics_Body *body);
* @param body The physics body. * @param body The physics body.
* @param x The axis x component of center of mass. * @param x The axis x component of center of mass.
* @param y The axis y component of center of mass. * @param y The axis y component of center of mass.
* @param z The axis z component of center of mass.
* *
* @see ephysics_body_shape_add(). * @see ephysics_body_shape_add().
* *
* @ingroup EPhysics_Body * @ingroup EPhysics_Body
*/ */
EAPI void ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y); EAPI void ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y, double *z);
/** /**
* @brief * @brief

View File

@ -633,7 +633,7 @@ ephysics_body_collision_group_list_get(const EPhysics_Body *body)
} }
static EPhysics_Body * static EPhysics_Body *
_ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_y) _ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_y, double cm_z)
{ {
EPhysics_Body *body; EPhysics_Body *body;
@ -648,12 +648,13 @@ _ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_
body->world = world; body->world = world;
body->cm.x = cm_x; body->cm.x = cm_x;
body->cm.y = cm_y; body->cm.y = cm_y;
body->cm.z = cm_z;
return body; return body;
} }
static EPhysics_Body * static EPhysics_Body *
_ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y) _ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y, double cm_z)
{ {
btRigidBody::btRigidBodyConstructionInfo *rigid_body_ci; btRigidBody::btRigidBodyConstructionInfo *rigid_body_ci;
btDefaultMotionState *motion_state; btDefaultMotionState *motion_state;
@ -668,7 +669,7 @@ _ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision
return NULL; return NULL;
} }
body = _ephysics_body_new(world, mass, cm_x, cm_y); body = _ephysics_body_new(world, mass, cm_x, cm_y, cm_z);
if (!body) if (!body)
{ {
ERR("Couldn't create a new body instance."); ERR("Couldn't create a new body instance.");
@ -1273,7 +1274,7 @@ _ephysics_body_soft_body_add(EPhysics_World *world, btCollisionShape *collision_
EPhysics_Body *body; EPhysics_Body *body;
body = _ephysics_body_rigid_body_add(world, collision_shape, "soft box", 0.5, body = _ephysics_body_rigid_body_add(world, collision_shape, "soft box", 0.5,
0.5); 0.5, 0.5);
if (!body) if (!body)
{ {
if (body->deleted) return NULL; if (body->deleted) return NULL;
@ -1411,7 +1412,7 @@ ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
return NULL; return NULL;
} }
body = _ephysics_body_new(world, 1, 0.5, 0.5); body = _ephysics_body_new(world, 1, 0.5, 0.5, 0.5);
if (!body) if (!body)
goto no_body; goto no_body;
@ -1530,7 +1531,7 @@ ephysics_body_circle_add(EPhysics_World *world)
ephysics_world_lock_take(world); ephysics_world_lock_take(world);
body = _ephysics_body_rigid_body_add(world, collision_shape, "circle", 0.5, body = _ephysics_body_rigid_body_add(world, collision_shape, "circle", 0.5,
0.5); 0.5, 0.5);
ephysics_world_lock_release(world); ephysics_world_lock_release(world);
return body; return body;
} }
@ -1614,7 +1615,8 @@ ephysics_body_box_add(EPhysics_World *world)
collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
ephysics_world_lock_take(world); ephysics_world_lock_take(world);
body = _ephysics_body_rigid_body_add(world, collision_shape, "box", 0.5, 0.5); body = _ephysics_body_rigid_body_add(world, collision_shape, "box", 0.5,
0.5, 0.5);
ephysics_world_lock_release(world); ephysics_world_lock_release(world);
return body; return body;
} }
@ -1622,7 +1624,8 @@ ephysics_body_box_add(EPhysics_World *world)
EAPI EPhysics_Body * EAPI EPhysics_Body *
ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape) ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
{ {
double max_x, max_y, min_x, min_y, cm_x, cm_y, range_x, range_y; double max_x, max_y, max_z, min_x, min_y, min_z, cm_x, cm_y, cm_z,
range_x, range_y, range_z;
btConvexHullShape *full_shape, *simplified_shape; btConvexHullShape *full_shape, *simplified_shape;
btAlignedObjectArray<btVector3> vertexes, planes; btAlignedObjectArray<btVector3> vertexes, planes;
const Eina_Inlist *points; const Eina_Inlist *points;
@ -1662,7 +1665,8 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
point = EINA_INLIST_CONTAINER_GET(points, EPhysics_Point); point = EINA_INLIST_CONTAINER_GET(points, EPhysics_Point);
max_x = min_x = point->x; max_x = min_x = point->x;
max_y = min_y = point->y; max_y = min_y = point->y;
cm_x = cm_y = 0; max_z = min_z = point->z;
cm_x = cm_y = cm_z = 0;
/* FIXME : only vertices should be used to calculate the center of mass */ /* FIXME : only vertices should be used to calculate the center of mass */
EINA_INLIST_FOREACH(points, point) EINA_INLIST_FOREACH(points, point)
@ -1671,27 +1675,30 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
if (point->x < min_x) min_x = point->x; if (point->x < min_x) min_x = point->x;
if (point->y > max_y) max_y = point->y; if (point->y > max_y) max_y = point->y;
if (point->y < min_y) min_y = point->y; if (point->y < min_y) min_y = point->y;
if (point->z > max_z) max_z = point->z;
if (point->z < min_z) min_z = point->z;
cm_x += point->x; cm_x += point->x;
cm_y += point->y; cm_y += point->y;
cm_z += point->z;
} }
cm_x /= eina_inlist_count(points); cm_x /= eina_inlist_count(points);
cm_y /= eina_inlist_count(points); cm_y /= eina_inlist_count(points);
cm_z /= eina_inlist_count(points);
range_x = max_x - min_x; range_x = max_x - min_x;
range_y = max_y - min_y; range_y = max_y - min_y;
range_z = max_z - min_z;
EINA_INLIST_FOREACH(points, point) EINA_INLIST_FOREACH(points, point)
{ {
double x, y; double x, y, z;
x = (point->x - cm_x) / range_x; x = (point->x - cm_x) / range_x;
y = - (point->y - cm_y) / range_y; y = - (point->y - cm_y) / range_y;
z = (point->z - cm_z) / range_z;
point3d = btVector3(x, y, -0.5); point3d = btVector3(x, y, z);
vertexes.push_back(point3d);
point3d = btVector3(x, y, 0.5);
vertexes.push_back(point3d); vertexes.push_back(point3d);
} }
@ -1732,7 +1739,8 @@ ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
body = _ephysics_body_rigid_body_add(world, body = _ephysics_body_rigid_body_add(world,
(btCollisionShape *)simplified_shape, (btCollisionShape *)simplified_shape,
"generic", (cm_x - min_x) / range_x, "generic", (cm_x - min_x) / range_x,
1 - (cm_y - min_y) / range_y); 1 - (cm_y - min_y) / range_y,
(cm_z - min_z) / range_z);
ephysics_world_lock_release(world); ephysics_world_lock_release(world);
return body; return body;
} }
@ -2723,7 +2731,7 @@ ephysics_body_forces_clear(EPhysics_Body *body)
} }
EAPI void EAPI void
ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y) ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y, double *z)
{ {
if (!body) if (!body)
{ {
@ -2733,6 +2741,7 @@ ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y)
if (x) *x = body->cm.x; if (x) *x = body->cm.x;
if (y) *y = body->cm.y; if (y) *y = body->cm.y;
if (z) *z = body->cm.z;
} }
EAPI void EAPI void

View File

@ -63,6 +63,7 @@ struct _EPhysics_Point {
EINA_INLIST; EINA_INLIST;
double x; double x;
double y; double y;
double z;
}; };
typedef enum _EPhysics_Body_Type typedef enum _EPhysics_Body_Type
@ -101,6 +102,7 @@ struct _EPhysics_Body {
struct { struct {
double x; double x;
double y; double y;
double z;
} cm; } cm;
Eina_Bool active:1; Eina_Bool active:1;
Eina_Bool deleted:1; Eina_Bool deleted:1;

View File

@ -70,7 +70,7 @@ ephysics_shape_del(EPhysics_Shape *shape)
} }
EAPI Eina_Bool EAPI Eina_Bool
ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y) ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y, double z)
{ {
EPhysics_Point *point; EPhysics_Point *point;
@ -86,6 +86,7 @@ ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y)
point->x = x; point->x = x;
point->y = y; point->y = y;
point->z = z;
shape->points = eina_inlist_append(shape->points, EINA_INLIST_GET(point)); shape->points = eina_inlist_append(shape->points, EINA_INLIST_GET(point));