forked from enlightenment/efl
EPhysics: add EPhysics Shape
It will be used to create bodies with collision shapes other than boxes or circles. For now, only convex shapes. SVN revision: 75151
This commit is contained in:
parent
2497491440
commit
6c53875522
|
@ -21,6 +21,7 @@
|
|||
* @li @ref EPhysics_Body
|
||||
* @li @ref EPhysics_Camera
|
||||
* @li @ref EPhysics_Constraint
|
||||
* @li @ref EPhysics_Shape
|
||||
*
|
||||
* Please see the @ref authors page for contact details.
|
||||
*/
|
||||
|
@ -119,6 +120,166 @@ EAPI int ephysics_shutdown(void);
|
|||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EPhysics_Shape EPhysics Shape
|
||||
* @ingroup EPhysics
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* Shapes are used to create bodies with shapes that differ from primitive
|
||||
* ones, like box and circle.
|
||||
*
|
||||
* A shape consists in a group of points, the vertices of the body to be
|
||||
* created later with @ref ephysics_body_shape_add().
|
||||
*
|
||||
* A new shape is created with @ref ephysics_shape_new() and points are
|
||||
* set with @ref ephysics_shape_point_add(). A shape can be used to
|
||||
* create many bodies. When done, it's required to delete the shape
|
||||
* with @ref ephysics_shape_del().
|
||||
*
|
||||
* A shape can be load from a file describing it with
|
||||
* @ref ephysics_shape_load(), and can be saved to a file with
|
||||
* @ref ephysics_shape_save(). With that shapes can be done or visualized
|
||||
* on design applications.
|
||||
*
|
||||
* @note Using primitive shapes has better perfomance than generic shapes.
|
||||
* @note For now, only convex shapes are supported.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef EPhysics_Shape
|
||||
*
|
||||
* Shape handle, represents a shape to be used to create a body.
|
||||
*
|
||||
* Created with @ref ephysics_shape_new() and deleted with
|
||||
* @ref ephysics_shape_del().
|
||||
*
|
||||
* @ingroup EPhysics_Shape
|
||||
*/
|
||||
typedef struct _EPhysics_Shape EPhysics_Shape;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Create a new shape.
|
||||
*
|
||||
* The returned shape initially doesn't has points set, so it's required
|
||||
* to set vertices with @ref ephysics_shape_point_add().
|
||||
*
|
||||
* After the shape is completelly defined, all the points were added,
|
||||
* it's possible to create one or more bodies with
|
||||
* @ref ephysics_body_shape_add().
|
||||
*
|
||||
* @return The created shape or @c NULL on error.
|
||||
*
|
||||
* @see ephysics_shape_del().
|
||||
* @see ephysics_shape_load().
|
||||
*
|
||||
* @ingroup EPhysics_Shape
|
||||
*/
|
||||
EAPI EPhysics_Shape *ephysics_shape_new(void);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Delete a shape.
|
||||
*
|
||||
* After a shape is used to create the wanted bodies, it's required
|
||||
* to delete it. It won't be deleted automatically by ephysics
|
||||
* at any point, even on shutdown. The creator is responsible to
|
||||
* free it after usage is concluded.
|
||||
*
|
||||
* @param shape The shape to be deleted.
|
||||
*
|
||||
* @see ephysics_shape_new().
|
||||
*
|
||||
* @ingroup EPhysics_Shape
|
||||
*/
|
||||
EAPI void ephysics_shape_del(EPhysics_Shape *shape);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Add a new point to the shape.
|
||||
*
|
||||
* Any point can be added to a shape, but only vertices matter.
|
||||
* A vertex is a special kind of point that describes a corner of
|
||||
* geometric shapes. The final shape will be constructed in such a way
|
||||
* it will have all the added points and will be convex.
|
||||
*
|
||||
* 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_body_shape_add(world, shape);
|
||||
*
|
||||
* ephysics_shape_del(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.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Load the shape from a file.
|
||||
*
|
||||
* Useful to edit shapes on design tools and load it from an exported file.
|
||||
*
|
||||
* Also it helps to avoid lots of @ref ephysics_shape_point_add() in
|
||||
* the code, and keep a better separation between code logic and
|
||||
* design stuff.
|
||||
*
|
||||
* @param filename The path to the file describing the shape.
|
||||
* @return The loaded shape or @c NULL on error.
|
||||
*
|
||||
* @note Not implemented yet.
|
||||
*
|
||||
* @see ephysics_shape_new() for more details.
|
||||
* @see ephysics_shape_save().
|
||||
*
|
||||
* @ingroup EPhysics_Shape
|
||||
*/
|
||||
EAPI EPhysics_Shape *ephysics_shape_load(const char *filename);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Save the shape to a file.
|
||||
*
|
||||
* It can be useful to visualize it on design tools.
|
||||
*
|
||||
* @param shape The shape to be saved.
|
||||
* @param filename The path to save the shape.
|
||||
* @return @c EINA_TRUE on success or EINA_FALSE on error.
|
||||
*
|
||||
* @note Not implemented yet.
|
||||
*
|
||||
* @see ephysics_shape_new().
|
||||
* @see ephysics_shape_load().
|
||||
*
|
||||
* @ingroup EPhysics_Shape
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_shape_save(const EPhysics_Shape *shape, const char *filename);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef EPhysics_Body
|
||||
*
|
||||
|
|
|
@ -18,6 +18,7 @@ base_sources = \
|
|||
ephysics_camera.cpp \
|
||||
ephysics_constraints.cpp \
|
||||
ephysics_main.cpp \
|
||||
ephysics_shape.cpp \
|
||||
ephysics_world.cpp
|
||||
|
||||
libephysics_la_SOURCES = $(base_sources)
|
||||
|
|
|
@ -44,6 +44,8 @@ extern "C" {
|
|||
|
||||
#define RAD_TO_DEG 57.29582 /* 2 * pi radians == 360 degree */
|
||||
|
||||
typedef struct _EPhysics_Point EPhysics_Point;
|
||||
|
||||
typedef enum _EPhysics_World_Boundary
|
||||
{
|
||||
EPHYSICS_WORLD_BOUNDARY_TOP,
|
||||
|
@ -53,6 +55,12 @@ typedef enum _EPhysics_World_Boundary
|
|||
EPHYSICS_WORLD_BOUNDARY_LAST
|
||||
} EPhysics_World_Boundary;
|
||||
|
||||
struct _EPhysics_Point {
|
||||
EINA_INLIST;
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct _EPhysics_Body {
|
||||
EINA_INLIST;
|
||||
btCollisionShape *collision_shape;
|
||||
|
@ -95,6 +103,8 @@ void ephysics_camera_del(EPhysics_Camera *camera);
|
|||
void ephysics_camera_moved_set(EPhysics_Camera *camera, Eina_Bool moved);
|
||||
Eina_Bool ephysics_camera_moved_get(const EPhysics_Camera *camera);
|
||||
|
||||
const Eina_Inlist *ephysics_shape_points_get(const EPhysics_Shape *shape);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "ephysics_private.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _EPhysics_Shape {
|
||||
Eina_Inlist *points;
|
||||
};
|
||||
|
||||
static EPhysics_Point *
|
||||
_ephysics_shape_point_new(void)
|
||||
{
|
||||
EPhysics_Point *point;
|
||||
|
||||
point = (EPhysics_Point *)calloc(1, sizeof(EPhysics_Point));
|
||||
if (!point)
|
||||
{
|
||||
ERR("Failed to allocate point.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
const Eina_Inlist *
|
||||
ephysics_shape_points_get(const EPhysics_Shape *shape)
|
||||
{
|
||||
return shape->points;
|
||||
}
|
||||
|
||||
EAPI EPhysics_Shape *
|
||||
ephysics_shape_new(void)
|
||||
{
|
||||
EPhysics_Shape *shape;
|
||||
|
||||
shape = (EPhysics_Shape *)calloc(1, sizeof(EPhysics_Shape));
|
||||
if (!shape)
|
||||
{
|
||||
ERR("Failed to allocate shape.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_shape_del(EPhysics_Shape *shape)
|
||||
{
|
||||
EPhysics_Point *point;
|
||||
|
||||
if (!shape)
|
||||
{
|
||||
ERR("Can't delete shape, it's null.");
|
||||
return;
|
||||
}
|
||||
|
||||
while (shape->points)
|
||||
{
|
||||
point = EINA_INLIST_CONTAINER_GET(shape->points, EPhysics_Point);
|
||||
shape->points = eina_inlist_remove(shape->points, shape->points);
|
||||
free(point);
|
||||
}
|
||||
|
||||
free(shape);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_shape_point_add(EPhysics_Shape *shape, double x, double y)
|
||||
{
|
||||
EPhysics_Point *point;
|
||||
|
||||
if (!shape)
|
||||
{
|
||||
ERR("Can't add point to shape, it's null.");
|
||||
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;;
|
||||
|
||||
point->x = x;
|
||||
point->y = y;
|
||||
|
||||
shape->points = eina_inlist_append(shape->points, EINA_INLIST_GET(point));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* TODO: load points from file */
|
||||
EAPI EPhysics_Shape *
|
||||
ephysics_shape_load(const char *filename)
|
||||
{
|
||||
EPhysics_Shape *shape;
|
||||
|
||||
shape = ephysics_shape_new();
|
||||
if (!shape)
|
||||
return NULL;
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
/* TODO: save points to file */
|
||||
EAPI Eina_Bool
|
||||
ephysics_shape_save(const EPhysics_Shape *shape, const char *filename)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue