summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBogdan Devichev <b.devichev@samsung.com>2015-05-26 18:49:15 +0200
committerCedric BAIL <cedric@osg.samsung.com>2015-05-27 00:31:07 +0200
commit6dac83e643934573a734491d97b549a6b235c0f5 (patch)
treea5272df551b3c77107e79910cb0f9bde2f8ca6cc
parentabc1eabecb6da1bf77b530132814a2427bfb44fb (diff)
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 <cedric@osg.samsung.com>
-rw-r--r--src/Makefile_Evas.am14
-rw-r--r--src/lib/evas/Evas_Eo.h61
-rw-r--r--src/lib/evas/canvas/evas_3d_mesh.c13
-rw-r--r--src/lib/evas/canvas/evas_3d_mesh.eo11
-rw-r--r--src/lib/evas/canvas/evas_3d_primitive.c162
-rw-r--r--src/lib/evas/canvas/evas_3d_primitive.eo179
-rw-r--r--src/lib/evas/common3d/primitives/primitive_common.c209
-rw-r--r--src/lib/evas/common3d/primitives/primitive_common.h58
-rw-r--r--src/lib/evas/common3d/primitives/solids_of_revolution/cone.c140
-rw-r--r--src/lib/evas/common3d/primitives/solids_of_revolution/cylinder.c136
-rw-r--r--src/lib/evas/common3d/primitives/solids_of_revolution/sphere.c189
-rw-r--r--src/lib/evas/common3d/primitives/solids_of_revolution/torus.c67
-rw-r--r--src/lib/evas/common3d/primitives/surfaces/surface.c91
-rw-r--r--src/lib/evas/common3d/primitives/surfaces/terrain.c86
-rw-r--r--src/lib/evas/common3d/primitives/tabulated_primitives/cube.c57
-rw-r--r--src/lib/evas/common3d/primitives/tabulated_primitives/square.c18
-rw-r--r--src/lib/evas/include/evas_private.h23
17 files changed, 1511 insertions, 3 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 72f8365348..3a2f4af055 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -29,6 +29,7 @@ evas_eolian_files = \
29 lib/evas/canvas/evas_3d_material.eo\ 29 lib/evas/canvas/evas_3d_material.eo\
30 lib/evas/canvas/evas_3d_light.eo\ 30 lib/evas/canvas/evas_3d_light.eo\
31 lib/evas/canvas/evas_3d_mesh.eo\ 31 lib/evas/canvas/evas_3d_mesh.eo\
32 lib/evas/canvas/evas_3d_primitive.eo\
32 lib/evas/canvas/evas_3d_node.eo\ 33 lib/evas/canvas/evas_3d_node.eo\
33 lib/evas/canvas/evas_3d_scene.eo\ 34 lib/evas/canvas/evas_3d_scene.eo\
34 lib/evas/canvas/evas_3d_object.eo \ 35 lib/evas/canvas/evas_3d_object.eo \
@@ -202,6 +203,7 @@ lib/evas/canvas/evas_3d_light.c \
202lib/evas/canvas/evas_3d_mesh.c \ 203lib/evas/canvas/evas_3d_mesh.c \
203lib/evas/canvas/evas_3d_texture.c \ 204lib/evas/canvas/evas_3d_texture.c \
204lib/evas/canvas/evas_3d_material.c \ 205lib/evas/canvas/evas_3d_material.c \
206lib/evas/canvas/evas_3d_primitive.c \
205lib/evas/canvas/evas_3d_node_callback.h 207lib/evas/canvas/evas_3d_node_callback.h
206 208
207# Model savers/loaders (will be replaced to modules in next commits) 209# 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 \
215modules/evas/model_savers/ply/evas_model_save_ply.c \ 217modules/evas/model_savers/ply/evas_model_save_ply.c \
216lib/evas/canvas/evas_3d_eet.c 218lib/evas/canvas/evas_3d_eet.c
217 219
220# 3d primitives
221lib_evas_libevas_la_SOURCES += \
222lib/evas/common3d/primitives/tabulated_primitives/square.c \
223lib/evas/common3d/primitives/tabulated_primitives/cube.c \
224lib/evas/common3d/primitives/solids_of_revolution/sphere.c \
225lib/evas/common3d/primitives/solids_of_revolution/torus.c \
226lib/evas/common3d/primitives/solids_of_revolution/cylinder.c \
227lib/evas/common3d/primitives/solids_of_revolution/cone.c \
228lib/evas/common3d/primitives/surfaces/surface.c \
229lib/evas/common3d/primitives/surfaces/terrain.c \
230lib/evas/common3d/primitives/primitive_common.c
231
218# Evas_VG 232# Evas_VG
219lib_evas_libevas_la_SOURCES += \ 233lib_evas_libevas_la_SOURCES += \
220lib/evas/canvas/evas_object_vg.c \ 234lib/evas/canvas/evas_object_vg.c \
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index c81ce469d2..e401a51578 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;
304 */ 304 */
305 305
306/** 306/**
307 * @defgroup Evas_3D_Primitive Primitive Object
308 * @ingroup Evas_3D
309 *
310 * A primitive object is an object with necessary data for creating meshes with ptimitive shapes.
311 * Data from a primitive can be set to Evas_3D_Mesh by using evas_3d_mesh_from_primitive_set()
312 * function.
313 */
314
315/**
307 * @defgroup Evas_3D_Texture Texture Object 316 * @defgroup Evas_3D_Texture Texture Object
308 * @ingroup Evas_3D 317 * @ingroup Evas_3D
309 * 318 *
@@ -435,6 +444,33 @@ typedef Eo Evas_3D_Material;
435#define _EVAS_3D_MATERIAL_EO_CLASS_TYPE 444#define _EVAS_3D_MATERIAL_EO_CLASS_TYPE
436 445
437/** 446/**
447 * @typedef Evas_3D_Primitive
448 *
449 * Primitive object handle
450 *
451 * @since 1.15
452 * @ingroup Evas_3D_Primitive
453 */
454typedef Eo Evas_3D_Primitive;
455
456#define _EVAS_3D_PRIMITIVE_EO_CLASS_TYPE
457
458/**
459 * @typedef Evas_3D_Surface_Func
460 *
461 * User-defined parametric surface function.
462 * Used for easy creation of custom surfaces as a primitive.
463 *
464 * @since 1.15
465 * @ingroup Evas_3D_Primitive
466 */
467typedef void (Evas_3D_Surface_Func)(Evas_Real *out_x,
468 Evas_Real *out_y,
469 Evas_Real *out_z,
470 Evas_Real a,
471 Evas_Real b);
472
473/**
438 * Type of 3D Object 474 * Type of 3D Object
439 * 475 *
440 * @since 1.10 476 * @since 1.10
@@ -451,6 +487,7 @@ typedef enum _Evas_3D_Object_Type
451 EVAS_3D_OBJECT_TYPE_MESH, 487 EVAS_3D_OBJECT_TYPE_MESH,
452 EVAS_3D_OBJECT_TYPE_TEXTURE, 488 EVAS_3D_OBJECT_TYPE_TEXTURE,
453 EVAS_3D_OBJECT_TYPE_MATERIAL, 489 EVAS_3D_OBJECT_TYPE_MATERIAL,
490 EVAS_3D_OBJECT_TYPE_PRIMITIVE,
454} Evas_3D_Object_Type; 491} Evas_3D_Object_Type;
455 492
456/** 493/**
@@ -716,7 +753,7 @@ typedef enum _Evas_3D_Wrap_Mode
716} Evas_3D_Wrap_Mode; 753} Evas_3D_Wrap_Mode;
717 754
718/** 755/**
719 * Mesh Primitive 756 * Mesh primitive
720 * 757 *
721 * @since 1.12 758 * @since 1.12
722 * @ingroup Evas_3D_Types 759 * @ingroup Evas_3D_Types
@@ -740,10 +777,28 @@ typedef enum _Evas_3D_Mesh_Primitive
740 /**< Custom surface (can use pointer to users function, precision and texture scale) */ 777 /**< Custom surface (can use pointer to users function, precision and texture scale) */
741 EVAS_3D_MESH_PRIMITIVE_SURFACE, 778 EVAS_3D_MESH_PRIMITIVE_SURFACE,
742 /**< Terrain as surface with pointer to Perlin's noise function */ 779 /**< Terrain as surface with pointer to Perlin's noise function */
743 EVAS_3D_MESH_PRIMITIVE_TERRAIN 780 EVAS_3D_MESH_PRIMITIVE_TERRAIN,
781 /**< Count of supported primitives */
782 EVAS_3D_MESH_PRIMITIVE_COUNT
744} Evas_3D_Mesh_Primitive; 783} Evas_3D_Mesh_Primitive;
745 784
746/** 785/**
786 * Mode of mesh primitive
787 *
788 * @since 1.15
789 * @ingroup Evas_3D_Types
790 */
791typedef enum _Evas_3D_Primitive_Mode
792{
793 /**< Default mode of primitive */
794 EVAS_3D_PRIMITIVE_MODE_DEFAULT = 0,
795 /**< Primitive without base (supported for cylinder and cone) */
796 EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE,
797 /**< Ptimitive with alternative UV (supported for sphere)*/
798 EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV
799} Evas_3D_Primitive_Mode;
800
801/**
747 * Texture filters 802 * Texture filters
748 * 803 *
749 * @since 1.10 804 * @since 1.10
@@ -818,6 +873,8 @@ typedef enum _Evas_3D_Material_Attrib
818 873
819#include "canvas/evas_3d_mesh.eo.h" 874#include "canvas/evas_3d_mesh.eo.h"
820 875
876#include "canvas/evas_3d_primitive.eo.h"
877
821#include "canvas/evas_3d_node.eo.h" 878#include "canvas/evas_3d_node.eo.h"
822 879
823#include "canvas/evas_3d_scene.eo.h" 880#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 1b8cc14eb9..f15b42fc4f 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,
893 return EINA_TRUE; 893 return EINA_TRUE;
894} 894}
895 895
896EOLIAN static void
897_evas_3d_mesh_from_primitive_set(Eo *obj,
898 Evas_3D_Mesh_Data *pd EINA_UNUSED,
899 int frame,
900 Eo *primitive)
901{
902 if ((primitive == NULL) || (obj == NULL)) return;
903
904 Evas_3D_Primitive_Data *ppd = eo_data_scope_get(primitive, EVAS_3D_PRIMITIVE_CLASS);
905
906 evas_common_set_model_from_primitive(obj, frame, ppd);
907}
908
896static inline void 909static inline void
897_mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame, 910_mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame,
898 Eina_List **l, Eina_List **r) 911 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 5789cc00cb..db0f895df4 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)
291 @out dfactor: Evas_3D_Blend_Func; /*@ Pointer to receive destination blendin factors key.*/ 291 @out dfactor: Evas_3D_Blend_Func; /*@ Pointer to receive destination blendin factors key.*/
292 } 292 }
293 } 293 }
294 294 from_primitive_set {
295 /*@
296 Set the data of given mesh frame from the given primitive
297 @ingroup Evas_3D_Mesh
298 */
299 params {
300 @in frame: int; /*@ Specifies data of which frame of given mesh will be set.*/
301 @in primitive: Evas_3D_Primitive *; /*@ Specifies which data will be set.*/
302 }
303 }
295 @property shade_mode { 304 @property shade_mode {
296 set { 305 set {
297 /*@ 306 /*@
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 0000000000..34ecab6aef
--- /dev/null
+++ b/src/lib/evas/canvas/evas_3d_primitive.c
@@ -0,0 +1,162 @@
1#include "evas_common_private.h"
2#include "evas_private.h"
3
4#define MY_CLASS EVAS_3D_PRIMITIVE_CLASS
5
6static inline void
7_primitive_init(Evas_3D_Primitive_Data *pd)
8{
9 pd->form = EVAS_3D_MESH_PRIMITIVE_NONE;
10 pd->ratio = 3.0;
11 pd->precision = 10;
12 pd->surface = NULL;
13 pd->tex_scale.x = 1.0;
14 pd->tex_scale.y = 1.0;
15}
16
17static inline void
18_primitive_fini(Evas_3D_Primitive_Data *pd)
19{
20 if (pd->surface)
21 free(pd->surface);
22}
23
24EAPI Evas_3D_Primitive *
25evas_3d_primitive_add(Evas *e)
26{
27 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
28 return NULL;
29 MAGIC_CHECK_END();
30 Evas_Object *eo_obj = eo_add(MY_CLASS, e);
31 return eo_obj;
32}
33
34EOLIAN static Eo *
35_evas_3d_primitive_eo_base_constructor(Eo *obj, Evas_3D_Primitive_Data *pd)
36{
37 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
38 eo_do(obj, evas_3d_object_type_set(EVAS_3D_OBJECT_TYPE_PRIMITIVE));
39 _primitive_init(pd);
40
41 return obj;
42}
43
44EOLIAN static void
45_evas_3d_primitive_eo_base_destructor(Eo *obj, Evas_3D_Primitive_Data *pd)
46{
47 _primitive_fini(pd);
48 eo_do_super(obj, MY_CLASS, eo_destructor());
49}
50
51EOLIAN static void
52_evas_3d_primitive_form_set(Eo *obj EINA_UNUSED,
53 Evas_3D_Primitive_Data *pd,
54 Evas_3D_Mesh_Primitive form)
55{
56 if ((form < EVAS_3D_MESH_PRIMITIVE_NONE) ||
57 (form >= EVAS_3D_MESH_PRIMITIVE_COUNT))
58 {
59 ERR("Wrong form of primitive.");
60 return;
61 }
62
63 if (pd->form != form)
64 pd->form = form;
65}
66
67EOLIAN static Evas_3D_Mesh_Primitive
68_evas_3d_primitive_form_get(Eo *obj EINA_UNUSED,
69 Evas_3D_Primitive_Data *pd)
70{
71 return pd->form;
72}
73
74EOLIAN static void
75_evas_3d_primitive_mode_set(Eo *obj EINA_UNUSED,
76 Evas_3D_Primitive_Data *pd,
77 Evas_3D_Primitive_Mode mode)
78{
79 if (pd->mode != mode)
80 pd->mode = mode;
81}
82
83EOLIAN static Evas_3D_Primitive_Mode
84_evas_3d_primitive_mode_get(Eo *obj EINA_UNUSED,
85 Evas_3D_Primitive_Data *pd)
86{
87 return pd->mode;
88}
89
90EOLIAN static void
91_evas_3d_primitive_ratio_set(Eo *obj EINA_UNUSED,
92 Evas_3D_Primitive_Data *pd,
93 Evas_Real ratio)
94{
95 pd->ratio = ratio;
96}
97
98EOLIAN static Evas_Real
99_evas_3d_primitive_ratio_get(Eo *obj EINA_UNUSED,
100 Evas_3D_Primitive_Data *pd)
101{
102 return pd->ratio;
103}
104
105EOLIAN static void
106_evas_3d_primitive_precision_set(Eo *obj EINA_UNUSED,
107 Evas_3D_Primitive_Data *pd,
108 int precision)
109{
110 if ((precision < 3))
111 {
112 ERR("Precision of Evas_3D_Primitive cannot be less than 3.");
113 return;
114 }
115
116 if ((precision >= 100))
117 {
118 ERR("%s\n%s",
119 "Be careful with precision of Evas_3D_Primitive more than 100.",
120 "It can give unacceptable result.");
121 }
122
123 if (pd->precision != precision)
124 pd->precision = precision;
125}
126
127EOLIAN static int
128_evas_3d_primitive_precision_get(Eo *obj EINA_UNUSED,
129 Evas_3D_Primitive_Data *pd)
130{
131 return pd->precision;
132}
133
134EOLIAN static void
135_evas_3d_primitive_surface_set(Eo *obj EINA_UNUSED,
136 Evas_3D_Primitive_Data *pd,
137 Evas_3D_Surface_Func surface_func)
138{
139 pd->surface = surface_func;
140}
141
142EOLIAN static void
143_evas_3d_primitive_tex_scale_set(Eo *obj EINA_UNUSED,
144 Evas_3D_Primitive_Data *pd,
145 Evas_Real x,
146 Evas_Real y)
147{
148 if (x) pd->tex_scale.x = x;
149 if (y) pd->tex_scale.y = y;
150}
151
152EOLIAN static void
153_evas_3d_primitive_tex_scale_get(Eo *obj EINA_UNUSED,
154 Evas_3D_Primitive_Data *pd,
155 Evas_Real *x,
156 Evas_Real *y)
157{
158 if (x) *x = pd->tex_scale.x;
159 if (y) *y = pd->tex_scale.y;
160}
161
162#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 0000000000..e1336c66c0
--- /dev/null
+++ b/src/lib/evas/canvas/evas_3d_primitive.eo
@@ -0,0 +1,179 @@
1class Evas_3D_Primitive (Evas_3D_Object, Evas.Common_Interface)
2{
3 legacy_prefix: null;
4 data: Evas_3D_Primitive_Data;
5
6 methods {
7 @property form {
8 set {
9 /*
10 *Set the form of the given primitive.
11 *
12 *Form defines which function will be chosen to set data to mesh
13 *on call of evas_3d_mesh_primitive_set.
14 *
15 *Now avaliable next forms of primitives:
16 *-tabulated primitives: SQUARE and CUBE;
17 *-solids of revolution: CYLINDER, CONE, SPHERE and TORUS;
18 *-surfaces: SURFACE and TERRAIN.
19 *
20 *Default form is EVAS_3D_MESH_PRIMITIVE_NONE
21 *
22 *@ingroup Evas_3D_Primitive
23 */
24 }
25 get {
26 /*
27 *Get the form of the given primitive.
28 *@see evas_3d_primitive_form_set()
29 *@return The form of primitive.
30 *@ingroup Evas_3D_Primitive
31 */
32 }
33 values {
34 form: Evas_3D_Mesh_Primitive; /*@ Form of primitive.*/
35 }
36 }
37 @property mode {
38 set {
39 /*
40 *Set the mode of the given primitive.
41 *
42 *Mode defines which function will be chosen to set data to mesh
43 *on call of evas_3d_mesh_primitive_set. It helps to choose
44 *alternative algorithm for primitive with given form
45 *(like cone without base or sphere textured in alternative way).
46 *
47 *Now avaliable next mods of primitives:
48 *-witout base (bases): supported for cylinder and cone;
49 *-with alternative UV: supported by sphere;
50 *
51 *Default form is EVAS_3D_PRIMITIVE_MODE_DEFAULT
52 *
53 *@ingroup Evas_3D_Primitive
54 */
55 }
56 get {
57 /*
58 *Get the mode of the given primitive.
59 *@see evas_3d_primitive_mode_set()
60 *@return The mode of primitive.
61 *@ingroup Evas_3D_Primitive
62 */
63 }
64 values {
65 mode: Evas_3D_Primitive_Mode; /*@ Mode of primitive.*/
66 }
67 }
68 @property ratio {
69 set {
70 /*
71 *Set the ratio of the given primitive.
72 *
73 *Now ratio uses only in torus as the ratio of the
74 *major radius and minor radius. For this usage
75 *Avaliable values is from 1.0 to infinity.
76 *If ratio for torus has a bad value,
77 *will be used 3.0 as ratio. Like ratio of usual doughnut.
78 *
79 *Default ratio is 3.0
80 *
81 *@ingroup Evas_3D_Primitive
82 */
83 }
84 get {
85 /*
86 *Get the ratio of the given primitive.
87 *@see evas_3d_primitive_ratio_set()
88 *@return The ratio of primitive.
89 *@ingroup Evas_3D_Primitive
90 */
91 }
92 values {
93 ratio: Evas_Real; /*@ Ratio of primitive.*/
94 }
95 }
96 @property precision {
97 set {
98 /*
99 *Set the precision of the given primitive.
100 *
101 *Precision uses in all non tabulated primitives and defines
102 *precision of created primitives.
103 *Avaliable values is from 3 to infinity.
104 *But if value will be more than 100, should be a warning
105 *about possibility of incorrect or slow work.
106 *
107 *Default ratio is 10
108 *
109 *@ingroup Evas_3D_Primitive
110 */
111 }
112 get {
113 /*
114 *Get the precision of the given primitive.
115 *@see evas_3d_primitive_precision_set()
116 *@return The precision of primitive.
117 *@ingroup Evas_3D_Primitive
118 */
119 }
120 values {
121 precision: int; /*@ Precision of primitive.*/
122 }
123 }
124 @property surface {
125 set {
126 /*
127 *Set the surface of the given primitive.
128 *
129 *Surface uses only in surface primitive and defines
130 *equation of filling mesh data on call of
131 *evas_3d_mesh_primitive_set.
132 *
133 *It gives possibility to create customers primitives like
134 *shell, heart, hyperbolic paraboloid etc. See _shell_func in
135 *examples/evas/evas-3d-visual-test.c or _perlin_terrain in
136 *modules/evas/primitives/surfaces/terrain.c as an example of usage.
137 *
138 *Default surface is NULL
139 *
140 *@ingroup Evas_3D_Primitive
141 */
142 }
143 values {
144 surface: Evas_3D_Surface_Func *; /*@ Pointer to customers surface function.*/
145 }
146 }
147 @property tex_scale {
148 set {
149 /*
150 *Set the texture scale of the given primitive.
151 *
152 *Texture scale uses in all non tabulated primitives
153 *and defines scale of texture coords or primitives.
154 *
155 *It uses to create periodical textured meshes.
156 *
157 *Default tex_scale is {1.0, 1.0}
158 *
159 *@ingroup Evas_3D_Primitive
160 */
161 }
162 get {
163 /*
164 *Get the texture scale of the given primitive.
165 *@see evas_3d_primitive_tex_scale_set()
166 *@ingroup Evas_3D_Primitive
167 */
168 }
169 values {
170 tex_scale_x: Evas_Real;
171 tex_scale_y: Evas_Real;
172 }
173 }
174 }
175 implements {
176 Eo.Base.constructor;
177 Eo.Base.destructor;
178 }
179}
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 0000000000..066ef3b35c
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/primitive_common.c
@@ -0,0 +1,209 @@
1#include "primitive_common.h"
2
3void _set_vertex_data_from_array(Evas_3D_Mesh *mesh,
4 int frame,
5 const float *data,
6 Evas_3D_Vertex_Attrib attr,
7 int start,
8 int attr_count,
9 int line,
10 int vcount)
11{
12 float *address, *out;
13 int stride, i, j;
14 eo_do(mesh,
15 evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
16 address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
17 stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
18 if (stride == 0) stride = sizeof(float) * attr_count;
19 for (i = 0; i < vcount; i++)
20 {
21 out = (float *)((char *)address + stride * i);
22 for (j = 0; j < attr_count; j++)
23 out[j] = data[start + (line * i) + j];
24 }
25 eo_do(mesh,
26 evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
27}
28
29void
30_set_vec3_vertex_data(Evas_3D_Mesh *mesh,
31 int frame,
32 int vcount,
33 Evas_Vec3 *data,
34 Evas_3D_Vertex_Attrib attr)
35{
36 float *address, *out;
37 int stride, i;
38 eo_do(mesh,
39 evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
40 address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
41 stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
42 if (stride == 0) stride = sizeof(float) * 3;
43 for (i = 0; i < vcount; i++)
44 {
45 out = (float *)((char *)address + stride * i);
46 out[0] = data[i].x;
47 out[1] = data[i].y;
48 out[2] = data[i].z;
49 }
50 free(data);
51 eo_do(mesh,
52 evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
53}
54
55void
56_set_vec2_vertex_data(Evas_3D_Mesh *mesh,
57 int frame,
58 int vcount,
59 Evas_Vec2 *data,
60 Evas_3D_Vertex_Attrib attr)
61{
62 float *address, *out;
63 int stride, i;
64 eo_do(mesh,
65 evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
66 address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
67 stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
68 if (stride == 0) stride = sizeof(float) * 2;
69 for (i = 0; i < vcount; i++)
70 {
71 out = (float *)((char *)address + stride * i);
72 out[0] = data[i].x;
73 out[1] = data[i].y;
74 }
75 free(data);
76 eo_do(mesh,
77 evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
78}
79
80void
81_generate_indices(unsigned short *indices, int a, int b)
82{
83 int i, j, a1 = a + 1;
84 unsigned short *index = &indices[0];
85
86 for (i = 0; i < b; i++)
87 {
88 for (j = 0; j < a; j++)
89 {
90 *index++ = j + a1 * i;
91 *index++ = j + a1 * (i + 1);
92 *index++ = j + 1 + a1 * (i + 1);
93
94 *index++ = j + a1 * i;
95 *index++ = j + 1 + a1 * i;
96 *index++ = j + a1 * (i + 1) + 1;
97 }
98 }
99}
100
101void
102_primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src)
103{
104 dst->x = src->x;
105 dst->y = src->y;
106 dst->z = src->z;
107}
108
109void
110_primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
111{
112 out->x = a->x - b->x;
113 out->y = a->y - b->y;
114 out->z = a->z - b->z;
115}
116
117void
118_primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
119{
120 Evas_Vec3 tmp;
121
122 tmp.x = a->y * b->z - a->z * b->y;
123 tmp.y = a->z * b->x - a->x * b->z;
124 tmp.z = a->x * b->y - a->y * b->x;
125
126 _primitives_vec3_copy(out, &tmp);
127}
128
129void
130_primitives_vec3_normalize(Evas_Vec3 *out)
131{
132 Evas_Real size = out->x * out->x + out->y *out->y + out->z * out->z;
133 size = sqrt(size);
134 out->x /= size;
135 out->y /= size;
136 out->z /= size;
137}
138
139void
140evas_common_set_model_from_primitive(Evas_3D_Mesh *model,
141 int frame,
142 Evas_3D_Primitive_Data *primitive)
143{
144 Evas_Real ratio = primitive->ratio;
145 int precision = primitive->precision;
146 Evas_3D_Surface_Func *surface = primitive->surface;
147 Evas_Vec2 tex_scale = primitive->tex_scale;
148 Evas_3D_Primitive_Mode mode = primitive->mode;
149
150 switch (primitive->form)
151 {
152 case EVAS_3D_MESH_PRIMITIVE_NONE:
153 case EVAS_3D_MESH_PRIMITIVE_COUNT:
154 {
155 ERR("Primitive with this type cannot be set to mesh.");
156 break;
157 }
158 case EVAS_3D_MESH_PRIMITIVE_SQUARE:
159 {
160 evas_model_set_from_square_primitive(model, frame);
161 break;
162 }
163 case EVAS_3D_MESH_PRIMITIVE_CUBE:
164 {
165 evas_model_set_from_cube_primitive(model, frame);
166 break;
167 }
168 case EVAS_3D_MESH_PRIMITIVE_CYLINDER:
169 {
170 evas_model_set_from_cylinder_primitive(model, frame, mode,
171 precision, tex_scale);
172 break;
173 }
174 case EVAS_3D_MESH_PRIMITIVE_CONE:
175 {
176 evas_model_set_from_cone_primitive(model, frame, mode,
177 precision, tex_scale);
178 break;
179 }
180 case EVAS_3D_MESH_PRIMITIVE_SPHERE:
181 {
182 evas_model_set_from_sphere_primitive(model, frame, mode,
183 precision, tex_scale);
184 break;
185 }
186 case EVAS_3D_MESH_PRIMITIVE_TORUS:
187 {
188 evas_model_set_from_torus_primitive(model, frame,
189 ratio, precision, tex_scale);
190 break;
191 }
192 case EVAS_3D_MESH_PRIMITIVE_SURFACE:
193 {
194 evas_model_set_from_surface_primitive(model, frame,
195 surface, precision, tex_scale);
196 break;
197 }
198 case EVAS_3D_MESH_PRIMITIVE_TERRAIN:
199 {
200 evas_model_set_from_terrain_primitive(model, frame,
201 precision, tex_scale);
202 break;
203 }
204 default:
205 {
206 ERR("Unknown type of primitive");
207 }
208 }
209}
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 0000000000..c2b47f375b
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/primitive_common.h
@@ -0,0 +1,58 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif //HAVE_CONFIG_H
4
5#ifndef PRIMITIVE_COMMON
6#define PRIMITIVE_COMMON
7#include "evas_options.h"
8
9#include "evas_common_private.h"
10#include "evas_private.h"
11
12#define ALLOCATE_VERTEX_DATA \
13 Evas_Vec3 *vertices = malloc(sizeof(Evas_Vec3) * vcount); \
14 Evas_Vec3 *normals = malloc(sizeof(Evas_Vec3) * vcount); \
15 Evas_Vec2 *tex_coord = malloc(sizeof(Evas_Vec2) * vcount); \
16 Evas_Vec3 *tangents = malloc(sizeof(Evas_Vec3) * vcount); \
17 unsigned short *indices = malloc(sizeof(short) * icount);
18
19#define SET_VERTEX_DATA(frame) \
20 eo_do(mesh, \
21 evas_3d_mesh_vertex_count_set(vcount), \
22 evas_3d_mesh_frame_add(frame), \
23 evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, \
24 icount, &indices[0])); \
25 _set_vec3_vertex_data(mesh, frame, vcount, vertices, EVAS_3D_VERTEX_POSITION); \
26 _set_vec3_vertex_data(mesh, frame, vcount, normals, EVAS_3D_VERTEX_NORMAL); \
27 _set_vec2_vertex_data(mesh, frame, vcount, tex_coord, EVAS_3D_VERTEX_TEXCOORD); \
28 _set_vec3_vertex_data(mesh, frame, vcount, tangents, EVAS_3D_VERTEX_TANGENT); \
29 free(indices);
30
31#define SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, varray, vcount, indices, icount) \
32 eo_do(mesh, \
33 evas_3d_mesh_vertex_count_set(vcount), \
34 evas_3d_mesh_frame_add(frame), \
35 evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, \
36 icount, &indices[0])); \
37 _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_POSITION, \
38 0, 3, 15, vcount); \
39 _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_NORMAL, \
40 3, 3, 15, vcount); \
41 _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_COLOR, \
42 6, 4, 15, vcount); \
43 _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TEXCOORD, \
44 10, 2, 15, vcount); \
45 _set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TANGENT, \
46 12, 3, 15, vcount);
47
48void _generate_indices(unsigned short *indices, int count, int width);
49void _set_vec3_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, Evas_Vec3 *data, Evas_3D_Vertex_Attrib attr);
50void _set_vec2_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, Evas_Vec2 *data, Evas_3D_Vertex_Attrib attr);
51void _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);
52
53void _primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src);
54void _primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b);
55void _primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b);
56void _primitives_vec3_normalize(Evas_Vec3 *out);
57
58#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 0000000000..2b62f287c0
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/cone.c
@@ -0,0 +1,140 @@
1#include "../primitive_common.h"
2
3void
4_set_default_cone(Evas_3D_Mesh *mesh,
5 int frame,
6 int p,
7 Evas_Vec2 tex_scale)
8{
9 int vcount, icount, vccount, i, j, num;
10 double dfi, fi, sinfi, cosfi, nplane, nz;
11
12 icount = p * 18;
13 vccount = p + 1;
14 vcount = 4 * vccount;
15
16 dfi = 2.0 * M_PI / p;
17 nz = sqrt(1.0 / 3.0);
18 nplane = sqrt(2.0 / 3.0);
19
20 ALLOCATE_VERTEX_DATA
21
22 for (i = 0; i < vccount; i++)
23 {
24 fi = i * dfi;
25 sinfi = sin(fi);
26 cosfi = cos(fi);
27
28 vertices[i].x = 0.0;
29 vertices[i].y = 0.0;
30 vertices[i].z = -0.5;
31 vertices[i + vccount].x = sinfi / 2.0;
32 vertices[i + vccount].y = cosfi / 2.0;
33 vertices[i + vccount].z = -0.5;
34 vertices[i + 2 * vccount] = vertices[i + vccount];
35 vertices[i + 3 * vccount].x = 0.0;
36 vertices[i + 3 * vccount].y = 0.0;
37 vertices[i + 3 * vccount].z = 0.5;
38
39 normals[i].x = normals[i].y = 0.0;
40 normals[i].z = -1.0;
41 normals[i + vccount] = normals[i];
42 normals[i + 2 * vccount].x = sinfi * nplane;
43 normals[i + 2 * vccount].y = cosfi * nplane;
44 normals[i + 2 * vccount].z = nz;
45 normals[i + 3 * vccount] = normals[i + 2 * vccount];
46
47 for (j = 0; j < 4; j++)
48 {
49 num = i + j * vccount;
50
51 tangents[num].x = cosfi;
52 tangents[num].y = -sinfi;
53 tangents[num].z = 0.0;
54
55 tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
56 tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 2.0;
57 }
58 }
59
60 _generate_indices(indices, p, 3);
61
62 SET_VERTEX_DATA(frame)
63}
64
65void
66_set_cone_without_base(Evas_3D_Mesh *mesh,
67 int frame,
68 int p,
69 Evas_Vec2 tex_scale)
70{
71 int vcount, icount, vccount, i;
72 double dfi, fi, sinfi, cosfi, nplane, nz;
73
74 icount = p * 6;
75 vccount = p + 1;
76 vcount = 2 * vccount;
77
78 dfi = 2.0 * M_PI / p;
79 nz = sqrt(1.0 / 3.0);
80 nplane = sqrt(2.0 / 3.0);
81
82 ALLOCATE_VERTEX_DATA
83
84 for (i = 0; i < vccount; i++)
85 {
86 fi = i * dfi;
87 sinfi = sin(fi);
88 cosfi = cos(fi);
89 vertices[i].x = sinfi / 2.0;
90 vertices[i].y = cosfi / 2.0;
91 vertices[i].z = -0.5;
92 vertices[i + vccount].x = 0;
93 vertices[i + vccount].y = 0;
94 vertices[i + vccount].z = 0.5;
95
96 normals[i + vccount].x = normals[i].x = sinfi * nplane;
97 normals[i + vccount].y = normals[i].y = cosfi * nplane;
98 normals[i + vccount].z = normals[i].z = nz;
99
100 tangents[i + vccount].x = tangents[i].x = cosfi;
101 tangents[i + vccount].y = tangents[i].y = -sinfi;
102 tangents[i + vccount].z = tangents[i].z = 0;
103
104 tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
105 tex_coord[i].y = 0;
106 tex_coord[i + vccount].x = tex_coord[i].x;
107 tex_coord[i + vccount].y = tex_scale.y;
108 }
109
110 _generate_indices(indices, p, 1);
111
112 SET_VERTEX_DATA(frame)
113}
114
115void
116evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh,
117 int frame,
118 Evas_3D_Primitive_Mode mode,
119 int p,
120 Evas_Vec2 tex_scale)
121{
122 switch (mode)
123 {
124 case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
125 case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
126 {
127 _set_default_cone(mesh, frame, p, tex_scale);
128 break;
129 }
130 case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
131 {
132 _set_cone_without_base(mesh, frame, p, tex_scale);
133 break;
134 }
135 default:
136 {
137 ERR("Unknown mode of primitive");
138 }
139 }
140}
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 0000000000..dabe6f4989
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/cylinder.c
@@ -0,0 +1,136 @@
1#include "../primitive_common.h"
2
3void
4_set_default_cylinder(Evas_3D_Mesh *mesh,
5 int frame,
6 int p,
7 Evas_Vec2 tex_scale)
8{
9 int vcount, icount, vccount, i, j, num;
10 icount = p * 30;
11 vccount = p + 1;
12 vcount = 6 * vccount;
13
14 ALLOCATE_VERTEX_DATA
15
16 double dfi, fi, sinfi, cosfi;
17 dfi = 2 * M_PI / p;
18
19 for (i = 0; i < vccount; i++)
20 {
21 fi = i * dfi;
22 sinfi = sin(fi);
23 cosfi = cos(fi);
24
25 for (j = 0; j < 6; j++)
26 {
27 num = i + j * vccount;
28
29 vertices[num].z = -0.5 + (float)(j / 3);
30 if ((j == 0) || (j == 5))
31 {
32 vertices[num].x = vertices[num].y = 0.0;
33 }
34 else
35 {
36 vertices[num].x = sinfi / 2.0;
37 vertices[num].y = cosfi / 2.0;
38 }
39
40 if ((j == 2) || (j == 3))
41 {
42 normals[num].x = sinfi;
43 normals[num].y = cosfi;
44 normals[num].z = 0.0;
45 }
46 else
47 {
48 normals[num].x = normals[num].y = 0.0;
49 normals[num].z = -1.0 + (float)(j / 2);
50 }
51
52 tangents[num].x = cosfi;
53 tangents[num].y = -sinfi;
54 tangents[num].z = 0.0;
55
56 tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
57 tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 3.0;
58 }
59 }
60
61 _generate_indices(indices, p, 5);
62
63 SET_VERTEX_DATA(frame)
64}
65
66void
67_set_cylinder_without_bases(Evas_3D_Mesh *mesh,
68 int frame,
69 int p,
70 Evas_Vec2 tex_scale)
71{
72 int vcount, icount, vccount, i;
73 icount = p * 6;
74 vccount = p + 1;
75 vcount = 2 * vccount;
76
77 ALLOCATE_VERTEX_DATA
78
79 double dfi, fi, sinfi, cosfi;
80 dfi = 2 * M_PI / p;
81
82 for (i = 0; i < vccount; i++)
83 {
84 fi = i * dfi;
85 sinfi = sin(fi);
86 cosfi = cos(fi);
87 vertices[i + vccount].x = vertices[i].x = sinfi / 2.0;
88 vertices[i + vccount].y = vertices[i].y = cosfi / 2.0;
89 vertices[i].z = -0.5;
90 vertices[i + vccount].z = 0.5;
91
92 normals[i + vccount].x = normals[i].x = sinfi;
93 normals[i + vccount].y = normals[i].y = cosfi;
94 normals[i + vccount].z = normals[i].z = 0;
95
96 tangents[i + vccount].x = tangents[i].x = cosfi;
97 tangents[i + vccount].y = tangents[i].y = -sinfi;
98 tangents[i + vccount].z = tangents[i].z = 0;
99
100 tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
101 tex_coord[i].y = 0;
102 tex_coord[i + vccount].x = i / (float)(vccount - 1) * tex_scale.x;
103 tex_coord[i + vccount].y = tex_scale.y;
104 }
105
106 _generate_indices(indices, p, 1);
107
108 SET_VERTEX_DATA(frame)
109}
110
111void
112evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh,
113 int frame,
114 Evas_3D_Primitive_Mode mode,
115 int p,
116 Evas_Vec2 tex_scale)
117{
118 switch (mode)
119 {
120 case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
121 case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
122 {
123 _set_default_cylinder(mesh, frame, p, tex_scale);
124 break;
125 }
126 case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
127 {
128 _set_cylinder_without_bases(mesh, frame, p, tex_scale);
129 break;
130 }
131 default:
132 {
133 ERR("Unknown mode of primitive");
134 }
135 }
136}
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 0000000000..1a2409b2a5
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/sphere.c
@@ -0,0 +1,189 @@
1#include "../primitive_common.h"
2
3void
4_set_default_sphere(Evas_3D_Mesh *mesh,
5 int frame,
6 int p,
7 Evas_Vec2 tex_scale)
8{
9 int vcount, icount, vccount, i, j;
10 icount = p * p * 6;
11 vccount = p + 1;
12 vcount = vccount * vccount;
13
14 ALLOCATE_VERTEX_DATA
15
16 double dtheta, dfi, sinth, costh, fi, theta, sinfi, cosfi;
17 dtheta = M_PI / p;
18 dfi = 2 * M_PI / p;
19
20 for (j = 0; j < vccount; j++)
21 {
22 theta = j * dtheta;
23 sinth = sin(theta);
24 costh = cos(theta);
25 for (i = 0; i < vccount; i++)
26 {
27 fi = i * dfi;
28 sinfi = sin(fi);
29 cosfi = cos(fi);
30 normals[i + j * vccount].x = sinth * sinfi;
31 normals[i + j * vccount].y = sinth * cosfi;
32 normals[i + j * vccount].z = costh;
33
34 vertices[i + j * vccount].x = normals[i + j * vccount].x / 2;
35 vertices[i + j * vccount].y = normals[i + j * vccount].y / 2;
36 vertices[i + j * vccount].z = normals[i + j * vccount].z / 2;
37
38 tangents[i + j * vccount].x = -sinth * cosfi;
39 tangents[i + j * vccount].y = sinth * sinfi;
40 tangents[i + j * vccount].z = 0;
41
42 _primitives_vec3_normalize(&tangents[i + j * vccount]);
43
44 tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * tex_scale.x;
45 tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
46 }
47 }
48
49 _generate_indices(indices, p, p);
50
51 SET_VERTEX_DATA(frame)
52}
53
54void
55_set_sphere_with_alternative_uv(Evas_3D_Mesh *mesh,
56 int frame,
57 int p,
58 Evas_Vec2 tex_scale)
59{
60 int vcount, icount, vccount, i, j;
61
62 vccount = p + 1;
63 vcount = vccount * vccount;
64 icount = p * p * 6;
65
66 ALLOCATE_VERTEX_DATA
67
68 /* Calculate vertices position of the sphere mesh by using
69 splitting of sphere by latitude and longitude. */
70 for (i = 0; i <= p; i++)
71 {
72 double lati, z, r, point_r;
73
74 point_r = 0.00001;//non-zero little value for correct tangents calculation.
75
76 lati = ((M_PI - 2 * point_r) * (double)i) / (double)p;
77 z = cos(lati + point_r);
78 r = fabs(sin(lati + point_r));
79
80 for (j = 0; j <= p; j++)
81 {
82 double longi;
83 int num = (i * (p + 1)) + j;
84
85 longi = (M_PI * 2.0 * (double)j) / (double)p;
86
87 normals[num].x = r * sin(longi);
88 normals[num].y = r * cos(longi);
89 normals[num].z = z;
90
91 vertices[num].x = normals[num].x / 2;
92 vertices[num].y = normals[num].y / 2;
93 vertices[num].z = normals[num].z / 2;
94
95 if (vertices[num].x > 0.0)
96 {
97 tangents[num].x = -normals[num].z;
98 tangents[num].y = normals[num].y;
99 tangents[num].z = normals[num].x;
100 }
101 else
102 {
103 tangents[num].x = normals[num].z;
104 tangents[num].y = normals[num].y;
105 tangents[num].z = -normals[num].x;
106 }
107
108 tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
109 tex_coord[num].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
110 }
111 }
112
113 _generate_indices(indices, p, p);
114
115 /* Triangulation of sphere mesh in appliance with buffer of indices. */
116 for (i = 0; i < icount; i += 3)
117 {
118 Evas_Vec3 e1, e2;
119 float du1, du2, dv1, dv2, f;
120 Evas_Vec3 tangent;
121 int num0, num1, num2;
122
123 num0 = indices[i + 0];
124 num1 = indices[i + 1];
125 num2 = indices[i + 2];
126
127 e1.x = vertices[num1].x - vertices[num0].x;
128 e1.y = vertices[num1].y - vertices[num0].y;
129 e1.z = vertices[num1].z - vertices[num0].z;
130
131 e2.x = vertices[num2].x - vertices[num0].x;
132 e2.y = vertices[num2].y - vertices[num0].y;
133 e2.z = vertices[num2].z - vertices[num0].z;
134
135 du1 = tex_coord[num1].x - tex_coord[num0].x;
136 dv1 = tex_coord[num1].y - tex_coord[num0].y;
137
138 du2 = tex_coord[num2].x - tex_coord[num0].x;
139 dv2 = tex_coord[num2].y - tex_coord[num0].y;
140
141 f = 1.0 / ((du1 * dv2) - (du2 * dv1));
142
143 tangent.x = f * ((dv2 * e1.x) - (dv1 * e2.x));
144 tangent.y = f * ((dv2 * e1.y) - (dv1 * e2.y));
145 tangent.z = f * ((dv2 * e1.z) - (dv1 * e2.z));
146
147 tangents[num0] = tangent;
148 }
149
150 /* Coupling between vertices by calculation of tangent parametr correct value. */
151 for (i = 0; i <= p; i++)
152 {
153 for (j = 0; j <= p; j++)
154 {
155 if (j == p)
156 {
157 tangents[(i * (p + 1)) + j] = tangents[i * (p + 1)];
158 }
159 }
160 }
161 SET_VERTEX_DATA(frame)
162}
163
164void
165evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh,
166 int frame,
167 Evas_3D_Primitive_Mode mode,
168 int p,
169 Evas_Vec2 tex_scale)
170{
171 switch (mode)
172 {
173 case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
174 case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
175 {
176 _set_default_sphere(mesh, frame, p, tex_scale);
177 break;
178 }
179 case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
180 {
181 _set_sphere_with_alternative_uv(mesh, frame, p, tex_scale);
182 break;
183 }
184 default:
185 {
186 ERR("Unknown mode of primitive");
187 }
188 }
189}
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 0000000000..abb76d8c88
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/solids_of_revolution/torus.c
@@ -0,0 +1,67 @@
1#include "../primitive_common.h"
2
3void
4evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh,
5 int frame,
6 Evas_Real ratio,
7 int p,
8 Evas_Vec2 tex_scale)
9{
10 int vcount, icount, vccount, i, j;
11 icount = p * p * 6;
12 vccount = p + 1;
13 vcount = vccount * vccount;
14
15 ALLOCATE_VERTEX_DATA
16
17 double d, sinth, costh, fi, theta, sinfi, cosfi;
18
19 d = 2 * M_PI / p;
20
21 float rratio;
22
23 if ((ratio < 1.0))
24 {
25 printf("Ratio of torus should be greater than or equal 1.0.\n");
26 printf("Ratio = %f is a bad value, so 3.0 is used like default ratio.\n",
27 ratio);
28 rratio = 1.0 / 3.0;
29 }
30 else
31 {
32 rratio = 1.0 / ratio;
33 }
34
35 for (j = 0; j < vccount; j++)
36 {
37 theta = j * d;
38 sinth = sin(theta);
39 costh = cos(theta);
40 for (i = 0; i < vccount; i++)
41 {
42 fi = i * d;
43 sinfi = sin(fi);
44 cosfi = cos(fi);
45 vertices[i + j * vccount].x = (1.0 - rratio + rratio * cosfi) * costh * 0.5;
46 vertices[i + j * vccount].y = (1.0 - rratio + rratio * cosfi) * sinth * 0.5;
47 vertices[i + j * vccount].z = rratio * sinfi * 0.5;
48
49 normals[i + j * vccount].x = cosfi * costh;
50 normals[i + j * vccount].y = cosfi * sinth;
51 normals[i + j * vccount].z = sinfi;
52
53 tangents[i + j * vccount].x = -sinfi * costh;
54 tangents[i + j * vccount].y = -sinfi * sinth;
55 tangents[i + j * vccount].z = cosfi;
56
57 _primitives_vec3_normalize(&normals[i + j * vccount]);
58
59 tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * tex_scale.x;
60 tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
61 }
62 }
63
64 _generate_indices(indices, p, p);
65
66 SET_VERTEX_DATA(frame)
67}
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 0000000000..7eb1779ebe
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/surfaces/surface.c
@@ -0,0 +1,91 @@
1#include "../primitive_common.h"
2
3Evas_Vec3 _get_func_normal(Evas_3D_Surface_Func *func, Evas_Real x, Evas_Real y)
4{
5 Evas_Vec3 v00, v01, v10, d1, d2, normal;
6
7 func(&v00.x, &v00.y, &v00.z, x, y);
8 func(&v01.x, &v01.y, &v01.z, x, y + 0.01);
9 func(&v10.x, &v10.y, &v10.z, x + 0.01, y);
10 _primitives_vec3_subtract(&d1, &v00, &v01);
11 _primitives_vec3_subtract(&d2, &v01, &v10);
12
13 _primitives_vec3_cross_product(&normal, &d1, &d2);
14
15 _primitives_vec3_normalize(&normal);
16
17 return normal;
18}
19
20void
21_normalize(Evas_Vec3 *vertices, Evas_Vec3 *normals, int vcount)
22{
23 int i;
24 Evas_Vec3 min, max;
25 min = max = vertices[0];
26
27#define CHECK_MIN_AND_MAX(coord) \
28 if (min.coord > vertices[i].coord) \
29 min.coord = vertices[i].coord; \
30 else if (max.coord < vertices[i].coord) \
31 max.coord = vertices[i].coord;
32 for (i = 1; i < vcount; i++)
33 {
34 CHECK_MIN_AND_MAX(x)
35 CHECK_MIN_AND_MAX(y)
36 CHECK_MIN_AND_MAX(z)
37 }
38#undef CHECK_MIN_AND_MAX
39
40 for (i = 0; i < vcount; i++)
41 {
42 vertices[i].x = (vertices[i].x - min.x) / (max.x - min.x) - 0.5;
43 vertices[i].y = (vertices[i].y - min.y) / (max.y - min.y) - 0.5;
44 vertices[i].z = (vertices[i].z - min.z) / (max.z - min.z) - 0.5;
45
46 normals[i].x = normals[i].x / (max.x - min.x);
47 normals[i].y = normals[i].y / (max.y - min.y);
48 normals[i].z = normals[i].z / (max.z - min.z);
49 }
50}
51
52void
53evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh,
54 int frame,
55 Evas_3D_Surface_Func func,
56 int p,
57 Evas_Vec2 tex_scale)
58{
59 int vcount, icount, vccount, i, j, num;
60 icount = p * p * 6;
61 vccount = p + 1;
62 vcount = vccount * vccount;
63
64 ALLOCATE_VERTEX_DATA
65
66 Evas_Real v, u, d = 1.0 / p;
67
68 for (j = 0; j < vccount; j++)
69 {
70 u = j * d - 0.5;
71 for (i = 0; i < vccount; i++)
72 {
73 v = i * d - 0.5;
74 num = i + j * vccount;
75 func(&vertices[num].x,
76 &vertices[num].y,
77 &vertices[num].z,
78 v, u);
79 normals[num] = _get_func_normal(func, v, u);
80
81 tangents[num].x = tangents[num].y = tangents[num].z = 0;
82
83 tex_coord[num].x = i / ((vccount - 1) * tex_scale.x);
84 tex_coord[num].y = tex_scale.y - j / ((vccount - 1) * tex_scale.y);
85 }
86 }
87
88 _normalize(vertices, normals, vcount);
89 _generate_indices(indices, p, p);
90 SET_VERTEX_DATA(frame)
91}
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 0000000000..542ed74b0d
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/surfaces/terrain.c
@@ -0,0 +1,86 @@
1#include "../primitive_common.h"
2
3static Evas_Real
4_random(int x, int y)
5{
6 int k = x + y * 57;
7 k = (k << 13) ^ k;
8 return (1.0f - ((k * (k * k * 15731 + 789221) + 1376312589) & 0x7fffffff) /
9 1073741824.0f);
10}
11
12static Evas_Real
13_smooth(Evas_Real x, Evas_Real y)
14{
15 Evas_Real res;
16 res = (_random(x - 1, y - 1) + _random(x + 1, y - 1) +
17 _random(x - 1, y + 1) + _random(x + 1, y + 1)) / 16;
18 res += (_random(x - 1, y) + _random(x + 1, y) +
19 _random(x, y - 1) + _random(x, y + 1)) / 8;
20 res += _random(x, y) / 4;
21 return res;
22}
23
24static Evas_Real
25_interpolate(Evas_Real a, Evas_Real b, Evas_Real x)
26{
27 Evas_Real ft = x * M_PI;
28 Evas_Real f = (1 - cosf(ft)) * 0.5;
29 return a * (1 - f) + b * f;
30}
31
32static Evas_Real _noise(Evas_Real x, Evas_Real y)
33{
34 Evas_Real ix = (int)(x);
35 Evas_Real fx = x - ix;
36 Evas_Real iy = (int)(y);
37 Evas_Real fy = y - iy;
38
39 Evas_Real v1 = _smooth(ix, iy);
40 Evas_Real v2 = _smooth(ix + 1, iy);
41 Evas_Real v3 = _smooth(ix, iy + 1);
42 Evas_Real v4 = _smooth(ix + 1, iy + 1);
43
44 Evas_Real i1 = _interpolate(v1, v2, fx);
45 Evas_Real i2 = _interpolate(v3, v4, fx);
46
47 return _interpolate(i1, i2, fy);
48}
49
50static void
51_perlin_terrain(Evas_Real *out_x,
52 Evas_Real *out_y,
53 Evas_Real *out_z,
54 Evas_Real x,
55 Evas_Real y)
56{
57 Evas_Real persistence = 0.5f;
58 Evas_Real frequency = 5;
59 Evas_Real amplitude = 1;
60 int i = 0;
61 int octaves = 5;
62
63 *out_x = x;
64 x += 0.5;
65 *out_y = y;
66 y += 0.5;
67 *out_z = 0;
68
69 for(i = 0; i < octaves; i++)
70 {
71 *out_z += _noise(x * frequency, y * frequency) * amplitude;
72
73 amplitude *= persistence;
74 frequency *= 2;
75 }
76}
77
78void
79evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh,
80 int frame,
81 int p,
82 Evas_Vec2 tex_scale)
83{
84 evas_model_set_from_surface_primitive(mesh, frame, _perlin_terrain, p, tex_scale);
85}
86
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 0000000000..6f70a02b9d
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/tabulated_primitives/cube.c
@@ -0,0 +1,57 @@
1#include "../primitive_common.h"
2
3const float vertices_of_cube[] =
4{
5 /* positions normals vertex_color tex_coords tangents */
6 /* Front */
7 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,
8 -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,
9 -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,
10 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,
11
12 /* Left */
13 -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,
14 -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,
15 -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,
16 -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,
17
18 /* Back */
19 -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,
20 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,
21 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,
22 -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,
23
24 /* Right */
25 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,
26 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,
27 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,
28 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,
29
30 /* Top */
31 -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,
32 -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,
33 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,
34 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,
35
36 /* Bottom */
37 -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,
38 -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,
39 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,
40 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,
41};
42
43const unsigned short indices_of_cube[] =
44{
45 0, 1, 2, 6, 7, 4,
46 4, 5, 6, 10, 11, 8,
47 8, 9, 10, 14, 15, 12,
48 12, 13, 14, 2, 3, 0,
49 19, 16, 17, 17, 18, 19,
50 23, 20, 21, 21, 22, 23
51};
52
53void
54evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame)
55{
56 SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_cube, 24, indices_of_cube, 36)
57}
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 0000000000..6f5c0c6f27
--- /dev/null
+++ b/src/lib/evas/common3d/primitives/tabulated_primitives/square.c
@@ -0,0 +1,18 @@
1#include "../primitive_common.h"
2
3const float vertices_of_square[] =
4{
5 /* positions normals vertex_color tex_coords tangents */
6 -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,
7 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,
8 -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,
9 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,
10};
11
12const unsigned short indices_of_square[] = {0, 1, 2, 2, 1, 3};
13
14void
15evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame)
16{
17 SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_square, 4, indices_of_square, 6)
18}
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 7d9303c802..e7c8d02a5d 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;
100typedef struct _Evas_3D_Light Evas_3D_Light_Data; 100typedef struct _Evas_3D_Light Evas_3D_Light_Data;
101typedef struct _Evas_3D_Material Evas_3D_Material_Data; 101typedef struct _Evas_3D_Material Evas_3D_Material_Data;
102typedef struct _Evas_3D_Texture Evas_3D_Texture_Data; 102typedef struct _Evas_3D_Texture Evas_3D_Texture_Data;
103typedef struct _Evas_3D_Primitive Evas_3D_Primitive_Data;
103 104
104/* Structs for mesh eet saver/loader */ 105/* Structs for mesh eet saver/loader */
105typedef struct _Evas_3D_Vec2_Eet Evas_3D_Vec2_Eet; 106typedef struct _Evas_3D_Vec2_Eet Evas_3D_Vec2_Eet;
@@ -415,6 +416,17 @@ struct _Evas_3D_Material
415 Eina_Hash *meshes; 416 Eina_Hash *meshes;
416}; 417};
417 418
419struct _Evas_3D_Primitive
420{
421 Evas_3D_Mesh_Primitive form;
422 Evas_3D_Primitive_Mode mode;
423 Evas_Real ratio;
424 int precision;
425 Evas_3D_Surface_Func *surface;
426
427 Evas_Vec2 tex_scale;
428};
429
418struct _Evas_3D_Scene_Public_Data 430struct _Evas_3D_Scene_Public_Data
419{ 431{
420 Evas_Color bg_color; 432 Evas_Color bg_color;
@@ -1746,6 +1758,17 @@ void evas_model_save_file_eet(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh
1746void evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f); 1758void evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
1747void evas_model_save_file_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f); 1759void evas_model_save_file_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
1748 1760
1761/* Primitives functions */
1762void evas_common_set_model_from_primitive(Evas_3D_Mesh *model, int frame, Evas_3D_Primitive_Data *primitive);
1763void evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame);
1764void evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame);
1765void evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
1766void evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
1767void evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
1768void evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh, int frame, Evas_Real ratio, int precision, Evas_Vec2 tex_scale);
1769void evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
1770void evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale);
1771
1749extern int _evas_alloc_error; 1772extern int _evas_alloc_error;
1750extern int _evas_event_counter; 1773extern int _evas_event_counter;
1751 1774