forked from enlightenment/efl
ephysics: lights, camera, action!
Add light support. It uses evas_map_util_3d_lighting() internally and is only applied over selected bodies. SVN revision: 77803
This commit is contained in:
parent
3acb5dde8b
commit
c970090254
|
@ -1226,6 +1226,118 @@ EAPI void ephysics_world_simulation_set(EPhysics_World *world, double fixed_time
|
|||
*/
|
||||
EAPI void ephysics_world_simulation_get(const EPhysics_World *world, double *fixed_time_step, int *max_sub_steps);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set light properties to be applied on the scene.
|
||||
*
|
||||
* It will perform lighting calculations on the evas map applied on evas
|
||||
* objects associated with all the bodies to have light applied over.
|
||||
*
|
||||
* This is used to apply lighting calculations (from a single light source)
|
||||
* to a given object. The R, G and B values of each vertex will be modified to
|
||||
* reflect the lighting based on the lixth point coordinates, the light color
|
||||
* and the ambient color, and at what angle the map is facing the light source.
|
||||
* A surface should have its points be declared in a clockwise fashion if the
|
||||
* face is "facing" towards you (as opposed to away from you) as faces have a
|
||||
* "logical" side for lighting.
|
||||
*
|
||||
* More details can be found on evas_map_util_3d_lighting() documentation,
|
||||
* since this function is used internally by EPhysics.
|
||||
*
|
||||
* There are two ways of setting a body to receive lighting. One is to simple
|
||||
* set all the bodies to be affected, with
|
||||
* @ref ephysics_world_light_all_bodies_set(). The other, is to set each body
|
||||
* individually, with @ref ephysics_body_light_set().
|
||||
*
|
||||
* By default, no light is set. And after a light is set, by default,
|
||||
* no body will be affected. No change will be visible until
|
||||
* some bodies are set to be enlightened.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param lx X coordinate in space of light point
|
||||
* @param ly Y coordinate in space of light point
|
||||
* @param lz Z coordinate in space of light point
|
||||
* @param lr light red value (0 - 255)
|
||||
* @param lg light green value (0 - 255)
|
||||
* @param lb light blue value (0 - 255)
|
||||
* @param ar ambient color red value (0 - 255)
|
||||
* @param ag ambient color green value (0 - 255)
|
||||
* @param ab ambient color blue value (0 - 255)
|
||||
*
|
||||
* @see ephysics_world_light_get().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_light_set(EPhysics_World *world, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get light properties.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param lx X coordinate in space of light point
|
||||
* @param ly Y coordinate in space of light point
|
||||
* @param lz Z coordinate in space of light point
|
||||
* @param lr light red value (0 - 255)
|
||||
* @param lg light green value (0 - 255)
|
||||
* @param lb light blue value (0 - 255)
|
||||
* @param ar ambient color red value (0 - 255)
|
||||
* @param ag ambient color green value (0 - 255)
|
||||
* @param ab ambient color blue value (0 - 255)
|
||||
* @return @c EINA_TRUE if light is set, or @c EINA_FALSE if it isn't set,
|
||||
* or on error. On this case the other parameters won't be set.
|
||||
*
|
||||
* @see ephysics_world_light_set() for more details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_light_get(const EPhysics_World *world, Evas_Coord *lx, Evas_Coord *ly, Evas_Coord *lz, int *lr, int *lg, int *lb, int *ar, int *ag, int *ab);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Unset light on the scene.
|
||||
*
|
||||
* It will unset light, so no body will be enlightened anymore.
|
||||
*
|
||||
* @param world The physics world.
|
||||
*
|
||||
* @see ephysics_world_light_set() for more details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_light_unset(EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set if light should be applied over all the bodies.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @param enable @c EINA_TRUE if light should be obligatory applied over
|
||||
* all the bodies, or @c EINA_FALSE if it only should be applied on bodies with
|
||||
* light property set.
|
||||
*
|
||||
* @see ephysics_world_light_set() for more details.
|
||||
* @see ephysics_world_light_all_bodies_get().
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI void ephysics_world_light_all_bodies_set(EPhysics_World *world, Eina_Bool enable);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get light setting regarding being applied over all the bodies.
|
||||
*
|
||||
* @param world The physics world.
|
||||
* @return @c EINA_TRUE if light will be obligatory applied over all the bodies,
|
||||
* or @c EINA_FALSE if it only will be applied on bodies with light property
|
||||
* set, or on error.
|
||||
*
|
||||
* @see ephysics_world_light_all_bodies_set() for details.
|
||||
*
|
||||
* @ingroup EPhysics_World
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_world_light_all_bodies_get(const EPhysics_World *world);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -3159,12 +3271,56 @@ EAPI void ephysics_body_material_set(EPhysics_Body *body, EPhysics_Body_Material
|
|||
* @param body The physics body.
|
||||
* @return the @p material used by the body.
|
||||
*
|
||||
* @see ephysics_body_body_set() for more details.
|
||||
* @see ephysics_body_material_set() for more details.
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI EPhysics_Body_Material ephysics_body_material_get(const EPhysics_Body *body);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Set light effect over body.
|
||||
*
|
||||
* @param body The physics body.
|
||||
* @param enable If @c EINA_TRUE, light will be applied over this @p body,
|
||||
* otherwise it won't.
|
||||
*
|
||||
* It's possible to set the light to apply over all the bodies with
|
||||
* @ref ephysics_world_light_all_bodies_set(). This will have priority
|
||||
* over body's individual light settings.
|
||||
*
|
||||
* So, if @p body is set to doesn't be affect by the light, but light
|
||||
* is set to be applied over all the bodies, @p body will be displayed
|
||||
* with light over it.
|
||||
*
|
||||
* Also, if no light is set on the world with @ref ephysics_world_light_set(),
|
||||
* nothing will happens.
|
||||
*
|
||||
* @see ephysics_body_light_get().
|
||||
* @see ephysics_world_light_set() for more details regarding lighting.
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI void ephysics_body_light_set(EPhysics_Body *body, Eina_Bool enable);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Get light effect over body.
|
||||
*
|
||||
* @param body The physics body.
|
||||
* @return @c EINA_TRUE if light is applied over this @p body or @c EINA_FALSE
|
||||
* in the other case, or on error.
|
||||
*
|
||||
* @note If light is applied over all the bodies it may return @c EINA_FALSE
|
||||
* even if it's being affect by lights. This need to be checked with
|
||||
* @ref ephysics_world_light_all_bodies_get().
|
||||
*
|
||||
* @see ephysics_body_light_set() for more details.
|
||||
*
|
||||
* @ingroup EPhysics_Body
|
||||
*/
|
||||
EAPI Eina_Bool ephysics_body_light_get(const EPhysics_Body *body);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -1045,6 +1045,18 @@ _ephysics_body_evas_object_default_update(EPhysics_Body *body)
|
|||
|
||||
evas_map_util_rotate(map, rot, x + (w * body->cm.x), y +
|
||||
(h * body->cm.y));
|
||||
|
||||
if ((body->light_apply) ||
|
||||
(ephysics_world_light_all_bodies_get(body->world)))
|
||||
{
|
||||
int lr, lg, lb, ar, ag, ab;
|
||||
Evas_Coord lx, ly, lz;
|
||||
|
||||
if (ephysics_world_light_get(body->world, &lx, &ly, &lz,
|
||||
&lr, &lg, &lb, &ar, &ag, &ab))
|
||||
evas_map_util_3d_lighting(map, lx, ly, lz, lr, lg, lb, ar, ag, ab);
|
||||
}
|
||||
|
||||
evas_object_map_set(body->evas_obj, map);
|
||||
evas_object_map_enable_set(body->evas_obj, EINA_TRUE);
|
||||
evas_map_free(map);
|
||||
|
@ -2816,6 +2828,31 @@ ephysics_body_material_get(const EPhysics_Body *body)
|
|||
return body->material;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_body_light_set(EPhysics_Body *body, Eina_Bool enable)
|
||||
{
|
||||
if (!body)
|
||||
{
|
||||
ERR("No body, no light.");
|
||||
return;
|
||||
}
|
||||
|
||||
body->light_apply = !!enable;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_body_light_get(const EPhysics_Body *body)
|
||||
{
|
||||
if (!body)
|
||||
{
|
||||
ERR("No body, no light.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return body->light_apply;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -104,14 +104,15 @@ struct _EPhysics_Body {
|
|||
double y;
|
||||
double z;
|
||||
} cm;
|
||||
Eina_Bool active:1;
|
||||
Eina_Bool deleted:1;
|
||||
int slices;
|
||||
int *points_deform;
|
||||
EPhysics_Body_Type type;
|
||||
int cloth_columns;
|
||||
int cloth_rows;
|
||||
int anchor_prop;
|
||||
Eina_Bool active:1;
|
||||
Eina_Bool deleted:1;
|
||||
Eina_Bool light_apply:1;
|
||||
};
|
||||
|
||||
extern int _ephysics_log_dom;
|
||||
|
|
|
@ -32,6 +32,21 @@ struct _EPhysics_World_Callback {
|
|||
Eina_Bool deleted:1;
|
||||
};
|
||||
|
||||
typedef struct _EPhysics_Light EPhysics_Light;
|
||||
|
||||
struct _EPhysics_Light {
|
||||
Evas_Coord lx;
|
||||
Evas_Coord ly;
|
||||
Evas_Coord lz;
|
||||
int lr;
|
||||
int lg;
|
||||
int lb;
|
||||
int ar;
|
||||
int ag;
|
||||
int ab;
|
||||
Eina_Bool all_bodies:1;
|
||||
};
|
||||
|
||||
struct _EPhysics_World {
|
||||
EINA_INLIST;
|
||||
btBroadphaseInterface* broadphase;
|
||||
|
@ -45,6 +60,7 @@ struct _EPhysics_World {
|
|||
|
||||
EPhysics_Body *boundaries[4];
|
||||
EPhysics_Camera *camera;
|
||||
EPhysics_Light *light;
|
||||
Evas_Coord x, y, w, h;
|
||||
Eina_Inlist *callbacks;
|
||||
Eina_Inlist *bodies;
|
||||
|
@ -349,6 +365,9 @@ _ephysics_world_free(EPhysics_World *world)
|
|||
eina_condition_free(&world->condition);
|
||||
eina_lock_free(&world->mutex);
|
||||
|
||||
if (world->light)
|
||||
free(world->light);
|
||||
|
||||
free(world);
|
||||
INF("World %p deleted.", world);
|
||||
ephysics_dom_count_dec();
|
||||
|
@ -1412,6 +1431,122 @@ ephysics_world_lock_release(EPhysics_World *world)
|
|||
eina_lock_release(&world->mutex);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_light_set(EPhysics_World *world,
|
||||
Evas_Coord lx, Evas_Coord ly, Evas_Coord lz,
|
||||
int lr, int lg, int lb,
|
||||
int ar, int ag, int ab)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("No world, can't set light.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world->light)
|
||||
world->light = (EPhysics_Light *) calloc(1, sizeof(EPhysics_Light));
|
||||
|
||||
if (!world->light)
|
||||
{
|
||||
ERR("Failed to create light.");
|
||||
return;
|
||||
}
|
||||
|
||||
world->light->lx = lx;
|
||||
world->light->ly = ly;
|
||||
world->light->lz = lz;
|
||||
world->light->lr = lr;
|
||||
world->light->lg = lg;
|
||||
world->light->lb = lb;
|
||||
world->light->ar = ar;
|
||||
world->light->ag = ag;
|
||||
world->light->ab = ab;
|
||||
world->light->all_bodies = EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_light_get(const EPhysics_World *world,
|
||||
Evas_Coord *lx, Evas_Coord *ly, Evas_Coord *lz,
|
||||
int *lr, int *lg, int *lb,
|
||||
int *ar, int *ag, int *ab)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("No world, can't get light.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!world->light)
|
||||
{
|
||||
INF("Light isn't set.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (lx) *lx = world->light->lx;
|
||||
if (ly) *ly = world->light->ly;
|
||||
if (lz) *lz = world->light->lz;
|
||||
if (lr) *lr = world->light->lr;
|
||||
if (lg) *lg = world->light->lg;
|
||||
if (lb) *lb = world->light->lb;
|
||||
if (ar) *ar = world->light->ar;
|
||||
if (ag) *ag = world->light->ag;
|
||||
if (ab) *ab = world->light->ab;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_light_unset(EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("No world, can't unset light.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world->light)
|
||||
return;
|
||||
|
||||
free(world->light);
|
||||
world->light = NULL;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ephysics_world_light_all_bodies_set(EPhysics_World *world, Eina_Bool enable)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("No world, can't set light property.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world->light)
|
||||
{
|
||||
ERR("Light isn't set, can't apply on bodies");
|
||||
return;
|
||||
}
|
||||
|
||||
world->light->all_bodies = !!enable;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ephysics_world_light_all_bodies_get(const EPhysics_World *world)
|
||||
{
|
||||
if (!world)
|
||||
{
|
||||
ERR("No world, can't get light property.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!world->light)
|
||||
{
|
||||
INF("Light isn't set, can't get light property");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return world->light->all_bodies;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue