diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index db6311c3d97..42103396b53 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -1032,11 +1032,15 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen if(!need_update) return; - /* update normals */ + /* update normals and flags */ foreach(Mesh *mesh, scene->meshes) { + mesh->has_volume = false; foreach(uint shader, mesh->used_shaders) { if(scene->shaders[shader]->need_update_attributes) mesh->need_update = true; + if(scene->shaders[shader]->has_volume) { + mesh->has_volume = true; + } } if(mesh->need_update) { @@ -1105,37 +1109,10 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen bool motion_blur = false; #endif - /* TODO(sergey): There's an ongoing fake cyclic dependency between objects - * and meshes here -- needs to make update functions a bit more granular in - * order to keep all the updates in a logical way. - */ - /* update obejcts */ vector volume_objects; - foreach(Object *object, scene->objects) { + foreach(Object *object, scene->objects) object->compute_bounds(motion_blur); - if(object->mesh->has_volume) { - volume_objects.push_back(object); - } - } - - int object_index = 0; - uint *object_flags = dscene->object_flag.get_data(); - foreach(Object *object, scene->objects) { - foreach(Object *volume_object, volume_objects) { - if(object == volume_object) { - continue; - } - if(object->bounds.intersects(volume_object->bounds)) { - object_flags[object_index] |= SD_OBJECT_INTERSECTS_VOLUME; - break; - } - } - ++object_index; - } - - /* allocate object flag */ - device->tex_alloc("__object_flag", dscene->object_flag); if(progress.get_cancel()) return; diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 986a36ba120..46ddab235d9 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -348,27 +348,9 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], __int_as_float(numkeys)); objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], __int_as_float(numsteps), __int_as_float(numverts)); - /* That's a bit weird place to update mesh flags, but we do it here - * because object needs to know if it's a volume or not and mesh needs - * to have the updated. - * - * TODO(sergey): Check on whether we can reshuffle update order in scene. - */ - if(ob->mesh->need_update) { - ob->mesh->has_volume = false; - foreach(uint shader, ob->mesh->used_shaders) { - if(scene->shaders[shader]->has_volume) { - ob->mesh->has_volume = true; - break; - } - } - } - /* object flag */ if(ob->use_holdout) flag |= SD_HOLDOUT_MASK; - if(ob->mesh->has_volume) - flag |= SD_OBJECT_HAS_VOLUME; object_flag[i] = flag; /* have curves */ @@ -396,8 +378,6 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc device_free(device, dscene); - need_update = false; - if(scene->objects.size() == 0) return; @@ -418,6 +398,49 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc } } +void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene, + Scene *scene, Progress& progress) +{ + if(!need_update) + return; + + need_update = false; + + if(scene->objects.size() == 0) + return; + + /* object info flag */ + uint *object_flag = dscene->object_flag.get_data(); + + vector volume_objects; + foreach(Object *object, scene->objects) { + if(object->mesh->has_volume) { + volume_objects.push_back(object); + } + } + + int object_index = 0; + foreach(Object *object, scene->objects) { + if(object->mesh->has_volume) { + object_flag[object_index] |= SD_OBJECT_HAS_VOLUME; + } + + foreach(Object *volume_object, volume_objects) { + if(object == volume_object) { + continue; + } + if(object->bounds.intersects(volume_object->bounds)) { + object_flag[object_index] |= SD_OBJECT_INTERSECTS_VOLUME; + break; + } + } + ++object_index; + } + + /* allocate object flag */ + device->tex_alloc("__object_flag", dscene->object_flag); +} + void ObjectManager::device_free(Device *device, DeviceScene *dscene) { device->tex_free(dscene->objects); diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 677526b715f..2c69b83a2e9 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -76,6 +76,7 @@ public: void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress); + void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_free(Device *device, DeviceScene *dscene); void tag_update(Scene *scene); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index d0de8c51300..6c3f98bc9b0 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -175,6 +175,11 @@ void Scene::device_update(Device *device_, Progress& progress) if(progress.get_cancel()) return; + progress.set_status("Updating Objects Flags"); + object_manager->device_update_flags(device, &dscene, this, progress); + + if(progress.get_cancel()) return; + progress.set_status("Updating Hair Systems"); curve_system_manager->device_update(device, &dscene, this, progress);