cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6dac83e643934573a734491d97b549a6b235c0f5

commit 6dac83e643934573a734491d97b549a6b235c0f5
Author: Bogdan Devichev <b.devic...@samsung.com>
Date:   Tue May 26 18:49:15 2015 +0200

    evas: add API for creation Evas_3D node primitives.
    
    Summary: Now mechanism of creation of primitives is similar to model 
loading.
    
    Reviewers: Oleksander, Hermet, raster, cedric
    
    Reviewed By: cedric
    
    Subscribers: cedric
    
    Differential Revision: https://phab.enlightenment.org/D2516
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/Makefile_Evas.am                               |  14 ++
 src/lib/evas/Evas_Eo.h                             |  61 +++++-
 src/lib/evas/canvas/evas_3d_mesh.c                 |  13 ++
 src/lib/evas/canvas/evas_3d_mesh.eo                |  11 +-
 src/lib/evas/canvas/evas_3d_primitive.c            | 162 ++++++++++++++++
 src/lib/evas/canvas/evas_3d_primitive.eo           | 179 ++++++++++++++++++
 .../evas/common3d/primitives/primitive_common.c    | 209 +++++++++++++++++++++
 .../evas/common3d/primitives/primitive_common.h    |  58 ++++++
 .../primitives/solids_of_revolution/cone.c         | 140 ++++++++++++++
 .../primitives/solids_of_revolution/cylinder.c     | 136 ++++++++++++++
 .../primitives/solids_of_revolution/sphere.c       | 189 +++++++++++++++++++
 .../primitives/solids_of_revolution/torus.c        |  67 +++++++
 .../evas/common3d/primitives/surfaces/surface.c    |  91 +++++++++
 .../evas/common3d/primitives/surfaces/terrain.c    |  86 +++++++++
 .../primitives/tabulated_primitives/cube.c         |  57 ++++++
 .../primitives/tabulated_primitives/square.c       |  18 ++
 src/lib/evas/include/evas_private.h                |  23 +++
 17 files changed, 1511 insertions(+), 3 deletions(-)

diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 72f8365..3a2f4af 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -29,6 +29,7 @@ evas_eolian_files = \
        lib/evas/canvas/evas_3d_material.eo\
        lib/evas/canvas/evas_3d_light.eo\
        lib/evas/canvas/evas_3d_mesh.eo\
+       lib/evas/canvas/evas_3d_primitive.eo\
        lib/evas/canvas/evas_3d_node.eo\
        lib/evas/canvas/evas_3d_scene.eo\
        lib/evas/canvas/evas_3d_object.eo \
@@ -202,6 +203,7 @@ lib/evas/canvas/evas_3d_light.c \
 lib/evas/canvas/evas_3d_mesh.c \
 lib/evas/canvas/evas_3d_texture.c \
 lib/evas/canvas/evas_3d_material.c \
+lib/evas/canvas/evas_3d_primitive.c \
 lib/evas/canvas/evas_3d_node_callback.h
 
 # Model savers/loaders (will be replaced to modules in next commits)
@@ -215,6 +217,18 @@ modules/evas/model_savers/obj/evas_model_save_obj.c \
 modules/evas/model_savers/ply/evas_model_save_ply.c \
 lib/evas/canvas/evas_3d_eet.c
 
+# 3d primitives
+lib_evas_libevas_la_SOURCES += \
+lib/evas/common3d/primitives/tabulated_primitives/square.c \
+lib/evas/common3d/primitives/tabulated_primitives/cube.c \
+lib/evas/common3d/primitives/solids_of_revolution/sphere.c \
+lib/evas/common3d/primitives/solids_of_revolution/torus.c \
+lib/evas/common3d/primitives/solids_of_revolution/cylinder.c \
+lib/evas/common3d/primitives/solids_of_revolution/cone.c \
+lib/evas/common3d/primitives/surfaces/surface.c \
+lib/evas/common3d/primitives/surfaces/terrain.c \
+lib/evas/common3d/primitives/primitive_common.c
+
 # Evas_VG
 lib_evas_libevas_la_SOURCES += \
 lib/evas/canvas/evas_object_vg.c \
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index c81ce46..e401a51 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -304,6 +304,15 @@ EAPI extern const Eo_Event_Description 
_EVAS_CANVAS_EVENT_VIEWPORT_RESIZE;
  */
 
 /**
+ * @defgroup Evas_3D_Primitive Primitive Object
+ * @ingroup Evas_3D
+ *
+ * A primitive object is an object with necessary data for creating meshes 
with ptimitive shapes.
+ * Data from a primitive can be set to Evas_3D_Mesh by using 
evas_3d_mesh_from_primitive_set()
+ * function.
+ */
+
+/**
  * @defgroup Evas_3D_Texture Texture Object
  * @ingroup Evas_3D
  *
@@ -435,6 +444,33 @@ typedef Eo     Evas_3D_Material;
 #define _EVAS_3D_MATERIAL_EO_CLASS_TYPE
 
 /**
+ * @typedef Evas_3D_Primitive
+ *
+ * Primitive object handle
+ *
+ * @since 1.15
+ * @ingroup Evas_3D_Primitive
+ */
+typedef Eo     Evas_3D_Primitive;
+
+#define _EVAS_3D_PRIMITIVE_EO_CLASS_TYPE
+
+/**
+ * @typedef Evas_3D_Surface_Func
+ *
+ * User-defined parametric surface function.
+ * Used for easy creation of custom surfaces as a primitive.
+ *
+ * @since 1.15
+ * @ingroup Evas_3D_Primitive
+ */
+typedef void (Evas_3D_Surface_Func)(Evas_Real *out_x,
+                                    Evas_Real *out_y,
+                                    Evas_Real *out_z,
+                                    Evas_Real a,
+                                    Evas_Real b);
+
+/**
  * Type of 3D Object
  *
  * @since 1.10
@@ -451,6 +487,7 @@ typedef enum _Evas_3D_Object_Type
    EVAS_3D_OBJECT_TYPE_MESH,
    EVAS_3D_OBJECT_TYPE_TEXTURE,
    EVAS_3D_OBJECT_TYPE_MATERIAL,
+   EVAS_3D_OBJECT_TYPE_PRIMITIVE,
 } Evas_3D_Object_Type;
 
 /**
@@ -716,7 +753,7 @@ typedef enum _Evas_3D_Wrap_Mode
 } Evas_3D_Wrap_Mode;
 
 /**
- * Mesh Primitive
+ * Mesh primitive
  *
  * @since 1.12
  * @ingroup Evas_3D_Types
@@ -740,10 +777,28 @@ typedef enum _Evas_3D_Mesh_Primitive
    /**< Custom surface (can use pointer to users function, precision and 
texture scale) */
    EVAS_3D_MESH_PRIMITIVE_SURFACE,
    /**< Terrain as surface with pointer to Perlin's noise function */
