quick 3d test for people to know what the perspective and rotate
[framework/uifw/elementary.git] / src / bin / test_3d.c
1 #include <Elementary.h>
2 #ifdef HAVE_CONFIG_H
3 # include "elementary_config.h"
4 #endif
5 #ifndef ELM_LIB_QUICKLAUNCH
6
7 typedef struct _Point
8 {
9    Evas_Coord x, y, z, u, v;
10 } Point;
11
12 typedef struct _Side
13 {
14    Evas_Object *o;
15    Point pt[4];
16 } Side;
17
18 typedef struct _Cube
19 {
20    Side side[6];
21 } Cube;
22
23 static Cube *cube;
24 static double rotx = 0.0, roty = 0.0, rotz = 0.0;
25 static double cxo = 0.0, cyo = 0.0, focv = 256.0, z0v = 0.0;
26 #define POINT(n, p, xx, yy, zz, uu, vv) \
27    c->side[n].pt[p].x = xx; \
28    c->side[n].pt[p].y = yy; \
29    c->side[n].pt[p].z = zz; \
30    c->side[n].pt[p].u = uu; \
31    c->side[n].pt[p].v = vv
32
33 static Cube *
34 _cube_new(Evas *evas, Evas_Coord w, Evas_Coord h, Evas_Coord d)
35 {
36    Cube *c;
37    int i;
38    
39    w -= (w / 2);
40    h -= (h / 2);
41    d -= (d / 2);
42    c = calloc(1, sizeof(Cube));
43    for (i = 0; i < 6; i++)
44      {
45         Evas_Object *o;
46         char buf[PATH_MAX];
47         o = evas_object_image_add(evas);
48         c->side[i].o = o;
49         snprintf(buf, sizeof(buf), "%s/images/%s",
50                  PACKAGE_DATA_DIR, "twofish.jpg");
51         evas_object_image_file_set(o, buf, NULL);
52         evas_object_image_fill_set(o, 0, 0, 256, 256);
53         evas_object_resize(o, 256, 256);
54         evas_object_image_smooth_scale_set(o, 0);
55         evas_object_show(o);
56      }
57    POINT(0, 0, -w, -h, -d,   0,   0);
58    POINT(0, 1,  w, -h, -d, 256,   0);
59    POINT(0, 2,  w,  h, -d, 256, 256);
60    POINT(0, 3, -w,  h, -d,   0, 256);
61    
62    POINT(1, 0,  w, -h, -d,   0,   0);
63    POINT(1, 1,  w, -h,  d, 256,   0);
64    POINT(1, 2,  w,  h,  d, 256, 256);
65    POINT(1, 3,  w,  h, -d,   0, 256);
66    
67    POINT(2, 0,  w, -h,  d,   0,   0);
68    POINT(2, 1, -w, -h,  d, 256,   0);
69    POINT(2, 2, -w,  h,  d, 256, 256);
70    POINT(2, 3,  w,  h,  d,   0, 256);
71    
72    POINT(3, 0, -w, -h,  d,   0,   0);
73    POINT(3, 1, -w, -h, -d, 256,   0);
74    POINT(3, 2, -w,  h, -d, 256, 256);
75    POINT(3, 3, -w,  h,  d,   0, 256);
76    
77    POINT(4, 0, -w, -h,  d,   0,   0);
78    POINT(4, 1,  w, -h,  d, 256,   0);
79    POINT(4, 2,  w, -h, -d, 256, 256);
80    POINT(4, 3, -w, -h, -d,   0, 256);
81    
82    POINT(5, 0, -w,  h, -d,   0,   0);
83    POINT(5, 1,  w,  h, -d, 256,   0);
84    POINT(5, 2,  w,  h,  d, 256, 256);
85    POINT(5, 3, -w,  h,  d,   0, 256);
86    
87    return c;
88 }
89
90 static void
91 _cube_pos(Cube *c,
92           Evas_Coord x, Evas_Coord y, Evas_Coord z,
93           double dx, double dy, double dz,
94           Evas_Coord cx, Evas_Coord cy, Evas_Coord foc, Evas_Coord z0)
95 {
96    Evas_Map *m;
97    int i, j, order[6], sorted;
98    Evas_Coord mz[6];
99    
100    m = evas_map_new(4);
101    evas_map_smooth_set(m, 0);
102    
103    for (i = 0; i < 6; i++)
104      {
105         Evas_Coord tz[4];
106         
107         for (j = 0; j < 4; j++)
108           {
109              evas_map_point_coord_set(m, j,
110                                       c->side[i].pt[j].x + x,
111                                       c->side[i].pt[j].y + y,
112                                       c->side[i].pt[j].z + z);
113              evas_map_point_image_uv_set(m, j,
114                                          c->side[i].pt[j].u,
115                                          c->side[i].pt[j].v);
116              evas_map_point_color_set(m, j, 255, 255, 255, 255);
117           }
118         evas_map_util_3d_rotate(m, dx, dy, dz, x, y, z);
119         evas_map_util_3d_lighting(m, -1000, -1000, -1000,
120                                   255, 255, 255,
121                                   20, 20, 20);
122         evas_map_util_3d_perspective(m, cx, cy, foc, z0);
123         if (evas_map_util_clockwise_get(m))
124           {
125              evas_object_map_enable_set(c->side[i].o, 1);
126              evas_object_map_set(c->side[i].o, m);
127              evas_object_show(c->side[i].o);
128           }
129         else
130            evas_object_hide(c->side[i].o);
131         
132         order[i] = i;
133         for (j = 0; j < 4; j++)
134            evas_map_point_coord_get(m, j, NULL, NULL, &(tz[j]));
135         mz[i] = (tz[0] + tz[1] + tz[2] + tz[3]) / 4;
136      }
137    sorted = 0;
138    do
139      {
140         sorted = 1;
141         for (i = 0; i < 5; i++)
142           {
143              if (mz[order[i]] > mz[order[i + 1]])
144                {
145                   j = order[i];
146                   order[i] = order[i + 1];
147                   order[i + 1] = j;
148                   sorted = 0;
149                }
150           }
151      }
152    while (!sorted);
153    
154    evas_object_raise(c->side[order[0]].o);
155    for (i = 1; i < 6; i++)
156       evas_object_stack_below(c->side[order[i]].o, c->side[order[i - 1]].o);
157    evas_map_free(m);
158 }
159
160 static void
161 _cube_free(Cube *c)
162 {
163    int i;
164    
165    for (i = 0; i < 6; i++) evas_object_del(c->side[i].o);
166    free(c);
167 }
168
169 static void
170 _cube_update(Evas_Object *win, Cube *c)
171 {
172    Evas_Coord w, h;
173    
174    evas_object_geometry_get(win, NULL, NULL, &w, &h);
175    _cube_pos(c,
176              (w / 2), (h / 2), 512,
177              rotx, roty, rotz,
178              (w / 2) + cxo, (h / 2) + cyo, z0v, focv);
179 }
180
181 void
182 _ch_rot_x(void *data, Evas_Object *obj, void *event_info __UNUSED__)
183 {
184    Evas_Object *win = data;
185    rotx = elm_slider_value_get(obj);
186    _cube_update(win, cube);
187 }
188
189 void
190 _ch_rot_y(void *data, Evas_Object *obj, void *event_info __UNUSED__)
191 {
192    Evas_Object *win = data;
193    roty = elm_slider_value_get(obj);
194    _cube_update(win, cube);
195 }
196
197 void
198 _ch_rot_z(void *data, Evas_Object *obj, void *event_info __UNUSED__)
199 {
200    Evas_Object *win = data;
201    rotz = elm_slider_value_get(obj);
202    _cube_update(win, cube);
203 }
204
205 void
206 _ch_cx(void *data, Evas_Object *obj, void *event_info __UNUSED__)
207 {
208    Evas_Object *win = data;
209    cxo = elm_slider_value_get(obj);
210    _cube_update(win, cube);
211 }
212
213 void
214 _ch_cy(void *data, Evas_Object *obj, void *event_info __UNUSED__)
215 {
216    Evas_Object *win = data;
217    cyo = elm_slider_value_get(obj);
218    _cube_update(win, cube);
219 }
220
221 void
222 _ch_foc(void *data, Evas_Object *obj, void *event_info __UNUSED__)
223 {
224    Evas_Object *win = data;
225    focv = elm_slider_value_get(obj);
226    _cube_update(win, cube);
227 }
228
229 void
230 _ch_z0(void *data, Evas_Object *obj, void *event_info __UNUSED__)
231 {
232    Evas_Object *win = data;
233    z0v = elm_slider_value_get(obj);
234    _cube_update(win, cube);
235 }
236
237 void
238 test_3d(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
239 {
240    Evas_Object *win, *bg, *bx, *sl;
241    char buf[PATH_MAX];
242
243    win = elm_win_add(NULL, "3d", ELM_WIN_BASIC);
244    elm_win_title_set(win, "3D");
245    elm_win_autodel_set(win, 1);
246
247    bg = elm_bg_add(win);
248    elm_win_resize_object_add(win, bg);
249    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
250    evas_object_show(bg);
251
252    cube = _cube_new(evas_object_evas_get(win), 240, 240, 240);
253    
254    bx = elm_box_add(win);
255    evas_object_layer_set(bx, 10);
256    evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
257    elm_win_resize_object_add(win, bx);
258    evas_object_show(bx);
259
260    sl = elm_slider_add(win);
261    elm_slider_label_set(sl, "Rot X");
262    elm_slider_unit_format_set(sl, "%1.0f units");
263    elm_slider_span_size_set(sl, 360);
264    elm_slider_min_max_set(sl, 0, 360);
265    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
266    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
267    elm_box_pack_end(bx, sl);
268    evas_object_smart_callback_add(sl, "changed", _ch_rot_x, win);
269    evas_object_show(sl);
270
271    sl = elm_slider_add(win);
272    elm_slider_label_set(sl, "Rot Y");
273    elm_slider_unit_format_set(sl, "%1.0f units");
274    elm_slider_span_size_set(sl, 360);
275    elm_slider_min_max_set(sl, 0, 360);
276    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
277    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
278    elm_box_pack_end(bx, sl);
279    evas_object_smart_callback_add(sl, "changed", _ch_rot_y, win);
280    evas_object_show(sl);
281
282    sl = elm_slider_add(win);
283    elm_slider_label_set(sl, "Rot Z");
284    elm_slider_unit_format_set(sl, "%1.0f units");
285    elm_slider_span_size_set(sl, 360);
286    elm_slider_min_max_set(sl, 0, 360);
287    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
288    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
289    elm_box_pack_end(bx, sl);
290    evas_object_smart_callback_add(sl, "changed", _ch_rot_z, win);
291    evas_object_show(sl);
292
293    sl = elm_slider_add(win);
294    elm_slider_label_set(sl, "CX Off");
295    elm_slider_unit_format_set(sl, "%1.0f units");
296    elm_slider_span_size_set(sl, 360);
297    elm_slider_min_max_set(sl, -320, 320);
298    elm_slider_value_set(sl, cxo);
299    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
300    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
301    elm_box_pack_end(bx, sl);
302    evas_object_smart_callback_add(sl, "changed", _ch_cx, win);
303    evas_object_show(sl);
304
305    sl = elm_slider_add(win);
306    elm_slider_label_set(sl, "CY Off");
307    elm_slider_unit_format_set(sl, "%1.0f units");
308    elm_slider_span_size_set(sl, 360);
309    elm_slider_min_max_set(sl, -320, 320);
310    elm_slider_value_set(sl, cyo);
311    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
312    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
313    elm_box_pack_end(bx, sl);
314    evas_object_smart_callback_add(sl, "changed", _ch_cy, win);
315    evas_object_show(sl);
316
317    sl = elm_slider_add(win);
318    elm_slider_label_set(sl, "Foc");
319    elm_slider_unit_format_set(sl, "%1.0f units");
320    elm_slider_span_size_set(sl, 360);
321    elm_slider_min_max_set(sl, 1, 2000);
322    elm_slider_value_set(sl, focv);
323    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
324    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
325    elm_box_pack_end(bx, sl);
326    evas_object_smart_callback_add(sl, "changed", _ch_foc, win);
327    evas_object_show(sl);
328
329    sl = elm_slider_add(win);
330    elm_slider_label_set(sl, "Z0");
331    elm_slider_unit_format_set(sl, "%1.0f units");
332    elm_slider_span_size_set(sl, 360);
333    elm_slider_min_max_set(sl, -2000, 2000);
334    elm_slider_value_set(sl, z0v);
335    evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
336    evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
337    elm_box_pack_end(bx, sl);
338    evas_object_smart_callback_add(sl, "changed", _ch_z0, win);
339    evas_object_show(sl);
340
341    evas_object_resize(win, 480, 480);
342    _cube_update(win, cube);
343    evas_object_show(win);
344 }
345 #endif