forked from enlightenment/efl
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:
parent
59cc6c6f2f
commit
f75457d4b9
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in New Issue