Effector calculations are now thread safe.
authorJanne Karhu <jhkarh@gmail.com>
Sun, 24 Jul 2011 17:44:22 +0000 (17:44 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Sun, 24 Jul 2011 17:44:22 +0000 (17:44 +0000)
* where_is_object_time was called for every effector evaluation only to determine the object velocity in some rare cases.
* Calculating the effector velocity is now done in the effector precalculation stage.
* Removing this makes the code thread safe and also should give some nice performance boosts when simulating a lot of points.
* Thanks to MiikaH for noticing this problem.

source/blender/blenkernel/BKE_effect.h
source/blender/blenkernel/intern/effect.c

index 97ac711651b6b3cb0d2d66c942d0d997af38b1c7..12f9383cefbf8d877eeb7747bc15cbb025a9a297 100644 (file)
@@ -105,6 +105,7 @@ typedef struct EffectorCache {
        /* precalculated for guides */
        struct GuideEffectorData *guide_data;
        float guide_loc[4], guide_dir[3], guide_radius;
+       float velocity[3];
 
        float frame;
        int flag;
index ee46bef6038469de9756b98ba635e1b9681b1bb4..4b95c44f55feb66b6d20dbf3b05295a913d7539c 100644 (file)
@@ -241,6 +241,16 @@ static void precalculate_effector(EffectorCache *eff)
        }
        else if(eff->psys)
                psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
+
+       /* Store object velocity */
+       if(eff->ob) {
+               float old_vel[3];
+
+               where_is_object_time(eff->scene, eff->ob, cfra - 1.0f);
+               copy_v3_v3(old_vel, eff->ob->obmat[3]); 
+               where_is_object_time(eff->scene, eff->ob, cfra);
+               sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
+       }
 }
 static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
 {
@@ -680,10 +690,6 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
                Object *ob = eff->ob;
                Object obcopy = *ob;
 
-               /* XXX this is not thread-safe, but used from multiple threads by
-                  particle system */
-               where_is_object_time(eff->scene, ob, cfra);
-
                /* use z-axis as normal*/
                normalize_v3_v3(efd->nor, ob->obmat[2]);
 
@@ -702,13 +708,8 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
                        VECCOPY(efd->loc, ob->obmat[3]);
                }
 
-               if(real_velocity) {
-                       VECCOPY(efd->vel, ob->obmat[3]);
-
-                       where_is_object_time(eff->scene, ob, cfra - 1.0f);
-
-                       sub_v3_v3v3(efd->vel, efd->vel, ob->obmat[3]);
-               }
+               if(real_velocity)
+                       copy_v3_v3(efd->vel, eff->velocity);
 
                *eff->ob = obcopy;