summaryrefslogtreecommitdiff
path: root/src/lib/evas/common3d
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 /src/lib/evas/common3d
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>
Diffstat (limited to 'src/lib/evas/common3d')
-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
10 files changed, 1051 insertions, 0 deletions
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}