-   EVAS_3D_MESH_PRIMITIVE_TERRAIN
+   EVAS_3D_MESH_PRIMITIVE_TERRAIN,
+   /**< Count of supported primitives */
+   EVAS_3D_MESH_PRIMITIVE_COUNT
 } Evas_3D_Mesh_Primitive;
 
 /**
+ * Mode of mesh primitive
+ *
+ * @since 1.15
+ * @ingroup Evas_3D_Types
+ */
+typedef enum _Evas_3D_Primitive_Mode
+{
+   /**< Default mode of primitive */
+   EVAS_3D_PRIMITIVE_MODE_DEFAULT = 0,
+   /**< Primitive without base (supported for cylinder and cone) */
+   EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE,
+   /**< Ptimitive with alternative UV (supported for sphere)*/
+   EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV
+} Evas_3D_Primitive_Mode;
+
+/**
  * Texture filters
  *
  * @since 1.10
@@ -818,6 +873,8 @@ typedef enum _Evas_3D_Material_Attrib
 
 #include "canvas/evas_3d_mesh.eo.h"
 
+#include "canvas/evas_3d_primitive.eo.h"
+
 #include "canvas/evas_3d_node.eo.h"
 
 #include "canvas/evas_3d_scene.eo.h"
diff --git a/src/lib/evas/canvas/evas_3d_mesh.c 
b/src/lib/evas/canvas/evas_3d_mesh.c
index 1b8cc14..f15b42f 100644
--- a/src/lib/evas/canvas/evas_3d_mesh.c
+++ b/src/lib/evas/canvas/evas_3d_mesh.c
@@ -893,6 +893,19 @@ _evas_3d_mesh_efl_file_save(Eo *obj, Evas_3D_Mesh_Data *pd,
    return EINA_TRUE;
 }
 
+EOLIAN static void
+_evas_3d_mesh_from_primitive_set(Eo *obj,
+                                 Evas_3D_Mesh_Data *pd EINA_UNUSED,
+                                 int frame,
+                                 Eo *primitive)
+{
+   if ((primitive == NULL) || (obj == NULL)) return;
+
+   Evas_3D_Primitive_Data *ppd = eo_data_scope_get(primitive, 
EVAS_3D_PRIMITIVE_CLASS);
+
+   evas_common_set_model_from_primitive(obj, frame, ppd);
+}
+
 static inline void
 _mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame,
                  Eina_List **l, Eina_List **r)
diff --git a/src/lib/evas/canvas/evas_3d_mesh.eo 
b/src/lib/evas/canvas/evas_3d_mesh.eo
index 5789cc0..db0f895 100644
--- a/src/lib/evas/canvas/evas_3d_mesh.eo
+++ b/src/lib/evas/canvas/evas_3d_mesh.eo
@@ -291,7 +291,16 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface, 
Efl.File)
             @out dfactor: Evas_3D_Blend_Func; /*@ Pointer to receive 
destination blendin factors key.*/
          }
       }
