diff options
author | David Walter Seikel | 2014-05-02 01:23:33 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-05-02 01:23:33 +1000 |
commit | cee4c4ca9c9c9bf587cbaa74784b1c77972ad414 (patch) | |
tree | efa93981cde707aa9534ed19724a59becdfa0f82 /src/GuiLua | |
parent | Halve the test window size. (diff) | |
download | SledjHamr-cee4c4ca9c9c9bf587cbaa74784b1c77972ad414.zip SledjHamr-cee4c4ca9c9c9bf587cbaa74784b1c77972ad414.tar.gz SledjHamr-cee4c4ca9c9c9bf587cbaa74784b1c77972ad414.tar.bz2 SledjHamr-cee4c4ca9c9c9bf587cbaa74784b1c77972ad414.tar.xz |
Add the rotating Earth and pick example.
Diffstat (limited to 'src/GuiLua')
-rw-r--r-- | src/GuiLua/GuiLua.c | 322 |
1 files changed, 317 insertions, 5 deletions
diff --git a/src/GuiLua/GuiLua.c b/src/GuiLua/GuiLua.c index 36acd20..48c5c75 100644 --- a/src/GuiLua/GuiLua.c +++ b/src/GuiLua/GuiLua.c | |||
@@ -144,6 +144,11 @@ and ordinary elementary widgets. Proper introspection can come later. | |||
144 | 144 | ||
145 | 145 | ||
146 | 146 | ||
147 | globals ourGlobals; | ||
148 | static const char *globName = "ourGlobals"; | ||
149 | |||
150 | |||
151 | |||
147 | 152 | ||
148 | typedef struct _Scene_Data | 153 | typedef struct _Scene_Data |
149 | { | 154 | { |
@@ -151,22 +156,33 @@ typedef struct _Scene_Data | |||
151 | Evas_3D_Node *root_node; | 156 | Evas_3D_Node *root_node; |
152 | Evas_3D_Node *camera_node; | 157 | Evas_3D_Node *camera_node; |
153 | Evas_3D_Node *light_node; | 158 | Evas_3D_Node *light_node; |
154 | Evas_3D_Node *mesh_node; | ||
155 | Evas_3D_Node *mesh2_node; | ||
156 | 159 | ||
157 | Evas_3D_Camera *camera; | 160 | Evas_3D_Camera *camera; |
158 | Evas_3D_Light *light; | 161 | Evas_3D_Light *light; |
162 | |||
159 | Evas_3D_Mesh *mesh; | 163 | Evas_3D_Mesh *mesh; |
164 | Evas_3D_Node *mesh_node; | ||
160 | Evas_3D_Material *material0; | 165 | Evas_3D_Material *material0; |
161 | Evas_3D_Material *material1; | 166 | Evas_3D_Material *material1; |
162 | Evas_3D_Texture *texture0; | 167 | Evas_3D_Texture *texture0; |
163 | Evas_3D_Texture *texture1; | 168 | Evas_3D_Texture *texture1; |
164 | Evas_3D_Texture *texture_normal; | 169 | Evas_3D_Texture *texture_normal; |
170 | |||
165 | Evas_3D_Mesh *mesh2; | 171 | Evas_3D_Mesh *mesh2; |
172 | Evas_3D_Node *mesh2_node; | ||
166 | Evas_3D_Material *material2; | 173 | Evas_3D_Material *material2; |
167 | Evas_3D_Texture *texture2; | 174 | Evas_3D_Texture *texture2; |
175 | |||
176 | Evas_3D_Mesh *mesh3; | ||
177 | Evas_3D_Node *mesh3_node; | ||
178 | Evas_3D_Material *material3; | ||
179 | Evas_3D_Texture *texture_diffuse; | ||
180 | |||
168 | } Scene_Data; | 181 | } Scene_Data; |
169 | 182 | ||
183 | static Scene_Data ourScene; | ||
184 | |||
185 | |||
170 | static const float cube_vertices[] = | 186 | static const float cube_vertices[] = |
171 | { | 187 | { |
172 | /* Front */ | 188 | /* Front */ |
@@ -244,16 +260,205 @@ static const unsigned int pixels1[] = | |||
244 | }; | 260 | }; |
245 | 261 | ||
246 | 262 | ||
247 | globals ourGlobals; | 263 | typedef struct _vec4 |
248 | static const char *globName = "ourGlobals"; | 264 | { |
265 | float x; | ||
266 | float y; | ||
267 | float z; | ||
268 | float w; | ||
269 | } vec4; | ||
249 | 270 | ||
271 | typedef struct _vec3 | ||
272 | { | ||
273 | float x; | ||
274 | float y; | ||
275 | float z; | ||
276 | } vec3; | ||
277 | |||
278 | typedef struct _vec2 | ||
279 | { | ||
280 | float x; | ||
281 | float y; | ||
282 | } vec2; | ||
283 | |||
284 | typedef struct _vertex | ||
285 | { | ||
286 | vec3 position; | ||
287 | vec3 normal; | ||
288 | vec3 tangent; | ||
289 | vec4 color; | ||
290 | vec3 texcoord; | ||
291 | } vertex; | ||
292 | |||
293 | static int vertex_count = 0; | ||
294 | static vertex *sphere_vertices = NULL; | ||
295 | |||
296 | static int index_count = 0; | ||
297 | static unsigned short *sphere_indices = NULL; | ||
298 | |||
299 | static inline vec3 | ||
300 | _normalize(const vec3 *v) | ||
301 | { | ||
302 | double l = sqrt(v->x * v->x + v->y * v->y + v->z * v->z); | ||
303 | vec3 vec; | ||
304 | |||
305 | vec.x = v->x / l; | ||
306 | vec.y = v->y / l; | ||
307 | vec.z = v->z / l; | ||
308 | |||
309 | return vec; | ||
310 | } | ||
311 | |||
312 | static void | ||
313 | _sphere_fini() | ||
314 | { | ||
315 | if (sphere_vertices) | ||
316 | free(sphere_vertices); | ||
317 | |||
318 | if (sphere_indices) | ||
319 | free(sphere_indices); | ||
320 | } | ||
321 | |||
322 | static void | ||
323 | _sphere_init(int precision) | ||
324 | { | ||
325 | int i, j; | ||
326 | unsigned short *index; | ||
327 | |||
328 | vertex_count = (precision + 1) * (precision + 1); | ||
329 | index_count = precision * precision * 6; | ||
330 | |||
331 | /* Allocate buffer. */ | ||
332 | sphere_vertices = malloc(sizeof(vertex) * vertex_count); | ||
333 | sphere_indices = malloc(sizeof(unsigned short) * index_count); | ||
334 | |||
335 | for (i = 0; i <= precision; i++) | ||
336 | { | ||
337 | double lati = (M_PI * (double)i) / (double)precision; | ||
338 | double y = cos(lati); | ||
339 | double r = fabs(sin(lati)); | ||
340 | |||
341 | for (j = 0; j <= precision; j++) | ||
342 | { | ||
343 | double longi = (M_PI * 2.0 * j) / precision; | ||
344 | vertex *v = &sphere_vertices[i * (precision + 1) + j]; | ||
345 | |||
346 | if (j == 0 || j == precision) | ||
347 | v->position.x = 0.0; | ||
348 | else | ||
349 | v->position.x = r * sin(longi); | ||
350 | |||
351 | v->position.y = y; | ||
352 | |||
353 | if (j == 0 || j == precision) | ||
354 | v->position.z = r; | ||
355 | else | ||
356 | v->position.z = r * cos(longi); | ||
357 | |||
358 | v->normal = v->position; | ||
359 | |||
360 | if (v->position.x > 0.0) | ||
361 | { | ||
362 | v->tangent.x = -v->normal.y; | ||
363 | v->tangent.y = v->normal.x; | ||
364 | v->tangent.z = v->normal.z; | ||
365 | } | ||
366 | else | ||
367 | { | ||
368 | v->tangent.x = v->normal.y; | ||
369 | v->tangent.y = -v->normal.x; | ||
370 | v->tangent.z = v->normal.z; | ||
371 | } | ||
372 | |||
373 | v->color.x = v->position.x; | ||
374 | v->color.y = v->position.y; | ||
375 | v->color.z = v->position.z; | ||
376 | v->color.w = 1.0; | ||
377 | |||
378 | if (j == precision) | ||
379 | v->texcoord.x = 1.0; | ||
380 | else if (j == 0) | ||
381 | v->texcoord.x = 0.0; | ||
382 | else | ||
383 | v->texcoord.x = (double)j / (double)precision; | ||
384 | |||
385 | if (i == precision) | ||
386 | v->texcoord.y = 1.0; | ||
387 | else if (i == 0) | ||
388 | v->texcoord.y = 0.0; | ||
389 | else | ||
390 | v->texcoord.y = 1.0 - (double)i / (double)precision; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | index = &sphere_indices[0]; | ||
395 | |||
396 | for (i = 0; i < precision; i++) | ||
397 | { | ||
398 | for (j = 0; j < precision; j++) | ||
399 | { | ||
400 | *index++ = i * (precision + 1) + j; | ||
401 | *index++ = i * (precision + 1) + j + 1; | ||
402 | *index++ = (i + 1) * (precision + 1) + j; | ||
403 | |||
404 | *index++ = (i + 1) * (precision + 1) + j; | ||
405 | *index++ = i * (precision + 1) + j + 1; | ||
406 | *index++ = (i + 1) * (precision + 1) + j + 1; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | for (i = 0; i < index_count; i += 3) | ||
411 | { | ||
412 | vertex *v0 = &sphere_vertices[sphere_indices[i + 0]]; | ||
413 | vertex *v1 = &sphere_vertices[sphere_indices[i + 1]]; | ||
414 | vertex *v2 = &sphere_vertices[sphere_indices[i + 2]]; | ||
415 | |||
416 | vec3 e1, e2; | ||
417 | float du1, du2, dv1, dv2, f; | ||
418 | vec3 tangent; | ||
419 | |||
420 | e1.x = v1->position.x - v0->position.x; | ||
421 | e1.y = v1->position.y - v0->position.y; | ||
422 | e1.z = v1->position.z - v0->position.z; | ||
423 | |||
424 | e2.x = v2->position.x - v0->position.x; | ||
425 | e2.y = v2->position.y - v0->position.y; | ||
426 | e2.z = v2->position.z - v0->position.z; | ||
427 | |||
428 | du1 = v1->texcoord.x - v0->texcoord.x; | ||
429 | dv1 = v1->texcoord.y - v0->texcoord.y; | ||
430 | |||
431 | du2 = v2->texcoord.x - v0->texcoord.x; | ||
432 | dv2 = v2->texcoord.y - v0->texcoord.y; | ||
433 | |||
434 | f = 1.0 / (du1 * dv2 - du2 * dv1); | ||
435 | |||
436 | tangent.x = f * (dv2 * e1.x - dv1 * e2.x); | ||
437 | tangent.y = f * (dv2 * e1.y - dv1 * e2.y); | ||
438 | tangent.z = f * (dv2 * e1.z - dv1 * e2.z); | ||
439 | |||
440 | v0->tangent = tangent; | ||
441 | } | ||
442 | |||
443 | for (i = 0; i <= precision; i++) | ||
444 | { | ||
445 | for (j = 0; j <= precision; j++) | ||
446 | { | ||
447 | if (j == precision) | ||
448 | { | ||
449 | vertex *v = &sphere_vertices[i * (precision + 1) + j]; | ||
450 | v->tangent = sphere_vertices[i * (precision + 1)].tangent; | ||
451 | } | ||
452 | } | ||
453 | } | ||
454 | } | ||
250 | 455 | ||
251 | static Scene_Data ourScene; | ||
252 | 456 | ||
253 | static Eina_Bool | 457 | static Eina_Bool |
254 | _animate_scene(void *data) | 458 | _animate_scene(void *data) |
255 | { | 459 | { |
256 | static float angle = 0.0f; | 460 | static float angle = 0.0f; |
461 | static float earthAngle = 0.0f; | ||
257 | static int frame = 0; | 462 | static int frame = 0; |
258 | static int inc = 1; | 463 | static int inc = 1; |
259 | static int sonicFrame = 0; | 464 | static int sonicFrame = 0; |
@@ -281,6 +486,13 @@ _animate_scene(void *data) | |||
281 | evas_3d_node_mesh_frame_set(scene->mesh2, sonicFrame) | 486 | evas_3d_node_mesh_frame_set(scene->mesh2, sonicFrame) |
282 | ); | 487 | ); |
283 | 488 | ||
489 | // Animate earth. | ||
490 | earthAngle += 0.3; | ||
491 | if (earthAngle > 360.0) earthAngle -= 360.0f; | ||
492 | eo_do(scene->mesh3_node, | ||
493 | evas_3d_node_orientation_angle_axis_set(angle, 0.0, 1.0, 0.0) | ||
494 | ); | ||
495 | |||
284 | return EINA_TRUE; | 496 | return EINA_TRUE; |
285 | } | 497 | } |
286 | 498 | ||
@@ -399,6 +611,7 @@ _mesh_setup(globals *ourGlobals, Scene_Data *scene) | |||
399 | scene->mesh_node = evas_3d_node_add(ourGlobals->evas, EVAS_3D_NODE_TYPE_MESH); | 611 | scene->mesh_node = evas_3d_node_add(ourGlobals->evas, EVAS_3D_NODE_TYPE_MESH); |
400 | eo_do(scene->root_node, evas_3d_node_member_add(scene->mesh_node)); | 612 | eo_do(scene->root_node, evas_3d_node_member_add(scene->mesh_node)); |
401 | eo_do(scene->mesh_node, | 613 | eo_do(scene->mesh_node, |
614 | eo_key_data_set("Name", "cube", NULL), | ||
402 | evas_3d_node_position_set(40.0, 3.5, 23.0), | 615 | evas_3d_node_position_set(40.0, 3.5, 23.0), |
403 | evas_3d_node_mesh_add(scene->mesh) | 616 | evas_3d_node_mesh_add(scene->mesh) |
404 | ); | 617 | ); |
@@ -441,12 +654,65 @@ _mesh_setup(globals *ourGlobals, Scene_Data *scene) | |||
441 | evas_3d_node_member_add(scene->mesh2_node) | 654 | evas_3d_node_member_add(scene->mesh2_node) |
442 | ); | 655 | ); |
443 | eo_do(scene->mesh2_node, | 656 | eo_do(scene->mesh2_node, |
657 | eo_key_data_set("Name", "sonic", NULL), | ||
444 | evas_3d_node_mesh_add(scene->mesh2) | 658 | evas_3d_node_mesh_add(scene->mesh2) |
445 | ); | 659 | ); |
446 | 660 | ||
447 | eo_do(scene->mesh2, | 661 | eo_do(scene->mesh2, |
448 | evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG) | 662 | evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_PHONG) |
449 | ); | 663 | ); |
664 | |||
665 | |||
666 | // Setup earth material. | ||
667 | scene->material3 = eo_add(EVAS_3D_MATERIAL_CLASS, ourGlobals->evas); | ||
668 | |||
669 | scene->texture_diffuse = eo_add(EVAS_3D_TEXTURE_CLASS, ourGlobals->evas); | ||
670 | eo_do(scene->texture_diffuse, | ||
671 | evas_3d_texture_file_set("../../media/EarthDiffuse.png", NULL), | ||
672 | evas_3d_texture_filter_set(EVAS_3D_TEXTURE_FILTER_LINEAR, EVAS_3D_TEXTURE_FILTER_LINEAR)); | ||
673 | eo_do(scene->material3, | ||
674 | evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, scene->texture_diffuse), | ||
675 | |||
676 | evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE), | ||
677 | evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE), | ||
678 | evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE), | ||
679 | |||
680 | evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT, 0.01, 0.01, 0.01, 1.0), | ||
681 | evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE, 1.0, 1.0, 1.0, 1.0), | ||
682 | evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR, 1.0, 1.0, 1.0, 1.0), | ||
683 | evas_3d_material_shininess_set(50.0)); | ||
684 | |||
685 | // Setup earth mesh. | ||
686 | _sphere_init(100); | ||
687 | |||
688 | scene->mesh3 = eo_add(EVAS_3D_MESH_CLASS, ourGlobals->evas); | ||
689 | eo_do(scene->mesh3, | ||
690 | evas_3d_mesh_vertex_count_set(vertex_count), | ||
691 | evas_3d_mesh_frame_add(0), | ||
692 | evas_3d_mesh_frame_vertex_data_set(0, EVAS_3D_VERTEX_POSITION, sizeof(vertex), &sphere_vertices[0].position), | ||
693 | evas_3d_mesh_frame_vertex_data_set(0, EVAS_3D_VERTEX_NORMAL, sizeof(vertex), &sphere_vertices[0].normal), | ||
694 | evas_3d_mesh_frame_vertex_data_set(0, EVAS_3D_VERTEX_TANGENT, sizeof(vertex), &sphere_vertices[0].tangent), | ||
695 | evas_3d_mesh_frame_vertex_data_set(0, EVAS_3D_VERTEX_COLOR, sizeof(vertex), &sphere_vertices[0].color), | ||
696 | evas_3d_mesh_frame_vertex_data_set(0, EVAS_3D_VERTEX_TEXCOORD, sizeof(vertex), &sphere_vertices[0].texcoord), | ||
697 | |||
698 | evas_3d_mesh_index_data_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, index_count, &sphere_indices[0]), | ||
699 | evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES), | ||
700 | evas_3d_mesh_frame_material_set(0, scene->material3) | ||
701 | ); | ||
702 | |||
703 | scene->mesh3_node = evas_3d_node_add(ourGlobals->evas, EVAS_3D_NODE_TYPE_MESH); | ||
704 | eo_do(scene->root_node, | ||
705 | evas_3d_node_member_add(scene->mesh3_node) | ||
706 | ); | ||
707 | eo_do(scene->mesh3_node, | ||
708 | eo_key_data_set("Name", "earth", NULL), | ||
709 | evas_3d_node_position_set(40.0, -3.5, 23.0), | ||
710 | evas_3d_node_mesh_add(scene->mesh3) | ||
711 | ); | ||
712 | |||
713 | eo_do(scene->mesh3, | ||
714 | evas_3d_mesh_shade_mode_set(EVAS_3D_SHADE_MODE_DIFFUSE) | ||
715 | ); | ||
450 | } | 716 | } |
451 | 717 | ||
452 | 718 | ||
@@ -525,6 +791,50 @@ static void _on_click(void *data, Evas_Object *obj, void *event_info EINA_UNUSED | |||
525 | } | 791 | } |
526 | } | 792 | } |
527 | 793 | ||
794 | static void _on_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *o, void *einfo) | ||
795 | { | ||
796 | // globals *ourGlobals = data; | ||
797 | Evas_Event_Mouse_Down *ev = einfo; | ||
798 | Evas_Coord x, y, w, h; | ||
799 | Evas_Coord obj_x, obj_y; | ||
800 | int scene_w, scene_h; | ||
801 | Evas_Real scene_x, scene_y; | ||
802 | Evas_Real s, t; | ||
803 | Evas_3D_Node *n; | ||
804 | Evas_3D_Mesh *m; | ||
805 | Eina_Bool pick; | ||
806 | char *name; | ||
807 | |||
808 | evas_object_geometry_get(o, &x, &y, &w, &h); | ||
809 | |||
810 | obj_x = ev->canvas.x - x; | ||
811 | obj_y = ev->canvas.y - y; | ||
812 | |||
813 | eo_do(ourScene.scene, evas_3d_scene_size_get(&scene_w, &scene_h)); | ||
814 | |||
815 | scene_x = obj_x * scene_w / (Evas_Real)w; | ||
816 | scene_y = obj_y * scene_h / (Evas_Real)h; | ||
817 | |||
818 | eo_do(ourScene.scene, pick = evas_3d_scene_pick(scene_x, scene_y, &n, &m, &s, &t)); | ||
819 | if (pick) | ||
820 | { | ||
821 | name = evas_object_data_get(n, "Name"); | ||
822 | printf("Picked : "); | ||
823 | } | ||
824 | else | ||
825 | printf("Not picked : "); | ||
826 | if (NULL == name) | ||
827 | name = ""; | ||
828 | |||
829 | printf("output(%d, %d) canvas(%d, %d) object(%d, %d) scene(%f, %f) texcoord(%f, %f) " | ||
830 | "node(%p) %s mesh(%p)\n", | ||
831 | ev->output.x, ev->output.y, | ||
832 | ev->canvas.x, ev->canvas.y, | ||
833 | obj_x, obj_y, | ||
834 | scene_x, scene_y, | ||
835 | s, t, n, name, m); | ||
836 | } | ||
837 | |||
528 | static void _on_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) | 838 | static void _on_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) |
529 | { | 839 | { |
530 | // globals *ourGlobals = data; | 840 | // globals *ourGlobals = data; |
@@ -675,6 +985,7 @@ static int window(lua_State *L) | |||
675 | eo_do(temp, | 985 | eo_do(temp, |
676 | evas_obj_image_scene_set(ourScene.scene) | 986 | evas_obj_image_scene_set(ourScene.scene) |
677 | ); | 987 | ); |
988 | evas_object_event_callback_add(temp, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, &ourGlobals); | ||
678 | 989 | ||
679 | // Add animation timer callback. | 990 | // Add animation timer callback. |
680 | ecore_timer_add(0.016, _animate_scene, &ourScene); | 991 | ecore_timer_add(0.016, _animate_scene, &ourScene); |
@@ -741,6 +1052,7 @@ static int closeWindow(lua_State *L) | |||
741 | eo_unref(wid->obj); | 1052 | eo_unref(wid->obj); |
742 | } | 1053 | } |
743 | evas_object_del(ourGlobals->win); | 1054 | evas_object_del(ourGlobals->win); |
1055 | _sphere_fini(); | ||
744 | } | 1056 | } |
745 | 1057 | ||
746 | if (ourGlobals->logDom >= 0) | 1058 | if (ourGlobals->logDom >= 0) |