From 5cca2ff0b1507fdbb16da224dd02512aea88a6c4 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Wed, 28 Nov 2012 22:38:47 +0000 Subject: [PATCH] edje: support adding physics worlds and bodies Just an initial support, it's not possible to configure worlds or bodies. Just adding it. Only possible customization is the type of body. It defines what's the collision shape and type (rigid / soft). It can't be changed over time, so it's not on part's description. It's expected that many cases won't be covered yet. If you have ephysics installed and don't want it, just use --disable-ephysics. It shouldn't affect anything for cases where ephysics is not installed. SVN revision: 79793 --- legacy/edje/configure.ac | 21 ++++++++ legacy/edje/src/bin/Makefile.am | 6 +-- legacy/edje/src/bin/edje_cc_handlers.c | 66 ++++++++++++++++++++++++ legacy/edje/src/lib/Makefile.am | 3 +- legacy/edje/src/lib/edje_calc.c | 11 ++++ legacy/edje/src/lib/edje_data.c | 6 +++ legacy/edje/src/lib/edje_load.c | 69 ++++++++++++++++++++++++++ legacy/edje/src/lib/edje_private.h | 35 +++++++++++++ legacy/edje/src/lib/edje_smart.c | 13 +++++ 9 files changed, 226 insertions(+), 4 deletions(-) diff --git a/legacy/edje/configure.ac b/legacy/edje/configure.ac index 29a0065352..f3179acbb6 100644 --- a/legacy/edje/configure.ac +++ b/legacy/edje/configure.ac @@ -327,6 +327,26 @@ if test "x${want_eio}" = "xyes" -a "x${have_eio}" = "xno"; then AC_MSG_ERROR([Eio required, but not found]) fi +want_ephysics="auto" +have_ephysics="no" +AC_ARG_ENABLE([ephysics], + [AC_HELP_STRING([--disable-ephysics], [Disable build with ephysics])], + [want_ephysics="${enableval}"]) + +if test "x${want_ephysics}" != "xno"; then + PKG_CHECK_MODULES([EPHYSICS], + [ephysics], + [ + AC_DEFINE([HAVE_EPHYSICS], [1], [EPhysics is available for physics support]) + have_ephysics="yes" + requirement_edje="ephysics ${requirement_edje}" + ], + [have_ephysics="no"]) +fi +if test "x${want_ephysics}" = "xyes" -a "x${have_ephysics}" = "xno"; then + AC_MSG_ERROR([EPhysics required, but not found]) +fi + # Enable Multisense use want_multisense="no" @@ -643,6 +663,7 @@ echo echo " Amalgamation.........: ${do_amalgamation}" echo " Ecore IMF............: $have_ecore_imf" echo " EIO..................: $have_eio" +echo " EPhysics.............: $have_ephysics" dnl echo " Multisense...........: $want_multisense" if test "x${want_multisense}" = "xyes" ; then diff --git a/legacy/edje/src/bin/Makefile.am b/legacy/edje/src/bin/Makefile.am index 7584fc1b12..9850903d89 100644 --- a/legacy/edje/src/bin/Makefile.am +++ b/legacy/edje/src/bin/Makefile.am @@ -36,7 +36,7 @@ edje_cc_CPPFLAGS = \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -DEPP_DIR=\"$(libdir)/$(PACKAGE)/utils\" \ -@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@ @SNDFILE_CFLAGS@ +@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EPHYSICS_CFLAGS@ @EVIL_CFLAGS@ @SNDFILE_CFLAGS@ edje_cc_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_CC_LIBS@ @EDJE_LIBS@ @EVIL_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@ -lm edje_cc_LDFLAGS = @lt_enable_auto_import@ @@ -58,7 +58,7 @@ edje_pick_CPPFLAGS = \ -I$(top_srcdir)/src/bin \ -I$(top_srcdir)/src/lib \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ -@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@ +@EDJE_CFLAGS@ @EDJE_CC_CFLAGS@ @EIO_CFLAGS@ @EPHYSICS_CFLAGS@ @EVIL_CFLAGS@ edje_pick_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_LIBS@ edje_pick_LDFLAGS = @lt_enable_auto_import@ @@ -71,7 +71,7 @@ edje_cc_sources.c edje_decc_CPPFLAGS = \ -I$(top_srcdir)/src/bin \ -I$(top_srcdir)/src/lib \ -@EDJE_CFLAGS@ @EDJE_DECC_CFLAGS@ @EIO_CFLAGS@ @EVIL_CFLAGS@ +@EDJE_CFLAGS@ @EDJE_DECC_CFLAGS@ @EIO_CFLAGS@ @EPHYSICS_CFLAGS@ @EVIL_CFLAGS@ edje_decc_LDADD = $(top_builddir)/src/lib/libedje.la @EDJE_DECC_LIBS@ @EDJE_LIBS@ @VORBISENC_LIBS@ @FLAC_LIBS@ @SNDFILE_LIBS@ edje_decc_LDFLAGS = @lt_enable_auto_import@ diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index fea2bbdde1..2b8cdd710a 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -141,6 +141,9 @@ static Edje_Part *edje_cc_handlers_part_make(void); static void ob_collections_group_parts_part(void); static void st_collections_group_parts_part_name(void); static void st_collections_group_parts_part_type(void); +#ifdef HAVE_EPHYSICS +static void st_collections_group_parts_part_physics_body(void); +#endif static void st_collections_group_parts_part_insert_before(void); static void st_collections_group_parts_part_insert_after(void); static void st_collections_group_parts_part_effect(void); @@ -386,6 +389,9 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.name", st_collections_group_parts_part_name}, {"collections.group.parts.part.api", st_collections_group_parts_part_api}, {"collections.group.parts.part.type", st_collections_group_parts_part_type}, +#ifdef HAVE_EPHYSICS + {"collections.group.parts.part.physics_body", st_collections_group_parts_part_physics_body}, +#endif {"collections.group.parts.part.insert_before", st_collections_group_parts_part_insert_before}, {"collections.group.parts.part.insert_after", st_collections_group_parts_part_insert_after}, {"collections.group.parts.part.effect", st_collections_group_parts_part_effect}, @@ -3205,6 +3211,66 @@ st_collections_group_parts_part_type(void) current_part->type = type; } +#ifdef HAVE_EPHYSICS +/** + @page edcref + @property + physics_body + @parameters + [TYPE] + @effect + Set the type (all caps) from among the available types of physics + body, it's set to NONE by default. If type is NONE no physics + will be applied and physics block inside part will be discarded. + Valid types: + @li NONE + @li RIGID_BOX + @li RIGID_CIRCLE + @li SOFT_BOX + @li SOFT_CIRCLE + @li CLOTH + @li BOUNDARY_TOP + @li BOUNDARY_BOTTOM + @li BOUNDARY_RIGHT + @li BOUNDARY_LEFT + @li BOUNDARY_FRONT + @li BOUNDARY_BACK + @endproperty + @since 1.8.0 +*/ +static void +st_collections_group_parts_part_physics_body(void) +{ + unsigned int body; + + check_arg_count(1); + + body = parse_enum(0, + "NONE", EDJE_PART_PHYSICS_BODY_NONE, + "RIGID_BOX", EDJE_PART_PHYSICS_BODY_RIGID_BOX, + "RIGID_CIRCLE", EDJE_PART_PHYSICS_BODY_RIGID_CIRCLE, + "SOFT_BOX", EDJE_PART_PHYSICS_BODY_SOFT_BOX, + "SOFT_CIRCLE", EDJE_PART_PHYSICS_BODY_SOFT_CIRCLE, + "CLOTH", EDJE_PART_PHYSICS_BODY_CLOTH, + "BOUNDARY_TOP", EDJE_PART_PHYSICS_BODY_BOUNDARY_TOP, + "BOUNDARY_BOTTOM", EDJE_PART_PHYSICS_BODY_BOUNDARY_BOTTOM, + "BOUNDARY_RIGHT", EDJE_PART_PHYSICS_BODY_BOUNDARY_RIGHT, + "BOUNDARY_LEFT", EDJE_PART_PHYSICS_BODY_BOUNDARY_LEFT, + "BOUNDARY_FRONT", EDJE_PART_PHYSICS_BODY_BOUNDARY_FRONT, + "BOUNDARY_BACK", EDJE_PART_PHYSICS_BODY_BOUNDARY_BACK, + NULL); + + current_part->physics_body = body; + + if (body) + { + Edje_Part_Collection *pc; + pc = eina_list_data_get(eina_list_last(edje_collections)); + pc->physics_enabled = 1; + } +} +#endif + /** @page edcref @property diff --git a/legacy/edje/src/lib/Makefile.am b/legacy/edje/src/lib/Makefile.am index 6f0edada01..07a1f2f27c 100644 --- a/legacy/edje/src/lib/Makefile.am +++ b/legacy/edje/src/lib/Makefile.am @@ -13,6 +13,7 @@ AM_CPPFLAGS = \ @EDJE_CFLAGS@ \ @ECORE_IMF_CFLAGS@ \ @EIO_CFLAGS@ \ +@EPHYSICS_CFLAGS@ \ @EFL_EDJE_BUILD@ \ @REMIX_CFLAGS@ \ @SNDFILE_CFLAGS@ @@ -136,7 +137,7 @@ else libedje_la_SOURCES = $(base_sources) endif -libedje_la_LIBADD = @EDJE_LIBS@ @ECORE_IMF_LIBS@ @EIO_LIBS@ @EVIL_LIBS@ @REMIX_LIBS@ @SNDFILE_LIBS@ -lm +libedje_la_LIBADD = @EDJE_LIBS@ @ECORE_IMF_LIBS@ @EIO_LIBS@ @EPHYSICS_LIBS@ @EVIL_LIBS@ @REMIX_LIBS@ @SNDFILE_LIBS@ -lm libedje_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ EXTRA_DIST = edje_private.h edje_container.h edje_convert.h diff --git a/legacy/edje/src/lib/edje_calc.c b/legacy/edje/src/lib/edje_calc.c index 3fc8d30462..618f3c74b6 100644 --- a/legacy/edje/src/lib/edje_calc.c +++ b/legacy/edje/src/lib/edje_calc.c @@ -2984,6 +2984,17 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta case EDJE_PART_TYPE_GROUP: case EDJE_PART_TYPE_EXTERNAL: /* visibility and color have no meaning on SWALLOW and GROUP part. */ +#ifdef HAVE_EPHYSICS + if (ep->body) + { + Evas_Coord z; + ephysics_body_geometry_get(ep->body, NULL, NULL, &z, + NULL, NULL, NULL); + ephysics_body_move(ep->body, + ed->x + pf->x, ed->y + pf->y, z); + } + else +#endif evas_object_move(ep->object, ed->x + pf->x, ed->y + pf->y); evas_object_resize(ep->object, pf->w, pf->h); diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index fd2604035f..6eca7729c4 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -854,6 +854,9 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.events_id", dragable.event_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_part, Edje_Part, "items", items, _edje_edd_edje_pack_element_pointer); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "type", type, EET_T_UCHAR); +#ifdef HAVE_EPHYSICS + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "physics_body", physics_body, EET_T_UCHAR); +#endif EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "effect", effect, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "mouse_events", mouse_events, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "repeat_events", repeat_events, EET_T_UCHAR); @@ -908,4 +911,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "lua_script_only", lua_script_only, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "prop.orientation", prop.orientation, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "broadcast_signal", broadcast_signal, EET_T_UCHAR); +#ifdef HAVE_EPHYSICS + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection, Edje_Part_Collection, "physics_enabled", physics_enabled, EET_T_UCHAR); +#endif } diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index c9c3444e29..5d2b712063 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -341,6 +341,53 @@ _edje_programs_patterns_init(Edje *ed) ssp->sources_patterns = edje_match_programs_source_init(all, j); } +#ifdef HAVE_EPHYSICS +static void +_edje_physics_body_add(Edje_Real_Part *rp, EPhysics_World *world) +{ + switch (rp->part->physics_body) + { + case EDJE_PART_PHYSICS_BODY_RIGID_BOX: + rp->body = ephysics_body_box_add(world); + break; + case EDJE_PART_PHYSICS_BODY_RIGID_CIRCLE: + rp->body = ephysics_body_circle_add(world); + break; + case EDJE_PART_PHYSICS_BODY_SOFT_BOX: + rp->body = ephysics_body_soft_box_add(world); + break; + case EDJE_PART_PHYSICS_BODY_SOFT_CIRCLE: + rp->body = ephysics_body_soft_circle_add(world); + break; + case EDJE_PART_PHYSICS_BODY_CLOTH: + rp->body = ephysics_body_cloth_add(world, 0, 0); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_TOP: + rp->body = ephysics_body_top_boundary_add(world); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_BOTTOM: + rp->body = ephysics_body_bottom_boundary_add(world); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_RIGHT: + rp->body = ephysics_body_right_boundary_add(world); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_LEFT: + rp->body = ephysics_body_left_boundary_add(world); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_FRONT: + rp->body = ephysics_body_front_boundary_add(world); + break; + case EDJE_PART_PHYSICS_BODY_BOUNDARY_BACK: + rp->body = ephysics_body_back_boundary_add(world); + break; + default: + ERR("Invalid body: %i", rp->part->physics_body); + return; + } + ephysics_body_evas_object_set(rp->body, rp->object, EINA_TRUE); +} +#endif + int _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path, Eina_Array *nested) { @@ -384,6 +431,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g if (_edje_script_only(ed)) _edje_script_only_shutdown(ed); if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed); +#ifdef HAVE_EPHYSICS + /* clear physics world / shutdown ephysics */ + if ((ed->collection) && (ed->collection->physics_enabled)) + { + ephysics_world_del(ed->world); + ephysics_shutdown(); + } +#endif + _edje_file_del(ed); eina_stringshare_replace(&ed->path, file); @@ -432,6 +488,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g { unsigned int i; +#ifdef HAVE_EPHYSICS + /* create physics world */ + if (ed->collection->physics_enabled) + { + ephysics_init(); + ed->world = ephysics_world_new(); + } +#endif + /* colorclass stuff */ for (i = 0; i < ed->collection->parts_count; ++i) { @@ -663,6 +728,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g if (rp->part->clip_to_id < 0) evas_object_clip_set(rp->object, ed->base->clipper); } +#ifdef HAVE_EPHYSICS + if (ep->physics_body) + _edje_physics_body_add(rp, ed->world); +#endif } if (n > 0) { diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 0a93a34b64..26adfaa190 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -79,6 +79,10 @@ void *alloca (size_t); # include #endif +#ifdef HAVE_EPHYSICS +# include +#endif + #include "Edje.h" EAPI extern int _edje_default_log_dom ; @@ -731,6 +735,23 @@ typedef enum { EDJE_PART_LIMIT_OVER } Edje_Part_Limit_State; +#ifdef HAVE_EPHYSICS +typedef enum { + EDJE_PART_PHYSICS_BODY_NONE= 0, + EDJE_PART_PHYSICS_BODY_RIGID_BOX, + EDJE_PART_PHYSICS_BODY_RIGID_CIRCLE, + EDJE_PART_PHYSICS_BODY_SOFT_BOX, + EDJE_PART_PHYSICS_BODY_SOFT_CIRCLE, + EDJE_PART_PHYSICS_BODY_CLOTH, + EDJE_PART_PHYSICS_BODY_BOUNDARY_TOP, + EDJE_PART_PHYSICS_BODY_BOUNDARY_BOTTOM, + EDJE_PART_PHYSICS_BODY_BOUNDARY_RIGHT, + EDJE_PART_PHYSICS_BODY_BOUNDARY_LEFT, + EDJE_PART_PHYSICS_BODY_BOUNDARY_FRONT, + EDJE_PART_PHYSICS_BODY_BOUNDARY_BACK +} Edje_Part_Physics_Body; +#endif + struct _Edje_Part_Limit { int part; @@ -804,6 +825,10 @@ struct _Edje_Part_Collection unsigned char broadcast_signal; +#ifdef HAVE_EPHYSICS + unsigned char physics_enabled; /* will be 1 if a body is declared */ +#endif + unsigned char checked : 1; }; @@ -853,6 +878,9 @@ struct _Edje_Part Edje_Pack_Element **items; /* packed items for box and table */ unsigned int items_count; unsigned char type; /* what type (image, rect, text) */ +#ifdef HAVE_EPHYSICS + unsigned char physics_body; /* body (none, rigid box, soft circle, ...) */ +#endif unsigned char effect; /* 0 = plain... */ unsigned char mouse_events; /* it will affect/respond to mouse events */ unsigned char repeat_events; /* it will repeat events to objects below */ @@ -1184,6 +1212,10 @@ struct _Edje int walking_callbacks; +#ifdef HAVE_EPHYSICS + EPhysics_World *world; +#endif + Eina_Bool dirty : 1; Eina_Bool recalc : 1; Eina_Bool delete_callbacks : 1; @@ -1364,6 +1396,9 @@ struct _Edje_Real_Part Edje_Calc_Params *current; // 4 Edje_Real_Part *clip_to; // 4 Edje_Running_Program *program; // 4 +#ifdef HAVE_EPHYSICS + EPhysics_Body *body; // 4 +#endif union { Edje_Real_Part_Text *text; Edje_Real_Part_Container *container; diff --git a/legacy/edje/src/lib/edje_smart.c b/legacy/edje/src/lib/edje_smart.c index c92210f3aa..233bf0e827 100644 --- a/legacy/edje/src/lib/edje_smart.c +++ b/legacy/edje/src/lib/edje_smart.c @@ -99,6 +99,14 @@ _edje_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED) evas_object_smart_data_set(obj, NULL); if (_edje_script_only(ed)) _edje_script_only_shutdown(ed); if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed); +#ifdef HAVE_EPHYSICS + /* clear physics world / shutdown ephysics */ + if ((ed->collection) && (ed->collection->physics_enabled)) + { + ephysics_world_del(ed->world); + ephysics_shutdown(); + } +#endif if (ed->persp) edje_object_perspective_set(obj, NULL); _edje_file_del(ed); _edje_clean_objects(ed); @@ -217,6 +225,11 @@ _edje_smart_resize(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) } ed->w = w; ed->h = h; +#ifdef HAVE_EPHYSICS + if (ed->world) + ephysics_world_render_geometry_set(ed->world, ed->x, ed->y, -50, + ed->w, ed->h, 100); +#endif #ifdef EDJE_CALC_CACHE ed->all_part_change = EINA_TRUE; #endif