diff options
author | Dmytro Dadyka <d.dadyka@samsung.com> | 2015-02-17 15:33:05 +0100 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2015-02-17 15:39:48 +0100 |
commit | 1c74a1afe2d6353931ad4bab55a5ecbbd270b10a (patch) | |
tree | 1eb9a7d88e26dde429fecd7fdc6134138ed79e61 /src | |
parent | 88932d3645ebcd5b52a3b133479f599006e5ab5b (diff) |
evas: Evas_3D - refactor node shapes update mechanism.
Reviewers: cedric
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1984
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/evas/canvas/evas_3d_node.c | 389 | ||||
-rw-r--r-- | src/lib/evas/include/evas_3d_utils.h | 9 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 3 |
3 files changed, 233 insertions, 168 deletions
diff --git a/src/lib/evas/canvas/evas_3d_node.c b/src/lib/evas/canvas/evas_3d_node.c index 62e2c1cb01..87de24801b 100644 --- a/src/lib/evas/canvas/evas_3d_node.c +++ b/src/lib/evas/canvas/evas_3d_node.c | |||
@@ -248,198 +248,251 @@ _node_item_update(Evas_3D_Node *node, void *data EINA_UNUSED) | |||
248 | return EINA_TRUE; | 248 | return EINA_TRUE; |
249 | } | 249 | } |
250 | 250 | ||
251 | static Eina_Bool | 251 | static void |
252 | _node_aabb_update(Evas_3D_Node *node, void *data EINA_UNUSED) | 252 | _rotate_vertices(Evas_Vec4* orientation, int vertex_count, Evas_Vec3* vertex_position) |
253 | { | 253 | { |
254 | Evas_3D_Node_Data *pd = eo_data_scope_get(node, EVAS_3D_NODE_CLASS); | 254 | int i; |
255 | Eina_Bool transform_dirty = EINA_FALSE, mesh_geom_dirty = EINA_FALSE; | 255 | if (orientation->x || orientation->y || orientation->z) |
256 | Eina_Bool mesh_frame_dirty = EINA_FALSE, member_dirty = EINA_FALSE; | 256 | for (i = 0; i < vertex_count; i++) |
257 | Eina_Bool frame_found = EINA_FALSE, is_change_orientation = EINA_FALSE; | 257 | evas_vec3_quaternion_rotate(&vertex_position[i], &vertex_position[i], orientation); |
258 | const Eina_List *m, *l; | 258 | } |
259 | Evas_3D_Mesh *mesh; | ||
260 | int frame, count, size, i, j; | ||
261 | Evas_3D_Mesh_Frame *f; | ||
262 | float minx, miny, minz, maxx, maxy, maxz, vxmin, vymin, vzmin, vxmax, vymax, vzmax; | ||
263 | float *minmaxdata; | ||
264 | Evas_Vec4 orientation = {0}; | ||
265 | Evas_Box3 box3; | ||
266 | 259 | ||
267 | eo_do(node, | 260 | static void |
268 | transform_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_POSITION), | 261 | _scale_vertices(Evas_Vec3* scale, int vertex_count, Evas_Vec3* vertex_position) |
269 | transform_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_ORIENTATION), | 262 | { |
270 | transform_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_SCALE), | 263 | int i; |
271 | transform_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_ORIENTATION), | 264 | if ((scale->x != 1) || (scale->y != 1) || (scale->z != 1)) |
272 | transform_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_POSITION), | 265 | for (i = 0; i < vertex_count; i++) |
273 | transform_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_SCALE), | 266 | evas_vec3_multiply(&vertex_position[i], &vertex_position[i], scale); |
274 | mesh_geom_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_GEOMETRY), | 267 | } |
275 | mesh_frame_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_FRAME), | ||
276 | member_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MEMBER)); | ||
277 | 268 | ||
278 | if (transform_dirty || | 269 | static void |
279 | mesh_geom_dirty || | 270 | _calculate_sphere(Evas_Sphere *sphere, int vertex_count, Evas_Vec3 *vertex_position) |
280 | mesh_frame_dirty || | 271 | { |
281 | member_dirty) | 272 | float radius = 0.0001f; |
282 | { | 273 | Evas_Vec3 center, pos, diff; |
283 | if (pd->type == EVAS_3D_NODE_TYPE_MESH) | 274 | float len, alpha, alpha2; |
284 | { | 275 | int i, k; |
285 | 276 | ||
286 | if (pd->orientation_world.x || pd->orientation_world.y || pd->orientation_world.z) | 277 | // shuffle array for averaging algorithms error |
287 | { | 278 | for (i = 0; i < vertex_count; i++) |
288 | evas_vec4_set(&orientation, pd->orientation_world.x, pd->orientation_world.y, pd->orientation_world.z, pd->orientation_world.w); | 279 | { |
289 | is_change_orientation = EINA_TRUE; | 280 | k = i + rand()%(vertex_count-i); |
290 | } | 281 | pos = vertex_position[i]; |
282 | vertex_position[i] = vertex_position[k]; | ||
283 | vertex_position[k] = pos; | ||
284 | } | ||
291 | 285 | ||
292 | eo_do (node, m = (Eina_List *)evas_3d_node_mesh_list_get()); | 286 | center = vertex_position[0]; |
293 | 287 | ||
294 | EINA_LIST_FOREACH(m, l, mesh) | 288 | for (k = 0; k < 2; k++) |
289 | { | ||
290 | for (i = 0; i < vertex_count; ++i) | ||
291 | { | ||
292 | pos = vertex_position[i]; | ||
293 | evas_vec3_subtract(&diff, &pos, ¢er); | ||
294 | len = evas_vec3_length_get(&diff); | ||
295 | if (len > radius) | ||
295 | { | 296 | { |
296 | eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); | 297 | alpha = len / radius; |
297 | Evas_3D_Mesh_Data *mpd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); | 298 | alpha2 = alpha * alpha; |
298 | f = evas_3d_mesh_frame_find(mpd, frame); | 299 | radius = 0.5f * (alpha + 1 / alpha) * radius; |
299 | 300 | evas_vec3_scale(&pos, &pos, 1 - 1 / alpha2); | |
300 | if (f) | 301 | evas_vec3_scale(¢er, ¢er, (1 + 1 / alpha2)); |
301 | { | 302 | evas_vec3_add(¢er, ¢er, &pos); |
302 | i = 0, j = 0; | 303 | evas_vec3_scale(¢er, ¢er, 0.5f); |
304 | } | ||
305 | } | ||
306 | } | ||
303 | 307 | ||
304 | evas_box3_empty_set(&box3); | 308 | for (i = 0; i < vertex_count; ++i) |
305 | count = f->vertices[EVAS_3D_VERTEX_POSITION].element_count; | 309 | { |
306 | size = f->vertices[EVAS_3D_VERTEX_POSITION].size; | 310 | pos = vertex_position[i]; |
307 | if (!size) size = count * sizeof(float) * mpd->vertex_count; | 311 | evas_vec3_subtract(&diff, &pos, ¢er); |
308 | minmaxdata = (float *)malloc(size); | 312 | len = evas_vec3_length_get(&diff); |
309 | 313 | ||
310 | if (!minmaxdata) | 314 | if (len > radius) |
311 | { | 315 | { |
312 | ERR("Not enough memory."); | 316 | radius = (radius + len) / 2.0f; |
313 | return EINA_FALSE; | 317 | evas_vec3_scale(&diff, &diff, (len - radius) / len); |
314 | } | 318 | evas_vec3_add(¢er, ¢er, &diff); |
319 | } | ||
320 | } | ||
315 | 321 | ||
316 | memcpy(minmaxdata, f->vertices[EVAS_3D_VERTEX_POSITION].data, size); | 322 | sphere->radius = radius; |
323 | sphere->center = center; | ||
324 | } | ||
317 | 325 | ||
318 | /*get current coordinates, set orientation and find min/max*/ | 326 | static void |
319 | if (is_change_orientation) | 327 | _calculate_box(Evas_Box3 *box3, int vertex_count, Evas_Vec3 *vertex_position) |
320 | { | 328 | { |
321 | Evas_Vec3 rotate; | 329 | int i = 0; |
322 | evas_vec3_set(&rotate, minmaxdata[0], minmaxdata[1], minmaxdata[2]); | 330 | float vxmin, vymin, vzmin, vxmax, vymax, vzmax; |
323 | evas_vec3_quaternion_rotate(&rotate, &rotate, &orientation); | ||
324 | vxmax = vxmin = minmaxdata[0] = rotate.x; | ||
325 | vymax = vymin = minmaxdata[1] = rotate.y; | ||
326 | vzmax = vzmin = minmaxdata[2] = rotate.z; | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | vxmax = vxmin = minmaxdata[0]; | ||
331 | vymax = vymin = minmaxdata[1]; | ||
332 | vzmax = vzmin = minmaxdata[2]; | ||
333 | } | ||
334 | 331 | ||
335 | j += count; | 332 | vxmax = vxmin = vertex_position[0].x; |
333 | vymax = vymin = vertex_position[0].y; | ||
334 | vzmax = vzmin = vertex_position[0].z; | ||
336 | 335 | ||
337 | if (is_change_orientation) | 336 | for (i = 1; i < vertex_count; ++i) |
338 | { | 337 | { |
339 | for (i = 1; i < mpd->vertex_count; ++i) | 338 | if (vxmin > vertex_position[i].x) vxmin = vertex_position[i].x; |
340 | { | 339 | if (vxmax < vertex_position[i].x) vxmax = vertex_position[i].x; |
341 | Evas_Vec3 rotate; | 340 | if (vymin > vertex_position[i].y) vymin = vertex_position[i].y; |
342 | evas_vec3_set(&rotate, minmaxdata[j], minmaxdata[j + 1], minmaxdata[j + 2]); | 341 | if (vymax < vertex_position[i].y) vymax = vertex_position[i].y; |
343 | evas_vec3_quaternion_rotate(&rotate, &rotate, &orientation); | 342 | if (vzmin > vertex_position[i].z) vzmin = vertex_position[i].z; |
344 | minmaxdata[j] = rotate.x; | 343 | if (vzmax < vertex_position[i].z) vzmax = vertex_position[i].z; |
345 | minmaxdata[j + 1] = rotate.y; | 344 | } |
346 | minmaxdata[j + 2] = rotate.z; | 345 | evas_box3_set(box3, vxmin, vymin, vzmin, vxmax, vymax, vzmax); |
347 | vxmin > minmaxdata[j] ? vxmin = minmaxdata[j] : 0; | 346 | } |
348 | vxmax < minmaxdata[j] ? vxmax = minmaxdata[j] : 0; | ||
349 | vymin > minmaxdata[j + 1] ? vymin = minmaxdata[j + 1] : 0; | ||
350 | vymax < minmaxdata[j + 1] ? vymax = minmaxdata[j + 1] : 0; | ||
351 | vzmin > minmaxdata[j + 2] ? vzmin = minmaxdata[j + 2] : 0; | ||
352 | vzmax < minmaxdata[j + 2] ? vzmax = minmaxdata[j + 2] : 0; | ||
353 | j += count; | ||
354 | } | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | for (i = 1; i < mpd->vertex_count; ++i) | ||
359 | { | ||
360 | vxmin > minmaxdata[j] ? vxmin = minmaxdata[j] : 0; | ||
361 | vxmax < minmaxdata[j] ? vxmax = minmaxdata[j] : 0; | ||
362 | vymin > minmaxdata[j + 1] ? vymin = minmaxdata[j + 1] : 0; | ||
363 | vymax < minmaxdata[j + 1] ? vymax = minmaxdata[j + 1] : 0; | ||
364 | vzmin > minmaxdata[j + 2] ? vzmin = minmaxdata[j + 2] : 0; | ||
365 | vzmax < minmaxdata[j + 2] ? vzmax = minmaxdata[j + 2] : 0; | ||
366 | j += count; | ||
367 | } | ||
368 | } | ||
369 | 347 | ||
370 | if (!frame_found) | 348 | static void |
371 | { | 349 | _pack_meshes_vertex_data(Evas_3D_Node *node, Evas_Vec3 **vertices, int *count) |
372 | evas_box3_empty_set(&pd->aabb); | 350 | { |
373 | evas_box3_empty_set(&pd->obb); | 351 | const Eina_List *m, *l; |
374 | minx = vxmin; | 352 | Evas_3D_Mesh *mesh; |
375 | miny = vymin; | 353 | Evas_3D_Mesh_Frame *f; |
376 | minz = vzmin; | 354 | int j; |
377 | maxx = vxmax; | 355 | int frame; |
378 | maxy = vymax; | 356 | Evas_3D_Mesh_Data *mpd; |
379 | maxz = vzmax; | 357 | Evas_Vec3 *it; |
380 | } | 358 | |
381 | else | 359 | *count = 0; |
382 | { | 360 | eo_do(node, m = (Eina_List *)evas_3d_node_mesh_list_get()); |
383 | minx > vxmin ? minx = vxmin : 0; | 361 | EINA_LIST_FOREACH(m, l, mesh) |
384 | maxx < vxmax ? maxx = vxmax : 0; | 362 | { |
385 | miny > vymin ? miny = vymin : 0; | 363 | eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); |
386 | maxy < vymax ? maxy = vymax : 0; | 364 | mpd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); |
387 | minz > vzmin ? minz = vzmin : 0; | 365 | f = evas_3d_mesh_frame_find(mpd, frame); |
388 | maxz < vzmax ? maxz = vzmax : 0; | 366 | if (f) *count += mpd->vertex_count; |
389 | } | 367 | } |
390 | 368 | ||
391 | frame_found = EINA_TRUE; | 369 | *vertices = (Evas_Vec3*)malloc(*count * sizeof(Evas_Vec3)); |
392 | free(minmaxdata); | 370 | it = *vertices; |
393 | evas_box3_set(&box3, minx, miny, minz, maxx, maxy, maxz); | 371 | if (!*vertices) |
394 | evas_box3_union(&pd->aabb, &pd->aabb, &box3); | 372 | { |
395 | evas_box3_union(&pd->obb, &pd->obb, &f->aabb); | 373 | ERR("Not enough memory."); |
396 | } | 374 | return; |
397 | } | 375 | } |
398 | 376 | ||
399 | if (frame_found) | 377 | EINA_LIST_FOREACH(m, l, mesh) |
378 | { | ||
379 | eo_do(node, frame = evas_3d_node_mesh_frame_get(mesh)); | ||
380 | mpd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); | ||
381 | f = evas_3d_mesh_frame_find(mpd, frame); | ||
382 | if (f) | ||
383 | { | ||
384 | float *src = (float *)f->vertices[EVAS_3D_VERTEX_POSITION].data; | ||
385 | int stride = f->vertices[EVAS_3D_VERTEX_POSITION].stride; | ||
386 | if (!stride) stride = sizeof(float) * 3; | ||
387 | for (j = 0; j < mpd->vertex_count; j++) | ||
400 | { | 388 | { |
401 | if ((pd->scale_world.x != 1 || pd->scale_world.y != 1 || pd->scale_world.z != 1)) | 389 | it->x = src[0]; |
402 | { | 390 | it->y = src[1]; |
403 | Evas_Vec3 scale; | 391 | it->z = src[2]; |
404 | evas_vec3_set(&scale, pd->scale_world.x, pd->scale_world.y, pd->scale_world.z); | 392 | it++; |
405 | evas_vec3_multiply(&pd->obb.p0, &scale, &pd->obb.p0); | 393 | src = (float *)((char *)src + stride); |
406 | evas_vec3_multiply(&pd->obb.p1, &scale, &pd->obb.p1); | ||
407 | evas_vec3_multiply(&pd->aabb.p0, &scale, &pd->aabb.p0); | ||
408 | evas_vec3_multiply(&pd->aabb.p1, &scale, &pd->aabb.p1); | ||
409 | } | ||
410 | if (is_change_orientation) | ||
411 | { | ||
412 | evas_vec3_quaternion_rotate(&pd->obb.p0, &pd->obb.p0, &orientation); | ||
413 | evas_vec3_quaternion_rotate(&pd->obb.p1, &pd->obb.p1, &orientation); | ||
414 | } | ||
415 | if ((pd->position_world.x || pd->position_world.y || pd->position_world.z)) | ||
416 | { | ||
417 | Evas_Vec3 position; | ||
418 | evas_vec3_set(&position, pd->position_world.x, pd->position_world.y, pd->position_world.z); | ||
419 | evas_vec3_add(&pd->obb.p0, &position, &pd->obb.p0); | ||
420 | evas_vec3_add(&pd->obb.p1, &position, &pd->obb.p1); | ||
421 | evas_vec3_add(&pd->aabb.p0, &position, &pd->aabb.p0); | ||
422 | evas_vec3_add(&pd->aabb.p1, &position, &pd->aabb.p1); | ||
423 | } | ||
424 | } | 394 | } |
425 | } | 395 | } |
426 | else | 396 | } |
427 | { | 397 | } |
428 | Eina_List *current; | ||
429 | Evas_3D_Node *datanode; | ||
430 | 398 | ||
431 | /* Update AABB, OBB, bounding sphere of this node. */ | 399 | static void |
432 | evas_box3_empty_set(&pd->aabb); | 400 | _update_node_shapes(Evas_3D_Node *node) |
433 | evas_box3_empty_set(&pd->obb); | 401 | { |
402 | Evas_3D_Node_Data *pd = eo_data_scope_get(node, EVAS_3D_NODE_CLASS); | ||
403 | Eina_Bool transform_orientation_dirty; | ||
404 | Eina_Bool transform_scale_dirty; | ||
405 | Eina_Bool mesh_geom_dirty; | ||
406 | Evas_Vec3 scale; | ||
407 | Evas_Vec3 position = pd->position_world; | ||
408 | evas_vec3_set(&scale, pd->scale_world.x, pd->scale.y, pd->scale.z); | ||
434 | 409 | ||
435 | EINA_LIST_FOREACH(pd->members, current, datanode) | 410 | if (pd->type != EVAS_3D_NODE_TYPE_MESH) |
411 | { | ||
412 | evas_box3_empty_set(&pd->local_aabb); | ||
413 | evas_box3_empty_set(&pd->local_obb); | ||
414 | pd->local_bsphere.radius = 0; | ||
415 | evas_vec3_set(&pd->local_bsphere.center, 0, 0, 0); | ||
416 | |||
417 | pd->aabb.p0 = position; | ||
418 | pd->aabb.p1 = position; | ||
419 | pd->obb.p0 = position; | ||
420 | pd->obb.p1 = position; | ||
421 | pd->bsphere.radius = 0; | ||
422 | pd->bsphere.center = position; | ||
423 | return; | ||
424 | } | ||
425 | |||
426 | eo_do(node, | ||
427 | transform_orientation_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_ORIENTATION), | ||
428 | transform_orientation_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_ORIENTATION), | ||
429 | transform_scale_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_SCALE), | ||
430 | transform_scale_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_SCALE), | ||
431 | mesh_geom_dirty = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_GEOMETRY), | ||
432 | mesh_geom_dirty |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_FRAME)); | ||
433 | |||
434 | if ( transform_orientation_dirty || transform_scale_dirty || mesh_geom_dirty) | ||
435 | { | ||
436 | int count; | ||
437 | Evas_Vec3 *vertices = NULL; | ||
438 | _pack_meshes_vertex_data(node, &vertices, &count); | ||
439 | if (count > 0) | ||
440 | { | ||
441 | _scale_vertices(&pd->scale_world, count, vertices); | ||
442 | if (mesh_geom_dirty) | ||
443 | _calculate_box(&pd->local_obb, count, vertices); | ||
444 | |||
445 | if (transform_scale_dirty || mesh_geom_dirty) | ||
446 | { | ||
447 | _calculate_sphere(&pd->local_bsphere, count, vertices); | ||
448 | } | ||
449 | if (transform_orientation_dirty || mesh_geom_dirty) | ||
436 | { | 450 | { |
437 | Evas_3D_Node_Data *datapd = eo_data_scope_get(datanode, EVAS_3D_NODE_CLASS); | 451 | _rotate_vertices(&pd->orientation_world, count, vertices); |
438 | evas_box3_union(&pd->obb, &pd->obb, &datapd->obb); | 452 | _calculate_box(&pd->local_aabb, count, vertices); |
439 | evas_box3_union(&pd->aabb, &pd->aabb, &datapd->aabb); | ||
440 | } | 453 | } |
454 | free(vertices); | ||
441 | } | 455 | } |
442 | evas_build_sphere(&pd->obb, &pd->bsphere); | 456 | } |
457 | |||
458 | pd->bsphere.radius = pd->local_bsphere.radius; | ||
459 | evas_vec3_quaternion_rotate(&pd->bsphere.center, &pd->local_bsphere.center, &pd->orientation_world); | ||
460 | evas_vec3_add(&pd->obb.p0, &position, &pd->local_obb.p0); | ||
461 | evas_vec3_add(&pd->obb.p1, &position, &pd->local_obb.p1); | ||
462 | evas_vec3_add(&pd->aabb.p0, &position, &pd->local_aabb.p0); | ||
463 | evas_vec3_add(&pd->aabb.p1, &position, &pd->local_aabb.p1); | ||
464 | evas_vec3_add(&pd->bsphere.center, &position, &pd->bsphere.center); | ||
465 | } | ||
466 | |||
467 | static Eina_Bool | ||
468 | _node_aabb_update(Evas_3D_Node *node, void *data EINA_UNUSED) | ||
469 | { | ||
470 | Evas_3D_Node_Data *pd = eo_data_scope_get(node, EVAS_3D_NODE_CLASS); | ||
471 | Eina_Bool need_recalc; | ||
472 | Eina_List *current; | ||
473 | Evas_3D_Node *datanode; | ||
474 | |||
475 | eo_do(node, | ||
476 | need_recalc = evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_ORIENTATION), | ||
477 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_ORIENTATION), | ||
478 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_POSITION), | ||
479 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_POSITION), | ||
480 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_TRANSFORM_SCALE), | ||
481 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_PARENT_SCALE), | ||
482 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_GEOMETRY), | ||
483 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MESH_FRAME), | ||
484 | need_recalc |= evas_3d_object_dirty_get(EVAS_3D_STATE_NODE_MEMBER)); | ||
485 | |||
486 | if (!need_recalc) return EINA_TRUE; | ||
487 | |||
488 | _update_node_shapes(node); | ||
489 | |||
490 | EINA_LIST_FOREACH(pd->members, current, datanode) | ||
491 | { | ||
492 | Evas_3D_Node_Data *datapd = eo_data_scope_get(datanode, EVAS_3D_NODE_CLASS); | ||
493 | evas_box3_union(&pd->obb, &pd->obb, &datapd->obb); | ||
494 | evas_box3_union(&pd->aabb, &pd->aabb, &datapd->aabb); | ||
495 | evas_build_sphere(&pd->aabb, &pd->bsphere); | ||
443 | } | 496 | } |
444 | 497 | ||
445 | return EINA_TRUE; | 498 | return EINA_TRUE; |
diff --git a/src/lib/evas/include/evas_3d_utils.h b/src/lib/evas/include/evas_3d_utils.h index 0cf9f34928..6f7f477a77 100644 --- a/src/lib/evas/include/evas_3d_utils.h +++ b/src/lib/evas/include/evas_3d_utils.h | |||
@@ -1764,6 +1764,15 @@ evas_build_sphere(const Evas_Box3 *box, Evas_Sphere *sphere) | |||
1764 | } | 1764 | } |
1765 | 1765 | ||
1766 | static inline void | 1766 | static inline void |
1767 | evas_sphere_empty_set(Evas_Sphere *dst) | ||
1768 | { | ||
1769 | dst->radius = 0; | ||
1770 | dst->center.x = 0; | ||
1771 | dst->center.y = 0; | ||
1772 | dst->center.z = 0; | ||
1773 | } | ||
1774 | |||
1775 | static inline void | ||
1767 | evas_plane_normalize(Evas_Vec4 *plane) | 1776 | evas_plane_normalize(Evas_Vec4 *plane) |
1768 | { | 1777 | { |
1769 | Evas_Vec3 tmp; | 1778 | Evas_Vec3 tmp; |
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 5f69b22d41..4f4ada41c0 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h | |||
@@ -225,6 +225,9 @@ struct _Evas_3D_Node | |||
225 | Evas_Box3 aabb; | 225 | Evas_Box3 aabb; |
226 | Evas_Box3 obb; | 226 | Evas_Box3 obb; |
227 | Evas_Sphere bsphere; | 227 | Evas_Sphere bsphere; |
228 | Evas_Box3 local_aabb; | ||
229 | Evas_Box3 local_obb; | ||
230 | Evas_Sphere local_bsphere; | ||
228 | 231 | ||
229 | Evas_3D_Node_Type type; | 232 | Evas_3D_Node_Type type; |
230 | 233 | ||