-
+      from_primitive_set {
+         /*@
+          Set the data of given mesh frame from the given primitive
+          @ingroup Evas_3D_Mesh
+         */
+         params {
+            @in frame: int; /*@ Specifies data of which frame of given mesh 
will be set.*/
+            @in primitive: Evas_3D_Primitive *; /*@ Specifies which data will 
be set.*/
+         }
+      }
       @property shade_mode {
          set {
             /*@
diff --git a/src/lib/evas/canvas/evas_3d_primitive.c 
b/src/lib/evas/canvas/evas_3d_primitive.c
new file mode 100644
index 0000000..34ecab6
--- /dev/null
+++ b/src/lib/evas/canvas/evas_3d_primitive.c
@@ -0,0 +1,162 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#define MY_CLASS EVAS_3D_PRIMITIVE_CLASS
+
+static inline void
+_primitive_init(Evas_3D_Primitive_Data *pd)
+{
+   pd->form = EVAS_3D_MESH_PRIMITIVE_NONE;
+   pd->ratio = 3.0;
+   pd->precision = 10;
+   pd->surface = NULL;
+   pd->tex_scale.x = 1.0;
+   pd->tex_scale.y = 1.0;
+}
+
+static inline void
+_primitive_fini(Evas_3D_Primitive_Data *pd)
+{
+   if (pd->surface)
+     free(pd->surface);
+}
+
+EAPI Evas_3D_Primitive *
+evas_3d_primitive_add(Evas *e)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return NULL;
+   MAGIC_CHECK_END();
+   Evas_Object *eo_obj = eo_add(MY_CLASS, e);
+   return eo_obj;
+}
+
+EOLIAN static Eo *
+_evas_3d_primitive_eo_base_constructor(Eo *obj, Evas_3D_Primitive_Data *pd)
+{
+   obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
+   eo_do(obj, evas_3d_object_type_set(EVAS_3D_OBJECT_TYPE_PRIMITIVE));
+   _primitive_init(pd);
+
+   return obj;
+}
+
+EOLIAN static void
+_evas_3d_primitive_eo_base_destructor(Eo *obj, Evas_3D_Primitive_Data *pd)
+{
+   _primitive_fini(pd);
+   eo_do_super(obj, MY_CLASS, eo_destructor());
+}
+
+EOLIAN static void
+_evas_3d_primitive_form_set(Eo *obj EINA_UNUSED,
+                            Evas_3D_Primitive_Data *pd,
+                            Evas_3D_Mesh_Primitive form)
+{
+   if ((form < EVAS_3D_MESH_PRIMITIVE_NONE) ||
+       (form >= EVAS_3D_MESH_PRIMITIVE_COUNT))
+     {
+        ERR("Wrong form of primitive.");
+        return;
+     }
+
+   if (pd->form != form)
+     pd->form = form;
+}
+
+EOLIAN static Evas_3D_Mesh_Primitive
+_evas_3d_primitive_form_get(Eo *obj EINA_UNUSED,
+                            Evas_3D_Primitive_Data *pd)
+{
+   return pd->form;
+}
+
+EOLIAN static void
+_evas_3d_primitive_mode_set(Eo *obj EINA_UNUSED,
+                            Evas_3D_Primitive_Data *pd,
+                            Evas_3D_Primitive_Mode mode)
+{
+   if (pd->mode != mode)
+     pd->mode = mode;
+}
+
+EOLIAN static Evas_3D_Primitive_Mode
+_evas_3d_primitive_mode_get(Eo *obj EINA_UNUSED,
+                            Evas_3D_Primitive_Data *pd)
+{
+   return pd->mode;
+}
+
+EOLIAN static void
+_evas_3d_primitive_ratio_set(Eo *obj EINA_UNUSED,
+                             Evas_3D_Primitive_Data *pd,
+                             Evas_Real ratio)
+{
+   pd->ratio = ratio;
+}
+
+EOLIAN static Evas_Real
+_evas_3d_primitive_ratio_get(Eo *obj EINA_UNUSED,
+                             Evas_3D_Primitive_Data *pd)
+{
+   return pd->ratio;
+}
+
+EOLIAN static void
+_evas_3d_primitive_precision_set(Eo *obj EINA_UNUSED,
+                                 Evas_3D_Primitive_Data *pd,
+                                 int precision)
+{
+   if ((precision < 3))
+     {
+        ERR("Precision of Evas_3D_Primitive cannot be less than 3.");
+        return;
+     }
+
+   if ((precision >= 100))
+     {
+        ERR("%s\n%s",
+            "Be careful with precision of Evas_3D_Primitive more than 100.",
+            "It can give unacceptable result.");
+     }
+
+   if (pd->precision != precision)
+     pd->precision = precision;
+}
+
+EOLIAN static int
+_evas_3d_primitive_precision_get(Eo *obj EINA_UNUSED,
+                                 Evas_3D_Primitive_Data *pd)
+{
+   return pd->precision;
+}
+
+EOLIAN static void
+_evas_3d_primitive_surface_set(Eo *obj EINA_UNUSED,
+                               Evas_3D_Primitive_Data *pd,
+                               Evas_3D_Surface_Func surface_func)
+{
+   pd->surface = surface_func;
+}
+
+EOLIAN static void
+_evas_3d_primitive_tex_scale_set(Eo *obj EINA_UNUSED,
+                                 Evas_3D_Primitive_Data *pd,
+                                 Evas_Real x,
+                                 Evas_Real y)
+{
+   if (x) pd->tex_scale.x = x;
+   if (y) pd->tex_scale.y = y;
+}
+
+EOLIAN static void
+_evas_3d_primitive_tex_scale_get(Eo *obj EINA_UNUSED,
+                                 Evas_3D_Primitive_Data *pd,
+                                 Evas_Real *x,
+                                 Evas_Real *y)
+{
+   if (x) *x = pd->tex_scale.x;
+   if (y) *y = pd->tex_scale.y;
+}
+
+#include "canvas/evas_3d_primitive.eo.c"
diff --git a/src/lib/evas/canvas/evas_3d_primitive.eo 
b/src/lib/evas/canvas/evas_3d_primitive.eo
new file mode 100644
index 0000000..e1336c6
--- /dev/null
+++ b/src/lib/evas/canvas/evas_3d_primitive.eo
@@ -0,0 +1,179 @@
+class Evas_3D_Primitive (Evas_3D_Object, Evas.Common_Interface)
+{
+   legacy_prefix: null;
+   data: Evas_3D_Primitive_Data;
+
+   methods {
+      @property form {
+         set {
+             /*
+              *Set the form of the given primitive.
+              *
+              *Form defines which function will be chosen to set data to mesh
+              *on call of evas_3d_mesh_primitive_set.
+              *
+              *Now avaliable next forms of primitives:
+              *-tabulated primitives: SQUARE and CUBE;
+              *-solids of revolution: CYLINDER, CONE, SPHERE and TORUS;
+              *-surfaces: SURFACE and TERRAIN.
+              *
+              *Default form is EVAS_3D_MESH_PRIMITIVE_NONE
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         get {
+             /*
+              *Get the form of the given primitive.
+              *@see evas_3d_primitive_form_set()
+              *@return The form of primitive.
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            form: Evas_3D_Mesh_Primitive; /*@ Form of primitive.*/
+         }
+      }
+      @property mode {
+         set {
+             /*
+              *Set the mode of the given primitive.
+              *
+              *Mode defines which function will be chosen to set data to mesh
+              *on call of evas_3d_mesh_primitive_set. It helps to choose
+              *alternative algorithm for primitive with given form
+              *(like cone without base or sphere textured in alternative way).
+              *
+              *Now avaliable next mods of primitives:
+              *-witout base (bases): supported for cylinder and cone;
+              *-with alternative UV: supported by sphere;
+              *
+              *Default form is EVAS_3D_PRIMITIVE_MODE_DEFAULT
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         get {
+             /*
+              *Get the mode of the given primitive.
+              *@see evas_3d_primitive_mode_set()
+              *@return The mode of primitive.
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            mode: Evas_3D_Primitive_Mode; /*@ Mode of primitive.*/
+         }
+      }
+      @property ratio {
+         set {
+             /*
+              *Set the ratio of the given primitive.
+              *
+              *Now ratio uses only in torus as the ratio of the
+              *major radius and minor radius. For this usage 
+              *Avaliable values is from 1.0 to infinity.
+              *If ratio for torus has a bad value,
+              *will be used 3.0 as ratio. Like ratio of usual doughnut.
+              *
+              *Default ratio is 3.0
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         get {
+             /*
+              *Get the ratio of the given primitive.
+              *@see evas_3d_primitive_ratio_set()
+              *@return The ratio of primitive.
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            ratio: Evas_Real; /*@ Ratio of primitive.*/
+         }
+      }
+      @property precision {
+         set {
+             /*
+              *Set the precision of the given primitive.
+              *
+              *Precision uses in all non tabulated primitives and defines
+              *precision of created primitives.
+              *Avaliable values is from 3 to infinity.
+              *But if value will be more than 100, should be a warning
+              *about possibility of incorrect or slow work.
+              *
+              *Default ratio is 10
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         get {
+             /*
+              *Get the precision of the given primitive.
+              *@see evas_3d_primitive_precision_set()
+              *@return The precision of primitive.
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            precision: int; /*@ Precision of primitive.*/
+         }
+      }
+      @property surface {
+         set {
+             /*
+              *Set the surface of the given primitive.
+              *
+              *Surface uses only in surface primitive and defines
+              *equation of filling mesh data on call of
+              *evas_3d_mesh_primitive_set.
+              *
+              *It gives possibility to create customers primitives like
+              *shell, heart, hyperbolic paraboloid etc. See _shell_func in
+              *examples/evas/evas-3d-visual-test.c or _perlin_terrain in
+              *modules/evas/primitives/surfaces/terrain.c as an example of 
usage.
+              *
+              *Default surface is NULL
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            surface: Evas_3D_Surface_Func *; /*@ Pointer to customers surface 
function.*/
+         }
+      }
+      @property tex_scale {
+         set {
+             /*
+              *Set the texture scale of the given primitive.
+              *
+              *Texture scale uses in all non tabulated primitives
+              *and defines scale of texture coords or primitives.
+              *
+              *It uses to create periodical textured meshes.
+              *
+              *Default tex_scale is {1.0, 1.0}
+              *
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         get {
+             /*
+              *Get the texture scale of the given primitive.
+              *@see evas_3d_primitive_tex_scale_set()
+              *@ingroup Evas_3D_Primitive
+              */
+         }
+         values {
+            tex_scale_x: Evas_Real;
+            tex_scale_y: Evas_Real;
+         }
+      }
+   }
+   implements {
+      Eo.Base.constructor;
+      Eo.Base.destructor;
+   }
+}
diff --git a/src/lib/evas/common3d/primitives/primitive_common.c 
b/src/lib/evas/common3d/primitives/primitive_common.c
new file mode 100644
index 0000000..066ef3b
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/primitive_common.c
@@ -0,0 +1,209 @@
+#include "primitive_common.h"
+
+void _set_vertex_data_from_array(Evas_3D_Mesh *mesh,
+                                 int frame,
+                                 const float *data,
+                                 Evas_3D_Vertex_Attrib attr,
+                                 int start,
+                                 int attr_count,
+                                 int line,
+                                 int vcount)
+{
+   float *address, *out;
+   int stride, i, j;
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
+         address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
+         stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
+   if (stride == 0) stride = sizeof(float) * attr_count;
+   for (i = 0; i < vcount; i++)
+     {
+        out = (float *)((char *)address + stride * i);
+        for (j = 0; j < attr_count; j++)
+           out[j] = data[start + (line * i) + j];
+     }
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
+}
+
+void
+_set_vec3_vertex_data(Evas_3D_Mesh *mesh,
+                      int frame,
+                      int vcount,
+                      Evas_Vec3 *data,
+                      Evas_3D_Vertex_Attrib attr)
+{
+   float *address, *out;
+   int stride, i;
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
+         address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
+         stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
+   if (stride == 0) stride = sizeof(float) * 3;
+   for (i = 0; i < vcount; i++)
+     {
+        out = (float *)((char *)address + stride * i);
+        out[0] = data[i].x;
+        out[1] = data[i].y;
+        out[2] = data[i].z;
+     }
+   free(data);
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
+}
+
+void
+_set_vec2_vertex_data(Evas_3D_Mesh *mesh,
+                      int frame,
+                      int vcount,
+                      Evas_Vec2 *data,
+                      Evas_3D_Vertex_Attrib attr)
+{
+   float *address, *out;
+   int stride, i;
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
+         address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
+         stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
+   if (stride == 0) stride = sizeof(float) * 2;
+   for (i = 0; i < vcount; i++)
+     {
+        out = (float *)((char *)address + stride * i);
+        out[0] = data[i].x;
+        out[1] = data[i].y;
+     }
+   free(data);
+   eo_do(mesh,
+         evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
+}
+
+void
+_generate_indices(unsigned short *indices, int a, int b)
+{
+   int i, j, a1 = a + 1;
+   unsigned short *index = &indices[0];
+
+   for (i = 0; i < b; i++)
+     {
+        for (j = 0; j < a; j++)
+          {
+             *index++ = j + a1 * i;
+             *index++ = j + a1 * (i + 1);
+             *index++ = j + 1 + a1 * (i + 1);
+
+             *index++ = j + a1 * i;
+             *index++ = j + 1 +  a1 * i;
+             *index++ = j + a1 * (i + 1) + 1;
+          }
+     }
+}
+
+void
+_primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src)
+{
+   dst->x = src->x;
+   dst->y = src->y;
+   dst->z = src->z;
+}
+
+void
+_primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 
*b)
+{
+   out->x = a->x - b->x;
+   out->y = a->y - b->y;
+   out->z = a->z - b->z;
+}
+
+void
+_primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const 
Evas_Vec3 *b)
+{
+   Evas_Vec3 tmp;
+
+   tmp.x = a->y * b->z - a->z * b->y;
+   tmp.y = a->z * b->x - a->x * b->z;
+   tmp.z = a->x * b->y - a->y * b->x;
+
+   _primitives_vec3_copy(out, &tmp);
+}
+
+void
+_primitives_vec3_normalize(Evas_Vec3 *out)
+{
+   Evas_Real size = out->x * out->x + out->y *out->y + out->z * out->z;
+   size = sqrt(size);
+   out->x /= size;
+   out->y /= size;
+   out->z /= size;
+}
+
+void
+evas_common_set_model_from_primitive(Evas_3D_Mesh *model,
+                                     int frame,
+                                     Evas_3D_Primitive_Data *primitive)
+{
+   Evas_Real ratio = primitive->ratio;
+   int precision = primitive->precision;
+   Evas_3D_Surface_Func *surface = primitive->surface;
+   Evas_Vec2 tex_scale = primitive->tex_scale;
+   Evas_3D_Primitive_Mode mode = primitive->mode;
+
+   switch (primitive->form)
+     {
+      case EVAS_3D_MESH_PRIMITIVE_NONE:
+      case EVAS_3D_MESH_PRIMITIVE_COUNT:
+        {
+           ERR("Primitive with this type cannot be set to mesh.");
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_SQUARE:
+        {
+           evas_model_set_from_square_primitive(model, frame);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_CUBE:
+        {
+           evas_model_set_from_cube_primitive(model, frame);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_CYLINDER:
+        {
+           evas_model_set_from_cylinder_primitive(model, frame, mode,
+                                                  precision, tex_scale);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_CONE:
+        {
+           evas_model_set_from_cone_primitive(model, frame, mode,
+                                              precision, tex_scale);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_SPHERE:
+        {
+           evas_model_set_from_sphere_primitive(model, frame, mode,
+                                                precision, tex_scale);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_TORUS:
+        {
+           evas_model_set_from_torus_primitive(model, frame,
+                                               ratio, precision, tex_scale);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_SURFACE:
+        {
+           evas_model_set_from_surface_primitive(model, frame,
+                                                 surface, precision, 
tex_scale);
+           break;
+        }
+      case EVAS_3D_MESH_PRIMITIVE_TERRAIN:
+        {
+           evas_model_set_from_terrain_primitive(model, frame,
+                                                 precision, tex_scale);
+           break;
+        }
+      default:
+        {
+           ERR("Unknown type of primitive");
+        }
+     }
+}
diff --git a/src/lib/evas/common3d/primitives/primitive_common.h 
b/src/lib/evas/common3d/primitives/primitive_common.h
new file mode 100644
index 0000000..c2b47f3
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/primitive_common.h
@@ -0,0 +1,58 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif //HAVE_CONFIG_H
+
+#ifndef PRIMITIVE_COMMON
+#define PRIMITIVE_COMMON
+#include "evas_options.h"
+
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#define ALLOCATE_VERTEX_DATA                                  \
+   Evas_Vec3 *vertices = malloc(sizeof(Evas_Vec3) * vcount);  \
+   Evas_Vec3 *normals = malloc(sizeof(Evas_Vec3) * vcount);   \
+   Evas_Vec2 *tex_coord = malloc(sizeof(Evas_Vec2) * vcount); \
+   Evas_Vec3 *tangents = malloc(sizeof(Evas_Vec3) * vcount);  \
+   unsigned short *indices = malloc(sizeof(short) * icount);
+
+#define SET_VERTEX_DATA(frame)                                                 
    \
+   eo_do(mesh,                                                                 
    \
+         evas_3d_mesh_vertex_count_set(vcount),                                
    \
+         evas_3d_mesh_frame_add(frame),                                        
    \
+         evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, 
    \
+                                          icount, &indices[0]));               
    \
+   _set_vec3_vertex_data(mesh, frame, vcount, vertices, 
EVAS_3D_VERTEX_POSITION);  \
+   _set_vec3_vertex_data(mesh, frame, vcount, normals, EVAS_3D_VERTEX_NORMAL); 
    \
+   _set_vec2_vertex_data(mesh, frame, vcount, tex_coord, 
EVAS_3D_VERTEX_TEXCOORD); \
+   _set_vec3_vertex_data(mesh, frame, vcount, tangents, 
EVAS_3D_VERTEX_TANGENT);   \
+   free(indices);
+
+#define SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, varray, vcount, indices, 
icount) \
+   eo_do(mesh, \
+         evas_3d_mesh_vertex_count_set(vcount), \
+         evas_3d_mesh_frame_add(frame), \
+         evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, 
\
+                                          icount, &indices[0])); \
+   _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_POSITION, \
+                               0, 3, 15, vcount); \
+   _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_NORMAL, \
+                               3, 3, 15, vcount); \
+   _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_COLOR, \
+                               6, 4, 15, vcount); \
+   _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TEXCOORD, \
+                               10, 2, 15, vcount); \
+   _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TANGENT, \
+                               12, 3, 15, vcount);
+
+void _generate_indices(unsigned short *indices, int count, int width);
+void _set_vec3_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, 
Evas_Vec3 *data, Evas_3D_Vertex_Attrib attr);
+void _set_vec2_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, 
Evas_Vec2 *data, Evas_3D_Vertex_Attrib attr);
+void _set_vertex_data_from_array(Evas_3D_Mesh *mesh, int frame, const float 
*data, Evas_3D_Vertex_Attrib attr, int start, int attr_count, int line, int 
vcount);
+
+void _primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src);
+void _primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const 
Evas_Vec3 *b);
+void _primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const 
Evas_Vec3 *b);
+void _primitives_vec3_normalize(Evas_Vec3 *out);
+
+#endif //PRIMITIVE_COMMON
diff --git a/src/lib/evas/common3d/primitives/solids_of_revolution/cone.c 
b/src/lib/evas/common3d/primitives/solids_of_revolution/cone.c
new file mode 100644
index 0000000..2b62f28
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/cone.c
@@ -0,0 +1,140 @@
+#include "../primitive_common.h"
+
+void
+_set_default_cone(Evas_3D_Mesh *mesh,
+                  int frame,
+                  int p,
+                  Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j, num;
+   double dfi, fi, sinfi, cosfi, nplane, nz;
+
+   icount = p * 18;
+   vccount = p + 1;
+   vcount = 4 * vccount;
+
+   dfi = 2.0 * M_PI / p;
+   nz = sqrt(1.0 / 3.0);
+   nplane = sqrt(2.0 / 3.0);
+
+   ALLOCATE_VERTEX_DATA
+
+   for (i = 0; i < vccount; i++)
+     {
+        fi = i * dfi;
+        sinfi = sin(fi);
+        cosfi = cos(fi);
+
+        vertices[i].x = 0.0;
+        vertices[i].y = 0.0;
+        vertices[i].z = -0.5;
+        vertices[i + vccount].x = sinfi / 2.0;
+        vertices[i + vccount].y = cosfi / 2.0;
+        vertices[i + vccount].z = -0.5;
+        vertices[i + 2 * vccount] = vertices[i + vccount];
+        vertices[i + 3 * vccount].x = 0.0;
+        vertices[i + 3 * vccount].y = 0.0;
+        vertices[i + 3 * vccount].z = 0.5;
+
+        normals[i].x = normals[i].y = 0.0;
+        normals[i].z = -1.0;
+        normals[i + vccount] = normals[i];
+        normals[i + 2 * vccount].x = sinfi * nplane;
+        normals[i + 2 * vccount].y = cosfi * nplane;
+        normals[i + 2 * vccount].z = nz;
+        normals[i + 3 * vccount] = normals[i + 2 * vccount];
+
+        for (j = 0; j < 4; j++)
+          {
+             num = i + j * vccount;
+
+             tangents[num].x = cosfi;
+             tangents[num].y = -sinfi;
+             tangents[num].z = 0.0;
+
+             tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
+             tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 2.0;
+          }
+     }
+
+   _generate_indices(indices, p, 3);
+
+   SET_VERTEX_DATA(frame)
+}
+
+void
+_set_cone_without_base(Evas_3D_Mesh *mesh,
+                       int frame,
+                       int p,
+                       Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i;
+   double dfi, fi, sinfi, cosfi, nplane, nz;
+
+   icount = p * 6;
+   vccount = p + 1;
+   vcount = 2 * vccount;
+
+   dfi = 2.0 * M_PI / p;
+   nz = sqrt(1.0 / 3.0);
+   nplane = sqrt(2.0 / 3.0);
+
+   ALLOCATE_VERTEX_DATA
+
+   for (i = 0; i < vccount; i++)
+     {
+        fi = i * dfi;
+        sinfi = sin(fi);
+        cosfi = cos(fi);
+        vertices[i].x = sinfi / 2.0;
+        vertices[i].y = cosfi / 2.0;
+        vertices[i].z = -0.5;
+        vertices[i + vccount].x = 0;
+        vertices[i + vccount].y = 0;
+        vertices[i + vccount].z = 0.5;
+
+        normals[i + vccount].x = normals[i].x = sinfi * nplane;
+        normals[i + vccount].y = normals[i].y = cosfi * nplane;
+        normals[i + vccount].z = normals[i].z = nz;
+
+        tangents[i + vccount].x = tangents[i].x = cosfi;
+        tangents[i + vccount].y = tangents[i].y = -sinfi;
+        tangents[i + vccount].z = tangents[i].z = 0;
+
+        tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
+        tex_coord[i].y = 0;
+        tex_coord[i + vccount].x = tex_coord[i].x;
+        tex_coord[i + vccount].y = tex_scale.y;
+     }
+
+   _generate_indices(indices, p, 1);
+
+   SET_VERTEX_DATA(frame)
+}
+
+void
+evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh,
+                                   int frame,
+                                   Evas_3D_Primitive_Mode mode,
+                                   int p,
+                                   Evas_Vec2 tex_scale)
+{
+   switch (mode)
+     {
+      case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
+      case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
+        {
+           _set_default_cone(mesh, frame, p, tex_scale);
+           break;
+        }
+      case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
+        {
+           _set_cone_without_base(mesh, frame, p, tex_scale);
+           break;
+        }
+      default:
+        {
+           ERR("Unknown mode of primitive");
+        }
+     }
+}
diff --git a/src/lib/evas/common3d/primitives/solids_of_revolution/cylinder.c 
b/src/lib/evas/common3d/primitives/solids_of_revolution/cylinder.c
new file mode 100644
index 0000000..dabe6f4
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/cylinder.c
@@ -0,0 +1,136 @@
+#include "../primitive_common.h"
+
+void
+_set_default_cylinder(Evas_3D_Mesh *mesh,
+                      int frame,
+                      int p,
+                      Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j, num;
+   icount = p * 30;
+   vccount = p + 1;
+   vcount = 6 * vccount;
+
+   ALLOCATE_VERTEX_DATA
+
+   double dfi, fi, sinfi, cosfi;
+   dfi = 2 * M_PI / p;
+
+   for (i = 0; i < vccount; i++)
+     {
+        fi = i * dfi;
+        sinfi = sin(fi);
+        cosfi = cos(fi);
+
+        for (j = 0; j < 6; j++)
+          {
+             num = i + j * vccount;
+
+             vertices[num].z = -0.5 + (float)(j / 3);
+             if ((j == 0) || (j == 5))
+               {
+                  vertices[num].x = vertices[num].y = 0.0;
+               }
+             else
+               {
+                  vertices[num].x = sinfi / 2.0;
+                  vertices[num].y = cosfi / 2.0;
+               }
+
+             if ((j == 2) || (j == 3))
+               {
+                  normals[num].x = sinfi;
+                  normals[num].y = cosfi;
+                  normals[num].z = 0.0;
+               }
+             else
+               {
+                  normals[num].x = normals[num].y = 0.0;
+                  normals[num].z = -1.0 + (float)(j / 2);
+               }
+
+             tangents[num].x = cosfi;
+             tangents[num].y = -sinfi;
+             tangents[num].z = 0.0;
+
+             tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
+             tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 3.0;
+          }
+     }
+
+   _generate_indices(indices, p, 5);
+
+   SET_VERTEX_DATA(frame)
+}
+
+void
+_set_cylinder_without_bases(Evas_3D_Mesh *mesh,
+                            int frame,
+                            int p,
+                            Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i;
+   icount = p * 6;
+   vccount = p + 1;
+   vcount = 2 * vccount;
+
+   ALLOCATE_VERTEX_DATA
+
+   double dfi, fi, sinfi, cosfi;
+   dfi = 2 * M_PI / p;
+
+   for (i = 0; i < vccount; i++)
+     {
+        fi = i * dfi;
+        sinfi = sin(fi);
+        cosfi = cos(fi);
+        vertices[i + vccount].x = vertices[i].x = sinfi / 2.0;
+        vertices[i + vccount].y = vertices[i].y = cosfi / 2.0;
+        vertices[i].z = -0.5;
+        vertices[i + vccount].z = 0.5;
+
+        normals[i + vccount].x = normals[i].x = sinfi;
+        normals[i + vccount].y = normals[i].y = cosfi;
+        normals[i + vccount].z = normals[i].z = 0;
+
+        tangents[i + vccount].x = tangents[i].x = cosfi;
+        tangents[i + vccount].y = tangents[i].y = -sinfi;
+        tangents[i + vccount].z = tangents[i].z = 0;
+
+        tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
+        tex_coord[i].y = 0;
+        tex_coord[i + vccount].x = i / (float)(vccount - 1) * tex_scale.x;
+        tex_coord[i + vccount].y = tex_scale.y;
+     }
+
+   _generate_indices(indices, p, 1);
+
+   SET_VERTEX_DATA(frame)
+}
+
+void
+evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh,
+                                       int frame,
+                                       Evas_3D_Primitive_Mode mode,
+                                       int p,
+                                       Evas_Vec2 tex_scale)
+{
+   switch (mode)
+     {
+      case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
+      case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
+        {
+           _set_default_cylinder(mesh, frame, p, tex_scale);
+           break;
+        }
+      case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
+        {
+           _set_cylinder_without_bases(mesh, frame, p, tex_scale);
+           break;
+        }
+      default:
+        {
+           ERR("Unknown mode of primitive");
+        }
+     }
+}
diff --git a/src/lib/evas/common3d/primitives/solids_of_revolution/sphere.c 
b/src/lib/evas/common3d/primitives/solids_of_revolution/sphere.c
new file mode 100644
index 0000000..1a2409b
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/sphere.c
@@ -0,0 +1,189 @@
+#include "../primitive_common.h"
+
+void
+_set_default_sphere(Evas_3D_Mesh *mesh,
+                   int frame,
+                   int p,
+                   Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j;
+   icount = p * p * 6;
+   vccount = p + 1;
+   vcount = vccount * vccount;
+
+   ALLOCATE_VERTEX_DATA
+
+   double dtheta, dfi, sinth, costh, fi, theta, sinfi, cosfi;
+   dtheta = M_PI / p;
+   dfi = 2 * M_PI / p;
+
+   for (j = 0; j < vccount; j++)
+     {
+        theta = j * dtheta;
+        sinth = sin(theta);
+        costh = cos(theta);
+        for (i = 0; i < vccount; i++)
+          {
+             fi = i * dfi;
+             sinfi = sin(fi);
+             cosfi = cos(fi);
+             normals[i + j * vccount].x = sinth * sinfi;
+             normals[i + j * vccount].y = sinth * cosfi;
+             normals[i + j * vccount].z = costh;
+
+             vertices[i + j * vccount].x = normals[i + j * vccount].x / 2;
+             vertices[i + j * vccount].y = normals[i + j * vccount].y / 2;
+             vertices[i + j * vccount].z = normals[i + j * vccount].z / 2;
+
+             tangents[i + j * vccount].x = -sinth * cosfi;
+             tangents[i + j * vccount].y = sinth * sinfi;
+             tangents[i + j * vccount].z = 0;
+
+             _primitives_vec3_normalize(&tangents[i + j * vccount]);
+
+             tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * 
tex_scale.x;
+             tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 
1) * tex_scale.y;
+          }
+     }
+
+   _generate_indices(indices, p, p);
+
+   SET_VERTEX_DATA(frame)
+}
+
+void
+_set_sphere_with_alternative_uv(Evas_3D_Mesh *mesh,
+                                int frame,
+                                int p,
+                                Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j;
+
+   vccount = p + 1;
+   vcount = vccount * vccount;
+   icount = p * p * 6;
+
+   ALLOCATE_VERTEX_DATA
+
+   /* Calculate vertices position of the sphere mesh by using
+      splitting of sphere by latitude and longitude. */
+   for (i = 0; i <= p; i++)
+     {
+        double lati, z, r, point_r;
+
+        point_r = 0.00001;//non-zero little value for correct tangents 
calculation.
+
+        lati = ((M_PI - 2 * point_r) * (double)i) / (double)p;
+        z = cos(lati + point_r);
+        r = fabs(sin(lati + point_r));
+
+        for (j = 0; j <= p; j++)
+          {
+             double longi;
+             int num = (i * (p + 1)) + j;
+
+             longi = (M_PI * 2.0 * (double)j) / (double)p;
+
+             normals[num].x = r * sin(longi);
+             normals[num].y = r * cos(longi);
+             normals[num].z = z;
+
+             vertices[num].x = normals[num].x / 2;
+             vertices[num].y = normals[num].y / 2;
+             vertices[num].z = normals[num].z / 2;
+
+             if (vertices[num].x > 0.0)
+               {
+                  tangents[num].x = -normals[num].z;
+                  tangents[num].y = normals[num].y;
+                  tangents[num].z = normals[num].x;
+               }
+             else
+               {
+                  tangents[num].x = normals[num].z;
+                  tangents[num].y = normals[num].y;
+                  tangents[num].z = -normals[num].x;
+               }
+
+             tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
+             tex_coord[num].y = tex_scale.y - j / (float)(vccount - 1) * 
tex_scale.y;
+          }
+     }
+
+   _generate_indices(indices, p, p);
+
+   /* Triangulation of sphere mesh in appliance with buffer of indices. */
+   for (i = 0; i < icount; i += 3)
+     {
+        Evas_Vec3 e1, e2;
+        float du1, du2, dv1, dv2, f;
+        Evas_Vec3 tangent;
+        int num0, num1, num2;
+
+        num0 = indices[i + 0];
+        num1 = indices[i + 1];
+        num2 = indices[i + 2];
+
+        e1.x = vertices[num1].x - vertices[num0].x;
+        e1.y = vertices[num1].y - vertices[num0].y;
+        e1.z = vertices[num1].z - vertices[num0].z;
+
+        e2.x = vertices[num2].x - vertices[num0].x;
+        e2.y = vertices[num2].y - vertices[num0].y;
+        e2.z = vertices[num2].z - vertices[num0].z;
+
+        du1 = tex_coord[num1].x - tex_coord[num0].x;
+        dv1 = tex_coord[num1].y - tex_coord[num0].y;
+
+        du2 = tex_coord[num2].x - tex_coord[num0].x;
+        dv2 = tex_coord[num2].y - tex_coord[num0].y;
+
+        f = 1.0 / ((du1 * dv2) - (du2 * dv1));
+
+        tangent.x = f * ((dv2 * e1.x) - (dv1 * e2.x));
+        tangent.y = f * ((dv2 * e1.y) - (dv1 * e2.y));
+        tangent.z = f * ((dv2 * e1.z) - (dv1 * e2.z));
+
+        tangents[num0] = tangent;
+     }
+
+   /* Coupling between vertices by calculation of tangent parametr correct 
value. */
+   for (i = 0; i <= p; i++)
+     {
+        for (j = 0; j <= p; j++)
+          {
+             if (j == p)
+               {
+                  tangents[(i * (p  + 1)) + j] = tangents[i * (p + 1)];
+               }
+          }
+     }
+   SET_VERTEX_DATA(frame)
+}
+
+void
+evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh,
+                                     int frame,
+                                     Evas_3D_Primitive_Mode mode,
+                                     int p,
+                                     Evas_Vec2 tex_scale)
+{
+   switch (mode)
+     {
+      case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
+      case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
+        {
+           _set_default_sphere(mesh, frame, p, tex_scale);
+           break;
+        }
+      case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
+        {
+           _set_sphere_with_alternative_uv(mesh, frame, p, tex_scale);
+           break;
+        }
+      default:
+        {
+           ERR("Unknown mode of primitive");
+        }
+     }
+}
diff --git a/src/lib/evas/common3d/primitives/solids_of_revolution/torus.c 
b/src/lib/evas/common3d/primitives/solids_of_revolution/torus.c
new file mode 100644
index 0000000..abb76d8
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/torus.c
@@ -0,0 +1,67 @@
+#include "../primitive_common.h"
+
+void
+evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh,
+                                    int frame,
+                                    Evas_Real ratio,
+                                    int p,
+                                    Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j;
+   icount = p * p * 6;
+   vccount = p + 1;
+   vcount = vccount * vccount;
+
+   ALLOCATE_VERTEX_DATA
+
+   double d, sinth, costh, fi, theta, sinfi, cosfi;
+
+   d = 2 * M_PI / p;
+
+   float rratio;
+
+   if ((ratio < 1.0))
+     {
+        printf("Ratio of torus should be greater than or equal 1.0.\n");
+        printf("Ratio = %f is a bad value, so 3.0 is used like default 
ratio.\n",
+                ratio);
+        rratio = 1.0 / 3.0;
+     }
+   else
+     {
+        rratio = 1.0 / ratio;
+     }
+
+   for (j = 0; j < vccount; j++)
+     {
+        theta = j * d;
+        sinth = sin(theta);
+        costh = cos(theta);
+        for (i = 0; i < vccount; i++)
+          {
+             fi = i * d;
+             sinfi = sin(fi);
+             cosfi = cos(fi);
+             vertices[i + j * vccount].x = (1.0 - rratio + rratio * cosfi) * 
costh * 0.5;
+             vertices[i + j * vccount].y = (1.0 - rratio + rratio * cosfi) * 
sinth * 0.5;
+             vertices[i + j * vccount].z = rratio * sinfi * 0.5;
+
+             normals[i + j * vccount].x = cosfi * costh;
+             normals[i + j * vccount].y = cosfi * sinth;
+             normals[i + j * vccount].z = sinfi;
+
+             tangents[i + j * vccount].x = -sinfi * costh;
+             tangents[i + j * vccount].y = -sinfi * sinth;
+             tangents[i + j * vccount].z = cosfi;
+
+             _primitives_vec3_normalize(&normals[i + j * vccount]);
+
+             tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * 
tex_scale.x;
+             tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 
1) * tex_scale.y;
+          }
+     }
+
+   _generate_indices(indices, p, p);
+
+   SET_VERTEX_DATA(frame)
+}
diff --git a/src/lib/evas/common3d/primitives/surfaces/surface.c 
b/src/lib/evas/common3d/primitives/surfaces/surface.c
new file mode 100644
index 0000000..7eb1779
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/surfaces/surface.c
@@ -0,0 +1,91 @@
+#include "../primitive_common.h"
+
+Evas_Vec3 _get_func_normal(Evas_3D_Surface_Func *func, Evas_Real x, Evas_Real 
y)
+{
+   Evas_Vec3 v00, v01, v10, d1, d2, normal;
+
+   func(&v00.x, &v00.y, &v00.z, x, y);
+   func(&v01.x, &v01.y, &v01.z, x, y + 0.01);
+   func(&v10.x, &v10.y, &v10.z, x + 0.01, y);
+   _primitives_vec3_subtract(&d1, &v00, &v01);
+   _primitives_vec3_subtract(&d2, &v01, &v10);
+
+   _primitives_vec3_cross_product(&normal, &d1, &d2);
+
+   _primitives_vec3_normalize(&normal);
+
+   return normal;
+}
+
+void
+_normalize(Evas_Vec3 *vertices, Evas_Vec3 *normals, int vcount)
+{
+   int i;
+   Evas_Vec3 min, max;
+   min = max = vertices[0];
+
+#define CHECK_MIN_AND_MAX(coord)                \
+        if (min.coord > vertices[i].coord)      \
+          min.coord = vertices[i].coord;        \
+        else if (max.coord < vertices[i].coord) \
+          max.coord = vertices[i].coord;
+   for (i = 1; i < vcount; i++)
+     {
+        CHECK_MIN_AND_MAX(x)
+        CHECK_MIN_AND_MAX(y)
+        CHECK_MIN_AND_MAX(z)
+     }
+#undef CHECK_MIN_AND_MAX
+
+   for (i = 0; i < vcount; i++)
+     {
+        vertices[i].x = (vertices[i].x - min.x) / (max.x - min.x) - 0.5;
+        vertices[i].y = (vertices[i].y - min.y) / (max.y - min.y) - 0.5;
+        vertices[i].z = (vertices[i].z - min.z) / (max.z - min.z) - 0.5;
+
+        normals[i].x = normals[i].x / (max.x - min.x);
+        normals[i].y = normals[i].y / (max.y - min.y);
+        normals[i].z = normals[i].z / (max.z - min.z);
+     }
+}
+
+void
+evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh,
+                                      int frame,
+                                      Evas_3D_Surface_Func func,
+                                      int p,
+                                      Evas_Vec2 tex_scale)
+{
+   int vcount, icount, vccount, i, j, num;
+   icount = p * p * 6;
+   vccount = p + 1;
+   vcount = vccount * vccount;
+
+   ALLOCATE_VERTEX_DATA
+
+   Evas_Real v, u, d = 1.0 / p;
+
+   for (j = 0; j < vccount; j++)
+     {
+        u = j * d - 0.5;
+        for (i = 0; i < vccount; i++)
+          {
+             v = i * d - 0.5;
+             num = i + j * vccount;
+             func(&vertices[num].x,
+                  &vertices[num].y,
+                  &vertices[num].z,
+                  v, u);
+             normals[num] = _get_func_normal(func, v, u);
+
+             tangents[num].x = tangents[num].y = tangents[num].z = 0;
+
+             tex_coord[num].x = i / ((vccount - 1) * tex_scale.x);
+             tex_coord[num].y = tex_scale.y - j / ((vccount - 1) * 
tex_scale.y);
+          }
+     }
+
+   _normalize(vertices, normals, vcount);
+   _generate_indices(indices, p, p);
+   SET_VERTEX_DATA(frame)
+}
diff --git a/src/lib/evas/common3d/primitives/surfaces/terrain.c 
b/src/lib/evas/common3d/primitives/surfaces/terrain.c
new file mode 100644
index 0000000..542ed74
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/surfaces/terrain.c
@@ -0,0 +1,86 @@
+#include "../primitive_common.h"
+
+static Evas_Real
+_random(int x, int y)
+{
+   int k = x + y * 57;
+   k = (k << 13) ^ k;
+   return (1.0f - ((k * (k * k * 15731 + 789221) + 1376312589) & 0x7fffffff) /
+      1073741824.0f);
+}
+
+static Evas_Real
+_smooth(Evas_Real x, Evas_Real y)
+{
+   Evas_Real res;
+   res = (_random(x - 1, y - 1) + _random(x + 1, y - 1) +
+        _random(x - 1, y + 1) + _random(x + 1, y + 1)) / 16;
+   res += (_random(x - 1, y) + _random(x + 1, y) +
+        _random(x, y - 1) + _random(x, y + 1)) / 8;
+   res += _random(x, y) / 4;
+   return res;
+}
+
+static Evas_Real
+_interpolate(Evas_Real a, Evas_Real b, Evas_Real x)
+{
+   Evas_Real ft = x * M_PI;
+   Evas_Real f = (1 - cosf(ft)) * 0.5;
+   return a * (1 - f) + b * f;
+}
+
+static Evas_Real _noise(Evas_Real x, Evas_Real y)
+{
+   Evas_Real ix = (int)(x);
+   Evas_Real fx = x - ix;
+   Evas_Real iy = (int)(y);
+   Evas_Real fy = y - iy;
+
+   Evas_Real v1 = _smooth(ix, iy);
+   Evas_Real v2 = _smooth(ix + 1, iy);
+   Evas_Real v3 = _smooth(ix, iy + 1);
+   Evas_Real v4 = _smooth(ix + 1, iy + 1);
+
+   Evas_Real i1 = _interpolate(v1, v2, fx);
+   Evas_Real i2 = _interpolate(v3, v4, fx);
+
+   return _interpolate(i1, i2, fy);
+}
+
+static void
+_perlin_terrain(Evas_Real *out_x,
+                Evas_Real *out_y,
+                Evas_Real *out_z,
+                Evas_Real x,
+                Evas_Real y)
+{
+   Evas_Real persistence = 0.5f;
+   Evas_Real frequency = 5;
+   Evas_Real amplitude = 1;
+   int i = 0;
+   int octaves = 5;
+
+   *out_x = x;
+   x += 0.5;
+   *out_y = y;
+   y += 0.5;
+   *out_z = 0;
+
+   for(i = 0; i < octaves; i++)
+     {
+        *out_z += _noise(x * frequency, y * frequency) * amplitude;
+
+        amplitude *= persistence;
+        frequency *= 2;
+     }
+}
+
+void
+evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh,
+                                      int frame,
+                                      int p,
+                                      Evas_Vec2 tex_scale)
+{
+   evas_model_set_from_surface_primitive(mesh, frame, _perlin_terrain, p, 
tex_scale);
+}
+
diff --git a/src/lib/evas/common3d/primitives/tabulated_primitives/cube.c 
b/src/lib/evas/common3d/primitives/tabulated_primitives/cube.c
new file mode 100644
index 0000000..6f70a02
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/tabulated_primitives/cube.c
@@ -0,0 +1,57 @@
+#include "../primitive_common.h"
+
+const float vertices_of_cube[] =
+{
+   /* positions        normals            vertex_color          tex_coords  
tangents    */
+   /* Front */
+    0.5, -0.5,  0.5,   0.0, -1.0,  0.0,   0.0, 1.0, 1.0, 1.0,   0.0, 0.0,  
-1.0, 0.0, 0.0,
+   -0.5, -0.5,  0.5,   0.0, -1.0,  0.0,   0.0, 1.0, 1.0, 1.0,   1.0, 0.0,  
-1.0, 0.0, 0.0,
+   -0.5, -0.5, -0.5,   0.0, -1.0,  0.0,   0.0, 1.0, 1.0, 1.0,   1.0, 1.0,  
-1.0, 0.0, 0.0,
+    0.5, -0.5, -0.5,   0.0, -1.0,  0.0,   0.0, 1.0, 1.0, 1.0,   0.0, 1.0,  
-1.0, 0.0, 0.0,
+
+   /* Left */
+   -0.5, -0.5,  0.5,  -1.0,  0.0,  0.0,   0.0, 1.0, 0.0, 1.0,   1.0, 0.0,   
0.0, 0.0, 1.0,
+   -0.5,  0.5,  0.5,  -1.0,  0.0,  0.0,   0.0, 1.0, 0.0, 1.0,   1.0, 1.0,   
0.0, 0.0, 1.0,
+   -0.5,  0.5, -0.5,  -1.0,  0.0,  0.0,   0.0, 1.0, 0.0, 1.0,   0.0, 1.0,   
0.0, 0.0, 1.0,
+   -0.5, -0.5, -0.5,  -1.0,  0.0,  0.0,   0.0, 1.0, 0.0, 1.0,   0.0, 0.0,   
0.0, 0.0, 1.0,
+
+   /* Back */
+   -0.5,  0.5,  0.5,   0.0,  1.0,  0.0,   1.0, 0.0, 1.0, 1.0,   0.0, 0.0,   
1.0, 0.0, 0.0,
+    0.5,  0.5,  0.5,   0.0,  1.0,  0.0,   1.0, 0.0, 1.0, 1.0,   1.0, 0.0,   
1.0, 0.0, 0.0,
+    0.5,  0.5, -0.5,   0.0,  1.0,  0.0,   1.0, 0.0, 1.0, 1.0,   1.0, 1.0,   
1.0, 0.0, 0.0,
+   -0.5,  0.5, -0.5,   0.0,  1.0,  0.0,   1.0, 0.0, 1.0, 1.0,   0.0, 1.0,   
1.0, 0.0, 0.0,
+
+   /* Right */
+    0.5,  0.5,  0.5,   1.0,  0.0,  0.0,   1.0, 1.0, 0.0, 1.0,   0.0, 1.0,   
0.0, 0.0, -1.0,
+    0.5, -0.5,  0.5,   1.0,  0.0,  0.0,   1.0, 1.0, 0.0, 1.0,   0.0, 0.0,   
0.0, 0.0, -1.0,
+    0.5, -0.5, -0.5,   1.0,  0.0,  0.0,   1.0, 1.0, 0.0, 1.0,   1.0, 0.0,   
0.0, 0.0, -1.0,
+    0.5,  0.5, -0.5,   1.0,  0.0,  0.0,   1.0, 1.0, 0.0, 1.0,   1.0, 1.0,   
0.0, 0.0, -1.0,
+
+   /* Top */
+   -0.5, -0.5,  0.5,   0.0,  0.0,  1.0,   1.0, 0.0, 0.0, 1.0,   0.0, 0.0,   
1.0, 0.0, 0.0,
+   -0.5,  0.5,  0.5,   0.0,  0.0,  1.0,   1.0, 0.0, 0.0, 1.0,   0.0, 1.0,   
1.0, 0.0, 0.0,
+    0.5,  0.5,  0.5,   0.0,  0.0,  1.0,   1.0, 0.0, 0.0, 1.0,   1.0, 1.0,   
1.0, 0.0, 0.0,
+    0.5, -0.5,  0.5,   0.0,  0.0,  1.0,   1.0, 0.0, 0.0, 1.0,   1.0, 0.0,   
1.0, 0.0, 0.0,
+
+   /* Bottom */
+   -0.5, -0.5, -0.5,   0.0,  0.0, -1.0,   0.0, 0.0, 1.0, 1.0,   1.0, 0.0,  
-1.0, 0.0, 0.0,
+   -0.5,  0.5, -0.5,   0.0,  0.0, -1.0,   0.0, 0.0, 1.0, 1.0,   1.0, 1.0,  
-1.0, 0.0, 0.0,
+    0.5,  0.5, -0.5,   0.0,  0.0, -1.0,   0.0, 0.0, 1.0, 1.0,   0.0, 1.0,  
-1.0, 0.0, 0.0,
+    0.5, -0.5, -0.5,   0.0,  0.0, -1.0,   0.0, 0.0, 1.0, 1.0,   0.0, 0.0,  
-1.0, 0.0, 0.0,
+};
+
+const unsigned short indices_of_cube[] =
+{
+   0,   1,  2,  6,  7,  4,
+   4,   5,  6, 10, 11,  8,
+   8,   9, 10, 14, 15, 12,
+   12, 13, 14,  2,  3,  0,
+   19, 16, 17, 17, 18, 19,
+   23, 20, 21, 21, 22, 23
+};
+
+void
+evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame)
+{
+   SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_cube, 24, 
indices_of_cube, 36)
+}
diff --git a/src/lib/evas/common3d/primitives/tabulated_primitives/square.c 
b/src/lib/evas/common3d/primitives/tabulated_primitives/square.c
new file mode 100644
index 0000000..6f5c0c6
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/tabulated_primitives/square.c
@@ -0,0 +1,18 @@
+#include "../primitive_common.h"
+
+const float vertices_of_square[] =
+{
+   /* positions       normals           vertex_color          tex_coords  
tangents    */
+   -0.5,  0.5, 0.0,   0.0, 0.0, -1.0,   1.0, 0.0, 0.0, 1.0,   0.0, 1.0,   1.0, 
0.0, 0.0,
+    0.5,  0.5, 0.0,   0.0, 0.0, -1.0,   1.0, 0.0, 0.0, 1.0,   1.0, 1.0,   1.0, 
0.0, 0.0,
+   -0.5, -0.5, 0.0,   0.0, 0.0, -1.0,   1.0, 0.0, 0.0, 1.0,   0.0, 0.0,   1.0, 
0.0, 0.0,
+    0.5, -0.5, 0.0,   0.0, 0.0, -1.0,   1.0, 0.0, 0.0, 1.0,   1.0, 0.0,   1.0, 
0.0, 0.0,
+};
+
+const unsigned short indices_of_square[] = {0, 1, 2, 2, 1, 3};
+
+void
+evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame)
+{
+   SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_square, 4, 
indices_of_square, 6)
+}
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 7d9303c..e7c8d02 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -100,6 +100,7 @@ typedef struct _Evas_3D_Camera           
Evas_3D_Camera_Data;
 typedef struct _Evas_3D_Light            Evas_3D_Light_Data;
 typedef struct _Evas_3D_Material         Evas_3D_Material_Data;
 typedef struct _Evas_3D_Texture          Evas_3D_Texture_Data;
