diff options
-rw-r--r-- | src/lib/evas/canvas/evas_3d_mesh.c | 46 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_3d_node.c | 99 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_3d_scene.c | 91 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 1 |
4 files changed, 122 insertions, 115 deletions
diff --git a/src/lib/evas/canvas/evas_3d_mesh.c b/src/lib/evas/canvas/evas_3d_mesh.c index 385820fe56..c51afacf30 100644 --- a/src/lib/evas/canvas/evas_3d_mesh.c +++ b/src/lib/evas/canvas/evas_3d_mesh.c @@ -911,14 +911,52 @@ _evas_3d_mesh_from_primitive_set(Eo *obj, evas_common_set_model_from_primitive(obj, frame, ppd); } +void +evas_3d_mesh_interpolate_position_get(Evas_Vec3 *out, const Evas_3D_Vertex_Buffer *pos0, const Evas_3D_Vertex_Buffer *pos1, + Evas_Real weight, int index) +{ + if (pos1->data == NULL) + { + float *ptr; + + if (pos0->stride != 0.0) + ptr = (char *)pos0->data + pos0->stride * index; + else + ptr = (char *)pos0->data + (3 * sizeof(float)) * index; + + out->x = ptr[0]; + out->y = ptr[1]; + out->z = ptr[2]; + } + else + { + float *ptr0, *ptr1; + + if (pos0->stride != 0.0) + ptr0 = (char *)pos0->data + pos0->stride * index; + else + ptr0 = (char *)pos0->data + (3 * sizeof(float)) * index; + + if (pos1->stride != 0.0) + ptr1 = (char *)pos1->data + pos1->stride * index; + else + ptr1 = (char *)pos1->data + (3 * sizeof(float)) * index; + + out->x = ptr0[0] * weight + ptr1[0] * (1.0 - weight); + out->y = ptr0[1] * weight + ptr1[1] * (1.0 - weight); + out->z = ptr0[2] * weight + ptr1[2] * (1.0 - weight); + } +} + static inline void -_mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame, +_mesh_frame_find(Evas_3D_Mesh *mesh, int frame, Eina_List **l, Eina_List **r) { Eina_List *left, *right; Evas_3D_Mesh_Frame *f0 = NULL, *f1; + Evas_3D_Mesh_Data *pdmesh = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); - left = mesh->frames; + left = pdmesh->frames; right = eina_list_next(left); while (right) @@ -945,6 +983,7 @@ _mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame, *l = left; *r = NULL; } + return; } *l = left; @@ -960,8 +999,7 @@ evas_3d_mesh_interpolate_vertex_buffer_get(Evas_3D_Mesh *mesh, int frame, { Eina_List *l, *r; const Evas_3D_Mesh_Frame *f0 = NULL, *f1 = NULL; - Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, MY_CLASS); - _mesh_frame_find(pd, frame, &l, &r); + _mesh_frame_find(mesh, frame, &l, &r); while (l) { diff --git a/src/lib/evas/canvas/evas_3d_node.c b/src/lib/evas/canvas/evas_3d_node.c index cce21f4001..b355e5e5e0 100644 --- a/src/lib/evas/canvas/evas_3d_node.c +++ b/src/lib/evas/canvas/evas_3d_node.c @@ -509,55 +509,60 @@ _calculate_box(Evas_Box3 *box3, int vertex_count, Evas_Vec3 *vertex_position) static void _pack_meshes_vertex_data(Evas_3D_Node *node, Evas_Vec3 **vertices, int *count) { - const Eina_List *m, *l; - Evas_3D_Mesh *mesh; - Evas_3D_Mesh_Frame *f; - int j; - int frame; - Evas_3D_Mesh_Data *mpd; - Evas_Vec3 *it; - - *count = 0; - eo_do(node, m = (Eina_List *)evas_3d_node_mesh_list_get()); - EINA_LIST_FOREACH(m, l, mesh) - { - eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); - mpd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); - f = evas_3d_mesh_frame_find(mpd, frame); - if (f) - if (f->vertices[EVAS_3D_VERTEX_POSITION].data) - *count += mpd->vertex_count; - } - - *vertices = (Evas_Vec3*)malloc(*count * sizeof(Evas_Vec3)); - it = *vertices; - if (!*vertices) - { - ERR("Not enough memory."); - return; - } - - EINA_LIST_FOREACH(m, l, mesh) - { - eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); - mpd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); - f = evas_3d_mesh_frame_find(mpd, frame); - if (f) + const Eina_List *m, *l; + Evas_3D_Mesh *mesh; + int j; + int frame; + Evas_Vec3 *it; + Evas_3D_Vertex_Buffer pos0, pos1; + Evas_Real pos_weight; + + *count = 0; + eo_do(node, m = (Eina_List *)evas_3d_node_mesh_list_get()); + EINA_LIST_FOREACH(m, l, mesh) + { + eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); + evas_3d_mesh_interpolate_vertex_buffer_get(mesh, frame, EVAS_3D_VERTEX_POSITION, + &pos0, &pos1, &pos_weight); + if(!pos0.data) continue; + if(!pos0.stride) + { + *count += pos0.size / (sizeof(float) * 3); + } + else + { + *count += pos0.size / pos0.stride; + } + } + *vertices = (Evas_Vec3*)malloc(*count * sizeof(Evas_Vec3)); + it = *vertices; + if(!*vertices) + { + ERR("Not enough memory."); + return; + } + + EINA_LIST_FOREACH(m, l, mesh) + { + eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); + evas_3d_mesh_interpolate_vertex_buffer_get(mesh, frame, EVAS_3D_VERTEX_POSITION, + &pos0, &pos1, &pos_weight); + if(!pos0.data) continue; + int stride = 0; + if(!pos0.stride) + { + stride = sizeof(float) * 3; + } + else { - float *src = (float *)f->vertices[EVAS_3D_VERTEX_POSITION].data; - if (!src) continue; - int stride = f->vertices[EVAS_3D_VERTEX_POSITION].stride; - if (!stride) stride = sizeof(float) * 3; - for (j = 0; j < mpd->vertex_count; j++) - { - it->x = src[0]; - it->y = src[1]; - it->z = src[2]; - it++; - src = (float *)((char *)src + stride); - } + stride = pos0.stride; } - } + for (j = 0; j < pos0.size / stride; j++) + { + evas_3d_mesh_interpolate_position_get(it, &pos0, &pos1, pos_weight, j); + it++; + } + } } static void diff --git a/src/lib/evas/canvas/evas_3d_scene.c b/src/lib/evas/canvas/evas_3d_scene.c index 6784c990a1..c4bfbcf253 100644 --- a/src/lib/evas/canvas/evas_3d_scene.c +++ b/src/lib/evas/canvas/evas_3d_scene.c @@ -225,43 +225,6 @@ _pick_data_triangle_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, } static inline void -_position_get(Evas_Vec3 *out, const Evas_3D_Vertex_Buffer *pos0, const Evas_3D_Vertex_Buffer *pos1, - Evas_Real weight, int index) -{ - if (pos1->data == NULL) - { - float *ptr; - - if (pos0->stride != 0.0) - ptr = (float *)((char *)pos0->data + pos0->stride * index); - else - ptr = (float *)((char *)pos0->data + (3 * sizeof(float)) * index); - - out->x = ptr[0]; - out->y = ptr[1]; - out->z = ptr[2]; - } - else - { - float *ptr0, *ptr1; - - if (pos0->stride != 0.0) - ptr0 = (float *)((char *)pos0->data + pos0->stride * index); - else - ptr0 = (float *)((char *)pos0->data + (3 * sizeof(float)) * index); - - if (pos1->stride != 0.0) - ptr1 = (float *)((char *)pos1->data + pos1->stride * index); - else - ptr1 = (float *)((char *)pos1->data + (3 * sizeof(float)) * index); - - out->x = ptr0[0] * weight + ptr1[0] * (1.0 - weight); - out->y = ptr0[1] * weight + ptr1[1] * (1.0 - weight); - out->z = ptr0[2] * weight + ptr1[2] * (1.0 - weight); - } -} - -static inline void _pick_data_texcoord_update(Evas_3D_Pick_Data *data, const Evas_3D_Vertex_Buffer *tex0, const Evas_3D_Vertex_Buffer *tex1, Evas_Real weight, unsigned int i0, unsigned int i1, unsigned int i2) @@ -357,9 +320,9 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, i2 = ((unsigned char *)pdmesh->indices)[i + 2]; } - _position_get(&tri.p0, &pos0, &pos1, pos_weight, i0); - _position_get(&tri.p1, &pos0, &pos1, pos_weight, i1); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, i0); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, i1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -383,8 +346,8 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, i2 = ((unsigned char *)pdmesh->indices)[1]; } - _position_get(&tri.p1, &pos0, &pos1, pos_weight, i1); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, i1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); for (i = 0; i < pdmesh->index_count - 2; i++) { @@ -396,7 +359,7 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, else i2 = ((unsigned char *)pdmesh->indices)[i + 2]; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -431,8 +394,8 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, i2 = ((unsigned char *)pdmesh->indices)[1]; } - _position_get(&tri.p0, &pos0, &pos1, pos_weight, i0); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, i0); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); for (i = 1; i < pdmesh->index_count - 1; i++) { @@ -443,7 +406,7 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, else i2 = ((unsigned char *)pdmesh->indices)[i + 1]; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -466,9 +429,9 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, { for (i = 0; i < pdmesh->index_count; i += 3) { - _position_get(&tri.p0, &pos0, &pos1, pos_weight, i); - _position_get(&tri.p1, &pos0, &pos1, pos_weight, i + 1); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, i); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, i + 1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -481,15 +444,15 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, } else if (pdmesh->assembly == EVAS_3D_VERTEX_ASSEMBLY_TRIANGLE_STRIP) { - _position_get(&tri.p1, &pos0, &pos1, pos_weight, 0); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, 0); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); for (i = 0; i < pdmesh->index_count - 2; i++) { tri.p0 = tri.p1; tri.p1 = tri.p2; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -502,14 +465,14 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, } else if (pdmesh->assembly == EVAS_3D_VERTEX_ASSEMBLY_TRIANGLE_FAN) { - _position_get(&tri.p0, &pos0, &pos1, pos_weight, 0); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, 0); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); for (i = 1; i < pdmesh->index_count - 1; i++) { tri.p1 = tri.p2; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 1); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -527,9 +490,9 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, { for (i = 0; i < pdmesh->vertex_count; i += 3) { - _position_get(&tri.p0, &pos0, &pos1, pos_weight, i); - _position_get(&tri.p1, &pos0, &pos1, pos_weight, i + 1); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, i); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, i + 1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -542,15 +505,15 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, } else if (pdmesh->assembly == EVAS_3D_VERTEX_ASSEMBLY_TRIANGLE_STRIP) { - _position_get(&tri.p1, &pos0, &pos1, pos_weight, 0); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); + evas_3d_mesh_interpolate_position_get(&tri.p1, &pos0, &pos1, pos_weight, 0); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); for (i = 0; i < pdmesh->vertex_count - 2; i++) { tri.p0 = tri.p1; tri.p1 = tri.p2; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 2); if (_pick_data_triangle_add(data, ray, &tri)) { @@ -563,14 +526,14 @@ _pick_data_mesh_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray, } else if (pdmesh->assembly == EVAS_3D_VERTEX_ASSEMBLY_TRIANGLE_FAN) { - _position_get(&tri.p0, &pos0, &pos1, pos_weight, 0); - _position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); + evas_3d_mesh_interpolate_position_get(&tri.p0, &pos0, &pos1, pos_weight, 0); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, 1); for (i = 1; i < pdmesh->vertex_count - 1; i++) { tri.p1 = tri.p2; - _position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 1); + evas_3d_mesh_interpolate_position_get(&tri.p2, &pos0, &pos1, pos_weight, i + 1); if (_pick_data_triangle_add(data, ray, &tri)) { diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 4464a60acf..52feb58367 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1720,6 +1720,7 @@ void evas_3d_light_node_del(Evas_3D_Light *light, Evas_3D_Node *node); /* Mesh functions. */ void evas_3d_mesh_node_add(Evas_3D_Mesh *mesh, Evas_3D_Node *node); void evas_3d_mesh_node_del(Evas_3D_Mesh *mesh, Evas_3D_Node *node); +void evas_3d_mesh_interpolate_position_get(Evas_Vec3 *out, const Evas_3D_Vertex_Buffer *pos0, const Evas_3D_Vertex_Buffer *pos1, Evas_Real weight, int index); void evas_3d_mesh_interpolate_vertex_buffer_get(Evas_3D_Mesh *mesh, int frame, Evas_3D_Vertex_Attrib attrib, Evas_3D_Vertex_Buffer *buffer0, Evas_3D_Vertex_Buffer *buffer1, Evas_Real *weight); void evas_3d_mesh_file_md2_set(Evas_3D_Mesh *mesh, const char *file); void evas_3d_mesh_save_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f); |