evas: for aabb add interpolation frame when base frame is not found

Summary:
Old algorithm searched specified frame of the base frame and when it could not find the specified frame it ignored. So the bounding box was not synchronized with the object.
New algorithm always returns specified base frame or frame interpolation between the nearest base frames. That does synchronizes mesh object and his bounding box.

Reviewers: Hermet, cedric

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D2594

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Ivan Furs 2015-06-03 16:34:45 +02:00 committed by Cedric BAIL
parent 69e44c24e3
commit a88aebe8cc
4 changed files with 120 additions and 113 deletions

View File

@ -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)
{

View File

@ -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;
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));
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;
}
*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;
}
*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)
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

View File

@ -224,43 +224,6 @@ _pick_data_triangle_add(Evas_3D_Pick_Data *data, const Evas_Ray3 *ray,
return EINA_FALSE;
}
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,
@ -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))
{

View File

@ -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);