+typedef struct _Evas_3D_Primitive        Evas_3D_Primitive_Data;
 
 /* Structs for mesh eet saver/loader */
 typedef struct _Evas_3D_Vec2_Eet         Evas_3D_Vec2_Eet;
@@ -415,6 +416,17 @@ struct _Evas_3D_Material
    Eina_Hash        *meshes;
 };
 
+struct _Evas_3D_Primitive
+{
+   Evas_3D_Mesh_Primitive  form;
+   Evas_3D_Primitive_Mode  mode;
+   Evas_Real               ratio;
+   int                     precision;
+   Evas_3D_Surface_Func   *surface;
+
+   Evas_Vec2 tex_scale;
+};
+
 struct _Evas_3D_Scene_Public_Data
 {
    Evas_Color       bg_color;
@@ -1746,6 +1758,17 @@ void evas_model_save_file_eet(Evas_3D_Mesh *mesh, const 
char *file, Evas_3D_Mesh
 void evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *file, 
Evas_3D_Mesh_Frame *f);
 void evas_model_save_file_ply(Evas_3D_Mesh *mesh, const char *file, 
Evas_3D_Mesh_Frame *f);
 
+/* Primitives functions */
+void evas_common_set_model_from_primitive(Evas_3D_Mesh *model, int frame, 
Evas_3D_Primitive_Data *primitive);
+void evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame);
+void evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame);
+void evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh, int frame, 
Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
+void evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh, int frame, 
Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
+void evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh, int frame, 
Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
+void evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh, int frame, 
Evas_Real ratio, int precision, Evas_Vec2 tex_scale);
+void evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh, int frame, 
Evas_3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
+void evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh, int frame, int 
precision, Evas_Vec2 tex_scale);
+
 extern int _evas_alloc_error;
 extern int _evas_event_counter;
 

-- 


Reply via email to