Center of these shapes were wrong, now it's much better.
But collision still seems a bit inaccurate.
SVN revision: 75572
{
EPhysics_Shape *pentagon_shape, *hexagon_shape;
EPhysics_Body *pentagon_body, *hexagon_body;
- EPhysics_Constraint *constraint;
Evas_Object *pentagon, *hexagon;
pentagon = elm_image_add(test_data->win);
elm_image_file_set(
pentagon, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "pentagon");
evas_object_move(pentagon, WIDTH / 3, HEIGHT / 2 - 30);
- evas_object_resize(pentagon, 70, 66);
+ evas_object_resize(pentagon, 70, 68);
evas_object_show(pentagon);
test_data->evas_objs = eina_list_append(test_data->evas_objs, pentagon);
pentagon_shape = ephysics_shape_new();
- ephysics_shape_point_add(pentagon_shape, 0/70., 24/66.);
- ephysics_shape_point_add(pentagon_shape, 35/70., 0/66.);
- ephysics_shape_point_add(pentagon_shape, 70/70., 24/66.);
- ephysics_shape_point_add(pentagon_shape, 56/70., 66/66.);
- ephysics_shape_point_add(pentagon_shape, 14/70., 66/66.);
+ 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);
pentagon_body = ephysics_body_shape_add(test_data->world, pentagon_shape);
ephysics_body_evas_object_set(pentagon_body, pentagon, EINA_TRUE);
ephysics_body_restitution_set(pentagon_body, 1);
- ephysics_body_friction_set(pentagon_body, 0);
test_data->bodies = eina_list_append(test_data->bodies, pentagon_body);
hexagon = elm_image_add(test_data->win);
elm_image_file_set(
hexagon, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "hexagon");
- evas_object_move(hexagon, WIDTH / 3 + 80, HEIGHT / 2 - 30 + 35);
+ evas_object_move(hexagon, WIDTH / 3 + 80, HEIGHT / 2 - 30);
evas_object_resize(hexagon, 70, 60);
evas_object_show(hexagon);
test_data->evas_objs = eina_list_append(test_data->evas_objs, hexagon);
hexagon_shape = ephysics_shape_new();
- ephysics_shape_point_add(hexagon_shape, 0, 0.5);
- ephysics_shape_point_add(hexagon_shape, 18/70., 0);
- ephysics_shape_point_add(hexagon_shape, 52/70., 0);
- ephysics_shape_point_add(hexagon_shape, 1, 0.5);
- ephysics_shape_point_add(hexagon_shape, 52/70., 1);
- ephysics_shape_point_add(hexagon_shape, 18/70., 1);
+ 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);
hexagon_body = ephysics_body_shape_add(test_data->world, hexagon_shape);
- ephysics_body_mass_set(hexagon_body, 5);
ephysics_body_evas_object_set(hexagon_body, hexagon, EINA_TRUE);
ephysics_body_restitution_set(hexagon_body, 1);
- ephysics_body_friction_set(hexagon_body, 0);
test_data->bodies = eina_list_append(test_data->bodies, hexagon_body);
- constraint = ephysics_constraint_p2p_add(pentagon_body, NULL, 8, 0,
- 0, 0);
- test_data->constraints = eina_list_append(test_data->constraints,
- constraint);
-
- constraint = ephysics_constraint_p2p_add(hexagon_body, NULL, 0, 0, 0, 0);
- test_data->constraints = eina_list_append(test_data->constraints,
- constraint);
-
- ephysics_body_torque_impulse_apply(pentagon_body, 2);
-
ephysics_shape_del(pentagon_shape);
ephysics_shape_del(hexagon_shape);
-
- ephysics_world_serialize(test_data->world, "/tmp/test.bullet");
}
static void
void
test_shapes(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
+ EPhysics_Body *boundary;
EPhysics_World *world;
Test_Data *test_data;
ephysics_world_render_geometry_set(world, 50, 40, WIDTH - 100, FLOOR_Y - 40);
test_data->world = world;
+ boundary = ephysics_body_bottom_boundary_add(test_data->world);
+ ephysics_body_restitution_set(boundary, 0.65);
+
+ ephysics_body_top_boundary_add(test_data->world);
+ ephysics_body_left_boundary_add(test_data->world);
+ ephysics_body_right_boundary_add(test_data->world);
+
_world_populate(test_data);
}
* geometric shapes. The final shape will be constructed in such a way
* it will have all the added points and will be convex.
*
+ * The center of mass will be the centroid, or geometric center of the
+ * shape.
+ *
* The order of points doesn't matter.
*
* For example, to create a pentagon:
* @code
* EPhysics_Shape *shape = ephysics_shape_new();
*
- * ephysics_shape_point_add(shape, 0/70., 24/66.);
- * ephysics_shape_point_add(shape, 35/70., 0/66.);
- * ephysics_shape_point_add(shape, 70/70., 24/66.);
- * ephysics_shape_point_add(shape, 56/70., 66/66.);
- * ephysics_shape_point_add(shape, 14/70., 66/66.);
+ * 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_body_shape_add(world, shape);
*
* @endcode
*
* @param shape The shape to be modified.
- * @param x Point position at x axis. Should be a value between 0 and 1.
- * @param y Point position at y axis. Should be a value between 0 and 1.
+ * @param x Point position at x axis.
+ * @param y Point position at y axis.
* @return @c EINA_TRUE on success or EINA_FALSE on error.
*
* @see ephysics_shape_new().
}
static EPhysics_Body *
-_ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type)
+_ephysics_body_add(EPhysics_World *world, btCollisionShape *collision_shape, const char *type, double cm_x, double cm_y)
{
btRigidBody::btRigidBodyConstructionInfo *rigid_body_ci;
btDefaultMotionState *motion_state;
body->rigid_body = rigid_body;
body->mass = mass;
body->world = world;
+ body->cm.x = cm_x;
+ body->cm.y = cm_y;
body->rigid_body->setUserPointer(body);
body->rigid_body->setLinearFactor(btVector3(1, 1, 0));
body->rigid_body->setAngularFactor(btVector3(0, 0, 1));
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
height += wy;
- mx = (x + body->w / 2) / rate;
- my = (height - (y + body->h / 2)) / rate;
+ mx = (x + body->w * body->cm.x) / rate;
+ my = (height - (y + body->h * body->cm.y)) / rate;
body->rigid_body->getMotionState()->getWorldTransform(trans);
trans.setOrigin(btVector3(mx, my, 0));
ephysics_world_render_geometry_get(body->world, NULL, &wy, NULL, &height);
height += wy;
- mx = (x + w / 2) / rate;
- my = (height - (y + h / 2)) / rate;
+ mx = (x + w * body->cm.x) / rate;
+ my = (height - (y + h * body->cm.y)) / rate;
sx = w / rate;
sy = h / rate;
evas_object_geometry_get(body->evas_obj, NULL, NULL, &w, &h);
rate = ephysics_world_rate_get(body->world);
- x = (int) (trans.getOrigin().getX() * rate) - w / 2 - cx;
- y = wh + wy - (int) (trans.getOrigin().getY() * rate) - h / 2 - cy;
+ x = (int) (trans.getOrigin().getX() * rate) - w * body->cm.x - cx;
+ y = wh + wy - (int) (trans.getOrigin().getY() * rate) - h * body->cm.y - cy;
evas_object_move(body->evas_obj, x, y);
if (body->soft_body)
_ephysics_body_soft_body_deform(body, rate, map);
- evas_map_util_rotate(map, rot, x + (w / 2), y + (h / 2));
+ evas_map_util_rotate(map, rot, x + (w * body->cm.x), y +
+ (h * body->cm.y));
evas_object_map_set(body->evas_obj, map);
evas_object_map_enable_set(body->evas_obj, EINA_TRUE);
evas_map_free(map);
btSoftBody::AJoint::Specs angular_joint;
btSoftBody::LJoint::Specs linear_joint;
- body = _ephysics_body_add(world, collision_shape, "soft box");
+ body = _ephysics_body_add(world, collision_shape, "soft box", 0.5, 0.5);
if (!body)
{
ephysics_body_del(body);
body->soft_body->getCollisionShape()->setMargin(0.22);
- soft_body->m_materials[0]->m_kLST = 0.35;
+ soft_body->m_materials[0]->m_kLST = 0.35;
soft_body->setPose(true, false);
body->soft_body->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
return NULL;
}
- return _ephysics_body_add(world, collision_shape, "circle");
+ return _ephysics_body_add(world, collision_shape, "circle", 0.5, 0.5);
}
EAPI EPhysics_Body *
collision_shape = new btBoxShape(btVector3(0.5, 0.5, 0.5));
- return _ephysics_body_add(world, collision_shape, "box");
+ return _ephysics_body_add(world, collision_shape, "box", 0.5, 0.5);
}
EAPI EPhysics_Body *
ephysics_body_shape_add(EPhysics_World *world, EPhysics_Shape *shape)
{
btConvexHullShape *full_shape, *simplified_shape;
+ double max_x, max_y, min_x, min_y, cm_x, cm_y, range_x, range_y;
const Eina_Inlist *points;
EPhysics_Point *point;
btShapeHull *hull;
return NULL;
}
+ points = ephysics_shape_points_get(shape);
+ if (eina_inlist_count(points) < 3)
+ {
+ ERR("At least 3 points are required to add a shape");
+ return NULL;
+ }
+
full_shape = new btConvexHullShape();
if (!full_shape)
{
return NULL;
}
- points = ephysics_shape_points_get(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;
+
+ /* FIXME : only vertices should be used to calculate the center of mass */
+ EINA_INLIST_FOREACH(points, point)
+ {
+ if (point->x > max_x) max_x = point->x;
+ 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;
+
+ cm_x += point->x;
+ cm_y += point->y;
+ }
+
+ cm_x /= eina_inlist_count(points);
+ cm_y /= eina_inlist_count(points);
+ range_x = max_x - min_x;
+ range_y = max_y - min_y;
EINA_INLIST_FOREACH(points, point)
{
- point3d = btVector3(point->x, point->y, 0);
+ double x, y;
+
+ x = (point->x - cm_x) / range_x;
+ y = - (point->y - cm_y) / range_y;
+
+ point3d = btVector3(x, y, -0.5);
full_shape->addPoint(point3d);
- point3d = btVector3(point->x, point->y, 0.5);
+
+ point3d = btVector3(x, y, 0.5);
full_shape->addPoint(point3d);
}
hull = new btShapeHull(full_shape);
+ if (!hull)
+ {
+ delete full_shape;
+ ERR("Couldn't create a shape hull.");
+ return NULL;
+ }
+
margin = full_shape->getMargin();
hull->buildHull(margin);
simplified_shape = new btConvexHullShape(&(hull->getVertexPointer()->getX()),
hull->numVertices());
+ delete hull;
+ delete full_shape;
+ if (!simplified_shape)
+ {
+ ERR("Couldn't create a simplified shape.");
+ return NULL;
+ }
return _ephysics_body_add(world, (btCollisionShape *)simplified_shape,
- "generic");
+ "generic", (cm_x - min_x) / range_x,
+ 1 - (cm_y - min_y) / range_y);
}
void
double y;
double torque;
} force;
+ struct {
+ double x;
+ double y;
+ } cm;
Eina_Bool active:1;
Eina_Bool deleted:1;
double distances[4][3];
return EINA_FALSE;;
}
- if ((x < 0) || (x > 1) || (y < 0) || (y > 1))
- {
- ERR("Points should be between 0 and 1.");
- return EINA_FALSE;
- }
-
point = _ephysics_shape_point_new();
if (!point)
return EINA_FALSE;;