edje: support adding physics worlds and bodies
authorBruno Dilly <bdilly@profusion.mobi>
Wed, 28 Nov 2012 22:38:47 +0000 (22:38 +0000)
committerBruno Dilly <bdilly@profusion.mobi>
Wed, 28 Nov 2012 22:38:47 +0000 (22:38 +0000)
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
legacy/edje/src/bin/Makefile.am
legacy/edje/src/bin/edje_cc_handlers.c
legacy/edje/src/lib/Makefile.am
legacy/edje/src/lib/edje_calc.c
legacy/edje/src/lib/edje_data.c
legacy/edje/src/lib/edje_load.c
legacy/edje/src/lib/edje_private.h
legacy/edje/src/lib/edje_smart.c

index 29a0065..f3179ac 100644 (file)
@@ -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
index 7584fc1..9850903 100644 (file)
@@ -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@
 
index fea2bbd..2b8cdd7 100644 (file)
@@ -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
index 6f0edad..07a1f2f 100644 (file)
@@ -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
index 3fc8d30..618f3c7 100644 (file)
@@ -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);
              
index fd26040..6eca772 100644 (file)
@@ -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
 }
index c9c3444..5d2b712 100644 (file)
@@ -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)
               {
index 0a93a34..26adfaa 100644 (file)
@@ -79,6 +79,10 @@ void *alloca (size_t);
 # include <Eio.h>
 #endif
 
+#ifdef HAVE_EPHYSICS
+# include <EPhysics.h>
+#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;
index c92210f..233bf0e 100644 (file)
@@ -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