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);
pentagon_shape = ephysics_shape_new();
ephysics_shape_point_add(pentagon_shape, -1, -9/33.);
ephysics_shape_point_add(pentagon_shape, 0, -1);
ephysics_shape_point_add(pentagon_shape, 1, -9/33.);
ephysics_shape_point_add(pentagon_shape, -21/35., 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, 0, -1, -1);
ephysics_shape_point_add(pentagon_shape, 0, -1, 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);
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);
hexagon_shape = ephysics_shape_new();
ephysics_shape_point_add(hexagon_shape, 0, 30);
ephysics_shape_point_add(hexagon_shape, 18, 0);
ephysics_shape_point_add(hexagon_shape, 52, 0);
ephysics_shape_point_add(hexagon_shape, 70, 30);
ephysics_shape_point_add(hexagon_shape, 52, 60);
ephysics_shape_point_add(hexagon_shape, 18, 60);
ephysics_shape_point_add(hexagon_shape, 0, 30, -10);
ephysics_shape_point_add(hexagon_shape, 0, 30, 10);
ephysics_shape_point_add(hexagon_shape, 18, 0, -10);
ephysics_shape_point_add(hexagon_shape, 18, 0, 10);
ephysics_shape_point_add(hexagon_shape, 52, 0, -10);
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);
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
* EPhysics_Shape *shape = ephysics_shape_new();
*
* ephysics_shape_point_add(shape, 0, 24);
* ephysics_shape_point_add(shape, 35, 0);
* ephysics_shape_point_add(shape, 70, 24);
* ephysics_shape_point_add(shape, 56, 66);
* ephysics_shape_point_add(shape, 14, 66);
* ephysics_shape_point_add(shape, 0, 24, -10);
* ephysics_shape_point_add(shape, 0, 24, 10);
* ephysics_shape_point_add(shape, 35, 0, -10);
* ephysics_shape_point_add(shape, 35, 0, 10);
* 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);
*
@ -228,13 +233,14 @@ EAPI void ephysics_shape_del(EPhysics_Shape *shape);
* @param shape The shape to be modified.
* @param x Point position at x 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.
*
* @see ephysics_shape_new().
*
* @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
@ -1765,7 +1771,7 @@ EAPI void ephysics_body_cloth_anchor_del(EPhysics_Body *body);
* @ref ephysics_shape_new().
*
* 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
* @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.
*
* 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
* center of mass x component = 20 and y component = 10, it will return
* @p x = 0.666 and @p y = 0.5.
* If a body of width = 30, height = 20 and depth = 20, and has the center of
* mass at x component = 20, y component = 10 and z = 10, it will return
* @p x = 0.666, @p y = 0.5 and @z = 0.5.
*
* 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
* with custom shapes.
@ -3058,12 +3064,13 @@ EAPI void ephysics_body_forces_clear(EPhysics_Body *body);
* @param body The physics body.
* @param x The axis x 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().
*
* @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

View File

@ -633,7 +633,7 @@ ephysics_body_collision_group_list_get(const EPhysics_Body *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;
@ -648,12 +648,13 @@ _ephysics_body_new(EPhysics_World *world, btScalar mass, double cm_x, double cm_
body->world = world;
body->cm.x = cm_x;
body->cm.y = cm_y;
body->cm.z = cm_z;
return 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;
btDefaultMotionState *motion_state;
@ -668,7 +669,7 @@ _ephysics_body_rigid_body_add(EPhysics_World *world, btCollisionShape *collision
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)
{
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;
body = _ephysics_body_rigid_body_add(world, collision_shape, "soft box", 0.5,
0.5);
0.5, 0.5);
if (!body)
{
if (body->deleted) return NULL;
@ -1411,7 +1412,7 @@ ephysics_body_cloth_add(EPhysics_World *world, unsigned short granularity)
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)
goto no_body;
@ -1530,7 +1531,7 @@ ephysics_body_circle_add(EPhysics_World *world)
ephysics_world_lock_take(world);
body = _ephysics_body_rigid_body_add(world, collision_shape, "circle", 0.5,
0.5);
0.5, 0.5);
ephysics_world_lock_release(world);
return body;
}
@ -1614,7 +1615,8 @@ ephysics_body_box_add(EPhysics_World *world)
collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
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);
return body;
}
@ -1622,7 +1624,8 @@ ephysics_body_box_add(EPhysics_World *world)
EAPI EPhysics_Body *
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;
btAlignedObjectArray<btVector3> vertexes, planes;
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);
max_x = min_x = point->x;
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 */
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->y > max_y) max_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_y += point->y;
cm_z += point->z;
}
cm_x /= eina_inlist_count(points);
cm_y /= eina_inlist_count(points);
cm_z /= eina_inlist_count(points);
range_x = max_x - min_x;
range_y = max_y - min_y;
range_z = max_z - min_z;
EINA_INLIST_FOREACH(points, point)
{
double x, y;
double x, y, z;
x = (point->x - cm_x) / range_x;
y = - (point->y - cm_y) / range_y;
z = (point->z - cm_z) / range_z;
point3d = btVector3(x, y, -0.5);
vertexes.push_back(point3d);
point3d = btVector3(x, y, 0.5);
point3d = btVector3(x, y, z);
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,
(btCollisionShape *)simplified_shape,
"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);
return body;
}
@ -2723,7 +2731,7 @@ ephysics_body_forces_clear(EPhysics_Body *body)
}
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)
{
@ -2733,6 +2741,7 @@ ephysics_body_center_mass_get(const EPhysics_Body *body, double *x, double *y)
if (x) *x = body->cm.x;
if (y) *y = body->cm.y;
if (z) *z = body->cm.z;
}
EAPI void

View File

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

View File

@ -70,7 +70,7 @@ ephysics_shape_del(EPhysics_Shape *shape)
}
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;
@ -86,6 +86,7 @@ ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y)
point->x = x;
point->y = y;
point->z = z;
shape->points = eina_inlist_append(shape->points, EINA_INLIST_GET(point));