diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-02-25 21:29:11 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2014-02-25 21:29:11 +0400 |
commit | 0bef196894abd19903b0741ec6250e0558b4f1a4 (patch) | |
tree | a65b0078c166fd60c194530ec9bd8435d3c92b15 /intern | |
parent | ef73d547cc7c663ad180721094c81b3c81482ac3 (diff) |
Fix T38811: Cycles particle ids are inconsistent when using multiple particle systems.
Problem is that the particle systems in the cycles database are not
stored in a well-defined order. This means the particle_id for dupli
objects can not simply be assigned using a global running index during
sync.
Now the particle index is assigned locally for each particle system.
When transferring particle data to the device as a single texture, the
particle indices are offset based on the final order of particle systems
in the database.
Reviewers: brecht
Reviewed By: brecht
CC: Andreas80
Differential Revision: https://developer.blender.org/D352
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 17 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 4 |
4 files changed, 25 insertions, 13 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 49da9384406..2ea0b27dff8 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -433,9 +433,6 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) BL::Scene::objects_iterator b_ob; BL::Scene b_sce = b_scene; - /* global particle index counter */ - int particle_id = 1; - bool cancel = false; for(; b_sce && !cancel; b_sce = b_sce.background_set()) { @@ -470,13 +467,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) /* sync possible particle data, note particle_id * starts counting at 1, first is dummy particle */ - if(!motion && object && sync_dupli_particle(*b_ob, *b_dup, object)) { - if(particle_id != object->particle_id) { - object->particle_id = particle_id; - scene->object_manager->tag_update(scene); - } - - particle_id++; + if(!motion && object) { + sync_dupli_particle(*b_ob, *b_dup, object); } } diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index ef832ed39c0..5b2782ec2ac 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -76,6 +76,11 @@ bool BlenderSync::sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Ob psys->particles.push_back(pa); + if (object->particle_index != psys->particles.size() - 1) + scene->object_manager->tag_update(scene); + object->particle_system = psys; + object->particle_index = psys->particles.size() - 1; + /* return that this object has particle data */ return true; } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 3edb934ef2c..b40f3616242 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -19,6 +19,7 @@ #include "mesh.h" #include "curves.h" #include "object.h" +#include "particles.h" #include "scene.h" #include "util_foreach.h" @@ -38,7 +39,8 @@ Object::Object() visibility = ~0; random_id = 0; pass_id = 0; - particle_id = 0; + particle_system = NULL; + particle_index = 0; bounds = BoundBox::empty; motion.pre = transform_identity(); motion.mid = transform_identity(); @@ -154,6 +156,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene float4 *objects_vector = NULL; int i = 0; map<Mesh*, float> surface_area_map; + map<ParticleSystem*, int> particle_offset; Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); bool have_motion = false; bool have_curves = false; @@ -162,6 +165,15 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene if(need_motion == Scene::MOTION_PASS) objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size()); + /* particle system device offsets + * 0 is dummy particle, index starts at 1 + */ + int numparticles = 1; + foreach(ParticleSystem *psys, scene->particle_systems) { + particle_offset[psys] = numparticles; + numparticles += psys->particles.size(); + } + foreach(Object *ob, scene->objects) { Mesh *mesh = ob->mesh; uint flag = 0; @@ -177,6 +189,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene float surface_area = 0.0f; float pass_id = ob->pass_id; float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF); + int particle_index = (ob->particle_system)? ob->particle_index + particle_offset[ob->particle_system]: 0; if(transform_uniform_scale(tfm, uniform_scale)) { map<Mesh*, float>::iterator it = surface_area_map.find(mesh); @@ -243,7 +256,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset], &tfm, sizeof(float4)*3); memcpy(&objects[offset+4], &itfm, sizeof(float4)*3); - objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id)); + objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(particle_index)); if(need_motion == Scene::MOTION_PASS) { /* motion transformations, is world/object space depending if mesh diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 5da85be3873..31400f3c7f1 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -27,6 +27,7 @@ CCL_NAMESPACE_BEGIN class Device; class DeviceScene; class Mesh; +class ParticleSystem; class Progress; class Scene; struct Transform; @@ -50,7 +51,8 @@ public: float3 dupli_generated; float2 dupli_uv; - int particle_id; + ParticleSystem *particle_system; + int particle_index; Object(); ~Object(); |