diff options
-rw-r--r-- | intern/cycles/render/geometry.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/geometry.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 1 |
4 files changed, 14 insertions, 13 deletions
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index e9a70e4b3fd..60a6f598ed2 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -1917,9 +1917,12 @@ void GeometryManager::device_update(Device *device, } } - /* update the bvh even when there is no geometry so the kernel bvh data is still valid, - * especially when removing all of the objects during interactive renders */ - bool need_update_scene_bvh = (scene->bvh == nullptr); + /* Update the BVH even when there is no geometry so the kernel's BVH data is still valid, + * especially when removing all of the objects during interactive renders. + * Also update the BVH if the transformations change, we cannot rely on tagging the Geometry + * as modified in this case, as we may accumulate displacement if the vertices do not also + * change. */ + bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & TRANSFORM_MODIFIED) != 0); { scoped_callback_timer timer([scene](double time) { if (scene->update_stats) { diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h index fe30f3a807c..abdd851a089 100644 --- a/intern/cycles/render/geometry.h +++ b/intern/cycles/render/geometry.h @@ -189,6 +189,8 @@ class GeometryManager { GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED, GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED, + TRANSFORM_MODIFIED = (1 << 10), + /* tag everything in the manager for an update */ UPDATE_ALL = ~0u, diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index e71d7d4a3eb..52f63685aeb 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -221,16 +221,7 @@ void Object::tag_update(Scene *scene) if (geometry) { if (tfm_is_modified()) { - /* tag the geometry as modified so the BVH is updated, but do not tag everything as modified - */ - if (geometry->is_mesh() || geometry->is_volume()) { - Mesh *mesh = static_cast<Mesh *>(geometry); - mesh->tag_verts_modified(); - } - else if (geometry->is_hair()) { - Hair *hair = static_cast<Hair *>(geometry); - hair->tag_curve_keys_modified(); - } + flag |= ObjectManager::TRANSFORM_MODIFIED; } foreach (Node *node, geometry->get_used_shaders()) { @@ -923,6 +914,10 @@ void ObjectManager::tag_update(Scene *scene, uint32_t flag) geometry_flag |= (GeometryManager::GEOMETRY_ADDED | GeometryManager::GEOMETRY_REMOVED); } + if ((flag & TRANSFORM_MODIFIED) != 0) { + geometry_flag |= GeometryManager::TRANSFORM_MODIFIED; + } + scene->geometry_manager->tag_update(scene, geometry_flag); } diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index cf1b9ca510a..23682270fd1 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -133,6 +133,7 @@ class ObjectManager { OBJECT_REMOVED = (1 << 4), OBJECT_MODIFIED = (1 << 5), HOLDOUT_MODIFIED = (1 << 6), + TRANSFORM_MODIFIED = (1 << 7), /* tag everything in the manager for an update */ UPDATE_ALL = ~0u, |