use BLI_strncpy and BLI_snprintf when the size of the string is known.
[blender-staging.git] / source / blender / blenkernel / intern / boids.c
index 18f065b59d90294f592fe03cb47b733986de7d14..d454bef3184268cbc1993e10628b824697061262 100644 (file)
@@ -1,8 +1,4 @@
-/* boids.c
- *
- *
- * $Id$
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -17,7 +13,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2009 by Janne Karhu.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/blenkernel/intern/boids.c
+ *  \ingroup bke
+ */
+
+
 #include <string.h>
 #include <math.h>
 
 #include "MEM_guardedalloc.h"
 
-#include "DNA_particle_types.h"
-#include "DNA_modifier_types.h"
 #include "DNA_object_force.h"
-#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_boid_types.h"
-#include "DNA_listBase.h"
 
 #include "BLI_rand.h"
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_kdtree.h"
-#include "BLI_kdopbvh.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_collision.h"
 #include "BKE_effect.h"
 #include "BKE_boids.h"
 #include "BKE_particle.h"
-#include "BKE_utildefines.h"
+
 #include "BKE_modifier.h"
 
 #include "RNA_enum_types.h"
@@ -63,7 +61,7 @@ typedef struct BoidValues {
 
 static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val, ParticleData *pa, float fuzziness);
 
-static int rule_none(BoidRule *rule, BoidBrainData *data, BoidValues *val, ParticleData *pa)
+static int rule_none(BoidRule *UNUSED(rule), BoidBrainData *UNUSED(data), BoidValues *UNUSED(val), ParticleData *UNUSED(pa))
 {
        return 0;
 }
@@ -72,125 +70,112 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
 {
        BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule;
        BoidSettings *boids = bbd->part->boids;
-       ParticleEffectorCache *ec;
-       Object *priority_ob = NULL;
        BoidParticle *bpa = pa->boid;
-       float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
+       EffectedPoint epoint;
+       ListBase *effectors = bbd->sim->psys->effectors;
+       EffectorCache *cur, *eff = NULL;
+       EffectorCache temp_eff;
+       EffectorData efd, cur_efd;
        float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
        float priority = 0.0f, len = 0.0f;
        int ret = 0;
 
-       /* first find out goal/predator with highest priority */
-       /* if rule->ob specified use it */
-       if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
-               PartDeflect *pd = gabr->ob->pd;
-               float vec_to_part[3];
-
-               if(pd && pd->forcefield == PFIELD_BOID) {
-                       effector_find_co(bbd->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
-                       
-                       VecSubf(vec_to_part, pa->prev_state.co, loc);
-
-                       priority = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
-               }
-               else
-                       priority = 1.0;
-
-               priority = 1.0;
-               priority_ob = gabr->ob;
-       }
-       else for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
-               if(ec->type & PSYS_EC_EFFECTOR) {
-                       Object *eob = ec->ob;
-                       PartDeflect *pd = eob->pd;
-
-                       /* skip current object */
-                       if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
-                               continue;
-
-                       if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
-                               float vec_to_part[3], temp;
+       pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
 
-                               effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
-                               
-                               VecSubf(vec_to_part, pa->prev_state.co, loc);
-
-                               temp = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part);
-
-                               if(temp == 0.0f)
-                                       ; /* do nothing */
-                               else if(temp > priority) {
-                                       priority = temp;
-                                       priority_ob = eob;
-                                       len = VecLength(vec_to_part);
-                               }
-                               /* choose closest object with same priority */
-                               else if(temp == priority) {
-                                       float len2 = VecLength(vec_to_part);
-
-                                       if(len2 < len) {
-                                               priority_ob = eob;
-                                               len = len2;
-                                       }
+       /* first find out goal/predator with highest priority */
+       if(effectors) for(cur = effectors->first; cur; cur=cur->next) {
+               Object *eob = cur->ob;
+               PartDeflect *pd = cur->pd;
+
+               if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
+                       if(gabr->ob == eob) {
+                               /* TODO: effectors with multiple points */
+                               if(get_effector_data(cur, &efd, &epoint, 0)) {
+                                       if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
+                                               priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
+                                       else
+                                               priority = 1.0;
+
+                                       eff = cur;
                                }
+                               break;
+                       }
+               }
+               else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
+                       ; /* skip current object */
+               else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) {
+                       float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
+
+                       if(temp == 0.0f)
+                               ; /* do nothing */
+                       else if(temp > priority) {
+                               priority = temp;
+                               eff = cur;
+                               efd = cur_efd;
+                               len = efd.distance;
+                       }
+                       /* choose closest object with same priority */
+                       else if(temp == priority && efd.distance < len) {
+                               eff = cur;
+                               efd = cur_efd;
+                               len = efd.distance;
                        }
                }
        }
 
+       /* if the object doesn't have effector data we have to fake it */
+       if(eff == NULL && gabr->ob) {
+               memset(&temp_eff, 0, sizeof(EffectorCache));
+               temp_eff.ob = gabr->ob;
+               temp_eff.scene = bbd->sim->scene;
+               eff = &temp_eff;
+               get_effector_data(eff, &efd, &epoint, 0);
+               priority = 1.0f;
+       }
+
        /* then use that effector */
        if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
-               Object *eob = priority_ob;
-               PartDeflect *pd = eob->pd;
-               float vec_to_part[3];
-               float surface = 0.0f;
-               float nor[3];
+               Object *eob = eff->ob;
+               PartDeflect *pd = eff->pd;
+               float surface = (pd && pd->shape == PFIELD_SHAPE_SURFACE) ? 1.0f : 0.0f;
 
                if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
                        /* estimate future location of target */
-                       surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL); 
-
-                       VecSubf(vec_to_part, pa->prev_state.co, loc);
-                       len = Normalize(vec_to_part);
+                       get_effector_data(eff, &efd, &epoint, 1);
 
-                       VecMulf(vec, len / (val->max_speed * bbd->timestep));
-                       VecAddf(loc, loc, vec);
-                       VecSubf(vec_to_part, pa->prev_state.co, loc);
-               }
-               else {
-                       surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
-
-                       VecSubf(vec_to_part, pa->prev_state.co, loc);
-                       len = VecLength(vec_to_part);
+                       mul_v3_fl(efd.vel, efd.distance / (val->max_speed * bbd->timestep));
+                       add_v3_v3(efd.loc, efd.vel);
+                       sub_v3_v3v3(efd.vec_to_point, pa->prev_state.co, efd.loc);
+                       efd.distance = len_v3(efd.vec_to_point);
                }
 
                if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) {
                        if(!bbd->goal_ob || bbd->goal_priority < priority) {
                                bbd->goal_ob = eob;
-                               VECCOPY(bbd->goal_co, loc);
-                               VECCOPY(bbd->goal_nor, nor);
+                               copy_v3_v3(bbd->goal_co, efd.loc);
+                               copy_v3_v3(bbd->goal_nor, efd.nor);
                        }
                }
                else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
                        priority > 2.0f * gabr->fear_factor) {
                        /* detach from surface and try to fly away from danger */
-                       VECCOPY(vec_to_part, bpa->gravity);
-                       VecMulf(vec_to_part, -1.0f);
+                       negate_v3_v3(efd.vec_to_point, bpa->gravity);
                }
 
-               VECCOPY(bbd->wanted_co, vec_to_part);
-               VecMulf(bbd->wanted_co, mul);
+               copy_v3_v3(bbd->wanted_co, efd.vec_to_point);
+               mul_v3_fl(bbd->wanted_co, mul);
 
                bbd->wanted_speed = val->max_speed * priority;
 
                /* with goals factor is approach velocity factor */
                if(rule->type == eBoidRuleType_Goal && boids->landing_smoothness > 0.0f) {
-                       float len2 = 2.0f*VecLength(pa->prev_state.vel);
+                       float len2 = 2.0f*len_v3(pa->prev_state.vel);
 
                        surface *= pa->size * boids->height;
 
-                       if(len2 > 0.0f && len - surface < len2) {
-                               len2 = (len - surface)/len2;
-                               bbd->wanted_speed *= pow(len2, boids->landing_smoothness);
+                       if(len2 > 0.0f && efd.distance - surface < len2) {
+                               len2 = (efd.distance - surface)/len2;
+                               bbd->wanted_speed *= powf(len2, boids->landing_smoothness);
                        }
                }
 
@@ -204,9 +189,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
 {
        BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule;
        KDTreeNearest *ptn = NULL;
-       ParticleEffectorCache *ec;
        ParticleTarget *pt;
        BoidParticle *bpa = pa->boid;
+       ColliderCache *coll;
        float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
        float co1[3], vel1[3], co2[3], vel2[3];
        float  len, t, inp, t_min = 2.0f;
@@ -214,45 +199,51 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
        int ret = 0;
 
        //check deflector objects first
-       if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS) {
+       if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) {
                ParticleCollision col;
                BVHTreeRayHit hit;
                float radius = val->personal_space * pa->size, ray_dir[3];
 
-               VECCOPY(col.co1, pa->prev_state.co);
-               VecAddf(col.co2, pa->prev_state.co, pa->prev_state.vel);
-               VecSubf(ray_dir, col.co2, col.co1);
-               VecMulf(ray_dir, acbr->look_ahead);
-               col.t = 0.0f;
+               copy_v3_v3(col.co1, pa->prev_state.co);
+               add_v3_v3v3(col.co2, pa->prev_state.co, pa->prev_state.vel);
+               sub_v3_v3v3(ray_dir, col.co2, col.co1);
+               mul_v3_fl(ray_dir, acbr->look_ahead);
+               col.f = 0.0f;
                hit.index = -1;
-               hit.dist = col.ray_len = VecLength(ray_dir);
+               hit.dist = col.original_ray_length = len_v3(ray_dir);
 
                /* find out closest deflector object */
-               for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
-                       if(ec->type & PSYS_EC_DEFLECT) {
-                               Object *eob = ec->ob;
-
-                               /* don't check with current ground object */
-                               if(eob == bpa->ground)
-                                       continue;
+               for(coll = bbd->sim->colliders->first; coll; coll=coll->next) {
+                       /* don't check with current ground object */
+                       if(coll->ob == bpa->ground)
+                               continue;
 
-                               col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
-                               col.ob_t = eob;
+                       col.current = coll->ob;
+                       col.md = coll->collmd;
 
-                               if(col.md && col.md->bvhtree)
-                                       BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
-                       }
+                       if(col.md && col.md->bvhtree)
+                               BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
                }
                /* then avoid that object */
                if(hit.index>=0) {
-                       /* TODO: not totally happy with this part */
-                       t = hit.dist/col.ray_len;
-
-                       VECCOPY(bbd->wanted_co, col.nor);
+                       t = hit.dist/col.original_ray_length;
+
+                       /* avoid head-on collision */
+                       if(dot_v3v3(col.pce.nor, pa->prev_state.ave) < -0.99f) {
+                               /* don't know why, but uneven range [0.0,1.0] */
+                               /* works much better than even [-1.0,1.0] */
+                               bbd->wanted_co[0] = BLI_frand();
+                               bbd->wanted_co[1] = BLI_frand();
+                               bbd->wanted_co[2] = BLI_frand();
+                       }
+                       else {
+                               copy_v3_v3(bbd->wanted_co, col.pce.nor);
+                       }
 
-                       VecMulf(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size);
+                       mul_v3_fl(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size);
 
-                       bbd->wanted_speed = sqrt(t) * VecLength(pa->prev_state.vel);
+                       bbd->wanted_speed = sqrtf(t) * len_v3(pa->prev_state.vel);
+                       bbd->wanted_speed = MAX2(bbd->wanted_speed, val->min_speed);
 
                        return 1;
                }
@@ -261,39 +252,39 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
        //check boids in own system
        if(acbr->options & BRULE_ACOLL_WITH_BOIDS)
        {
-               neighbors = BLI_kdtree_range_search(bbd->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
+               neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, acbr->look_ahead * len_v3(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
                if(neighbors > 1) for(n=1; n<neighbors; n++) {
-                       VECCOPY(co1, pa->prev_state.co);
-                       VECCOPY(vel1, pa->prev_state.vel);
-                       VECCOPY(co2, (bbd->psys->particles + ptn[n].index)->prev_state.co);
-                       VECCOPY(vel2, (bbd->psys->particles + ptn[n].index)->prev_state.vel);
+                       copy_v3_v3(co1, pa->prev_state.co);
+                       copy_v3_v3(vel1, pa->prev_state.vel);
+                       copy_v3_v3(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co);
+                       copy_v3_v3(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel);
 
-                       VecSubf(loc, co1, co2);
+                       sub_v3_v3v3(loc, co1, co2);
 
-                       VecSubf(vec, vel1, vel2);
+                       sub_v3_v3v3(vec, vel1, vel2);
                        
-                       inp = Inpf(vec,vec);
+                       inp = dot_v3v3(vec,vec);
 
                        /* velocities not parallel */
                        if(inp != 0.0f) {
-                               t = -Inpf(loc, vec)/inp;
+                               t = -dot_v3v3(loc, vec)/inp;
                                /* cpa is not too far in the future so investigate further */
                                if(t > 0.0f && t < t_min) {
-                                       VECADDFAC(co1, co1, vel1, t);
-                                       VECADDFAC(co2, co2, vel2, t);
+                                       madd_v3_v3fl(co1, vel1, t);
+                                       madd_v3_v3fl(co2, vel2, t);
                                        
-                                       VecSubf(vec, co2, co1);
+                                       sub_v3_v3v3(vec, co2, co1);
 
-                                       len = Normalize(vec);
+                                       len = normalize_v3(vec);
 
                                        /* distance of cpa is close enough */
                                        if(len < 2.0f * val->personal_space * pa->size) {
                                                t_min = t;
 
-                                               VecMulf(vec, VecLength(vel1));
-                                               VecMulf(vec, (2.0f - t)/2.0f);
-                                               VecSubf(bbd->wanted_co, vel1, vec);
-                                               bbd->wanted_speed = VecLength(bbd->wanted_co);
+                                               mul_v3_fl(vec, len_v3(vel1));
+                                               mul_v3_fl(vec, (2.0f - t)/2.0f);
+                                               sub_v3_v3v3(bbd->wanted_co, vel1, vec);
+                                               bbd->wanted_speed = len_v3(bbd->wanted_co);
                                                ret = 1;
                                        }
                                }
@@ -303,43 +294,43 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
        if(ptn){ MEM_freeN(ptn); ptn=NULL; }
 
        /* check boids in other systems */
-       for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
-               ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+       for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+               ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
 
                if(epsys) {
-                       neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
+                       neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * len_v3(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
                        if(neighbors > 0) for(n=0; n<neighbors; n++) {
-                               VECCOPY(co1, pa->prev_state.co);
-                               VECCOPY(vel1, pa->prev_state.vel);
-                               VECCOPY(co2, (epsys->particles + ptn[n].index)->prev_state.co);
-                               VECCOPY(vel2, (epsys->particles + ptn[n].index)->prev_state.vel);
+                               copy_v3_v3(co1, pa->prev_state.co);
+                               copy_v3_v3(vel1, pa->prev_state.vel);
+                               copy_v3_v3(co2, (epsys->particles + ptn[n].index)->prev_state.co);
+                               copy_v3_v3(vel2, (epsys->particles + ptn[n].index)->prev_state.vel);
 
-                               VecSubf(loc, co1, co2);
+                               sub_v3_v3v3(loc, co1, co2);
 
-                               VecSubf(vec, vel1, vel2);
+                               sub_v3_v3v3(vec, vel1, vel2);
                                
-                               inp = Inpf(vec,vec);
+                               inp = dot_v3v3(vec,vec);
 
                                /* velocities not parallel */
                                if(inp != 0.0f) {
-                                       t = -Inpf(loc, vec)/inp;
+                                       t = -dot_v3v3(loc, vec)/inp;
                                        /* cpa is not too far in the future so investigate further */
                                        if(t > 0.0f && t < t_min) {
-                                               VECADDFAC(co1, co1, vel1, t);
-                                               VECADDFAC(co2, co2, vel2, t);
+                                               madd_v3_v3fl(co1, vel1, t);
+                                               madd_v3_v3fl(co2, vel2, t);
                                                
-                                               VecSubf(vec, co2, co1);
+                                               sub_v3_v3v3(vec, co2, co1);
 
-                                               len = Normalize(vec);
+                                               len = normalize_v3(vec);
 
                                                /* distance of cpa is close enough */
                                                if(len < 2.0f * val->personal_space * pa->size) {
                                                        t_min = t;
 
-                                                       VecMulf(vec, VecLength(vel1));
-                                                       VecMulf(vec, (2.0f - t)/2.0f);
-                                                       VecSubf(bbd->wanted_co, vel1, vec);
-                                                       bbd->wanted_speed = VecLength(bbd->wanted_co);
+                                                       mul_v3_fl(vec, len_v3(vel1));
+                                                       mul_v3_fl(vec, (2.0f - t)/2.0f);
+                                                       sub_v3_v3v3(bbd->wanted_co, vel1, vec);
+                                                       bbd->wanted_speed = len_v3(bbd->wanted_co);
                                                        ret = 1;
                                                }
                                        }
@@ -356,19 +347,19 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
 
        return ret;
 }
-static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
+static int rule_separate(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
 {
        KDTreeNearest *ptn = NULL;
        ParticleTarget *pt;
        float len = 2.0f * val->personal_space * pa->size + 1.0f;
        float vec[3] = {0.0f, 0.0f, 0.0f};
-       int neighbors = BLI_kdtree_range_search(bbd->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
+       int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
        int ret = 0;
 
        if(neighbors > 1 && ptn[1].dist!=0.0f) {
-               VecSubf(vec, pa->prev_state.co, bbd->psys->particles[ptn[1].index].state.co);
-               VecMulf(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
-               VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
+               sub_v3_v3v3(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co);
+               mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
+               add_v3_v3(bbd->wanted_co, vec);
                bbd->wanted_speed = val->max_speed;
                len = ptn[1].dist;
                ret = 1;
@@ -376,16 +367,16 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
        if(ptn){ MEM_freeN(ptn); ptn=NULL; }
 
        /* check other boid systems */
-       for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
-               ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+       for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+               ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
 
                if(epsys) {
                        neighbors = BLI_kdtree_range_search(epsys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
                        
                        if(neighbors > 0 && ptn[0].dist < len) {
-                               VecSubf(vec, pa->prev_state.co, ptn[0].co);
-                               VecMulf(vec, (2.0f * val->personal_space * pa->size - ptn[0].dist) / ptn[1].dist);
-                               VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
+                               sub_v3_v3v3(vec, pa->prev_state.co, ptn[0].co);
+                               mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[0].dist) / ptn[1].dist);
+                               add_v3_v3(bbd->wanted_co, vec);
                                bbd->wanted_speed = val->max_speed;
                                len = ptn[0].dist;
                                ret = 1;
@@ -396,29 +387,29 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
        }
        return ret;
 }
-static int rule_flock(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa)
+static int rule_flock(BoidRule *UNUSED(rule), BoidBrainData *bbd, BoidValues *UNUSED(val), ParticleData *pa)
 {
        KDTreeNearest ptn[11];
        float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
-       int neighbors = BLI_kdtree_find_n_nearest(bbd->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
+       int neighbors = BLI_kdtree_find_n_nearest(bbd->sim->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
        int n;
        int ret = 0;
 
        if(neighbors > 1) {
                for(n=1; n<neighbors; n++) {
-                       VecAddf(loc, loc, bbd->psys->particles[ptn[n].index].prev_state.co);
-                       VecAddf(vec, vec, bbd->psys->particles[ptn[n].index].prev_state.vel);
+                       add_v3_v3(loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co);
+                       add_v3_v3(vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel);
                }
 
-               VecMulf(loc, 1.0f/((float)neighbors - 1.0f));
-               VecMulf(vec, 1.0f/((float)neighbors - 1.0f));
+               mul_v3_fl(loc, 1.0f/((float)neighbors - 1.0f));
+               mul_v3_fl(vec, 1.0f/((float)neighbors - 1.0f));
 
-               VecSubf(loc, loc, pa->prev_state.co);
-               VecSubf(vec, vec, pa->prev_state.vel);
+               sub_v3_v3(loc, pa->prev_state.co);
+               sub_v3_v3(vec, pa->prev_state.vel);
 
-               VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
-               VecAddf(bbd->wanted_co, bbd->wanted_co, loc);
-               bbd->wanted_speed = VecLength(bbd->wanted_co);
+               add_v3_v3(bbd->wanted_co, vec);
+               add_v3_v3(bbd->wanted_co, loc);
+               bbd->wanted_speed = len_v3(bbd->wanted_co);
 
                ret = 1;
        }
@@ -429,44 +420,44 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
        BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader*) rule;
        float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
        float mul, len;
-       int n = (flbr->queue_size <= 1) ? bbd->psys->totpart : flbr->queue_size;
-       int i, ret = 0, p = pa - bbd->psys->particles;
+       int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
+       int i, ret = 0, p = pa - bbd->sim->psys->particles;
 
        if(flbr->ob) {
                float vec2[3], t;
 
                /* first check we're not blocking the leader*/
-               VecSubf(vec, flbr->loc, flbr->oloc);
-               VecMulf(vec, 1.0f/bbd->timestep);
+               sub_v3_v3v3(vec, flbr->loc, flbr->oloc);
+               mul_v3_fl(vec, 1.0f/bbd->timestep);
 
-               VecSubf(loc, pa->prev_state.co, flbr->oloc);
+               sub_v3_v3v3(loc, pa->prev_state.co, flbr->oloc);
 
-               mul = Inpf(vec, vec);
+               mul = dot_v3v3(vec, vec);
 
                /* leader is not moving */
-               if(mul < 0.01) {
-                       len = VecLength(loc);
+               if(mul < 0.01f) {
+                       len = len_v3(loc);
                        /* too close to leader */
                        if(len < 2.0f * val->personal_space * pa->size) {
-                               VECCOPY(bbd->wanted_co, loc);
+                               copy_v3_v3(bbd->wanted_co, loc);
                                bbd->wanted_speed = val->max_speed;
                                return 1;
                        }
                }
                else {
-                       t = Inpf(loc, vec)/mul;
+                       t = dot_v3v3(loc, vec)/mul;
 
                        /* possible blocking of leader in near future */
                        if(t > 0.0f && t < 3.0f) {
-                               VECCOPY(vec2, vec);
-                               VecMulf(vec2, t);
+                               copy_v3_v3(vec2, vec);
+                               mul_v3_fl(vec2, t);
 
-                               VecSubf(vec2, loc, vec2);
+                               sub_v3_v3v3(vec2, loc, vec2);
 
-                               len = VecLength(vec2);
+                               len = len_v3(vec2);
 
                                if(len < 2.0f * val->personal_space * pa->size) {
-                                       VECCOPY(bbd->wanted_co, vec2);
+                                       copy_v3_v3(bbd->wanted_co, vec2);
                                        bbd->wanted_speed = val->max_speed * (3.0f - t)/3.0f;
                                        return 1;
                                }
@@ -475,20 +466,20 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
 
                /* not blocking so try to follow leader */
                if(p && flbr->options & BRULE_LEADER_IN_LINE) {
-                       VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
-                       VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
+                       copy_v3_v3(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
+                       copy_v3_v3(loc, bbd->sim->psys->particles[p-1].prev_state.co);
                }
                else {
-                       VECCOPY(loc, flbr->oloc);
-                       VecSubf(vec, flbr->loc, flbr->oloc);
-                       VecMulf(vec, 1.0/bbd->timestep);
+                       copy_v3_v3(loc, flbr->oloc);
+                       sub_v3_v3v3(vec, flbr->loc, flbr->oloc);
+                       mul_v3_fl(vec, 1.0f/bbd->timestep);
                }
                
                /* fac is seconds behind leader */
-               VECADDFAC(loc, loc, vec, -flbr->distance);
+               madd_v3_v3fl(loc, vec, -flbr->distance);
 
-               VecSubf(bbd->wanted_co, loc, pa->prev_state.co);
-               bbd->wanted_speed = VecLength(bbd->wanted_co);
+               sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co);
+               bbd->wanted_speed = len_v3(bbd->wanted_co);
                        
                ret = 1;
        }
@@ -496,38 +487,38 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
                float vec2[3], t, t_min = 3.0f;
 
                /* first check we're not blocking any leaders */
-               for(i = 0; i< bbd->psys->totpart; i+=n){
-                       VECCOPY(vec, bbd->psys->particles[i].prev_state.vel);
+               for(i = 0; i< bbd->sim->psys->totpart; i+=n){
+                       copy_v3_v3(vec, bbd->sim->psys->particles[i].prev_state.vel);
 
-                       VecSubf(loc, pa->prev_state.co, bbd->psys->particles[i].prev_state.co);
+                       sub_v3_v3v3(loc, pa->prev_state.co, bbd->sim->psys->particles[i].prev_state.co);
 
-                       mul = Inpf(vec, vec);
+                       mul = dot_v3v3(vec, vec);
 
                        /* leader is not moving */
-                       if(mul < 0.01) {
-                               len = VecLength(loc);
+                       if(mul < 0.01f) {
+                               len = len_v3(loc);
                                /* too close to leader */
                                if(len < 2.0f * val->personal_space * pa->size) {
-                                       VECCOPY(bbd->wanted_co, loc);
+                                       copy_v3_v3(bbd->wanted_co, loc);
                                        bbd->wanted_speed = val->max_speed;
                                        return 1;
                                }
                        }
                        else {
-                               t = Inpf(loc, vec)/mul;
+                               t = dot_v3v3(loc, vec)/mul;
 
                                /* possible blocking of leader in near future */
                                if(t > 0.0f && t < t_min) {
-                                       VECCOPY(vec2, vec);
-                                       VecMulf(vec2, t);
+                                       copy_v3_v3(vec2, vec);
+                                       mul_v3_fl(vec2, t);
 
-                                       VecSubf(vec2, loc, vec2);
+                                       sub_v3_v3v3(vec2, loc, vec2);
 
-                                       len = VecLength(vec2);
+                                       len = len_v3(vec2);
 
                                        if(len < 2.0f * val->personal_space * pa->size) {
                                                t_min = t;
-                                               VECCOPY(bbd->wanted_co, loc);
+                                               copy_v3_v3(bbd->wanted_co, loc);
                                                bbd->wanted_speed = val->max_speed * (3.0f - t)/3.0f;
                                                ret = 1;
                                        }
@@ -539,19 +530,19 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
 
                /* not blocking so try to follow leader */
                if(flbr->options & BRULE_LEADER_IN_LINE) {
-                       VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
-                       VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
+                       copy_v3_v3(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
+                       copy_v3_v3(loc, bbd->sim->psys->particles[p-1].prev_state.co);
                }
                else {
-                       VECCOPY(vec, bbd->psys->particles[p - p%n].prev_state.vel);
-                       VECCOPY(loc, bbd->psys->particles[p - p%n].prev_state.co);
+                       copy_v3_v3(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel);
+                       copy_v3_v3(loc, bbd->sim->psys->particles[p - p%n].prev_state.co);
                }
                
                /* fac is seconds behind leader */
-               VECADDFAC(loc, loc, vec, -flbr->distance);
+               madd_v3_v3fl(loc, vec, -flbr->distance);
 
-               VecSubf(bbd->wanted_co, loc, pa->prev_state.co);
-               bbd->wanted_speed = VecLength(bbd->wanted_co);
+               sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co);
+               bbd->wanted_speed = len_v3(bbd->wanted_co);
                
                ret = 1;
        }
@@ -570,40 +561,40 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
                bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
                bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
 
-               Normalize(bpa->wander);
+               normalize_v3(bpa->wander);
 
-               VECCOPY(vec, bpa->wander);
+               copy_v3_v3(vec, bpa->wander);
 
-               QuatMulVecf(pa->prev_state.rot, vec);
+               mul_qt_v3(pa->prev_state.rot, vec);
 
-               VECCOPY(bbd->wanted_co, pa->prev_state.ave);
+               copy_v3_v3(bbd->wanted_co, pa->prev_state.ave);
 
-               VecMulf(bbd->wanted_co, 1.1f);
+               mul_v3_fl(bbd->wanted_co, 1.1f);
 
-               VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
+               add_v3_v3(bbd->wanted_co, vec);
 
                /* leveling */
-               if(asbr->level > 0.0f) {
-                       Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
-                       VecMulf(vec, asbr->level);
-                       VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
+               if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
+                       project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
+                       mul_v3_fl(vec, asbr->level);
+                       sub_v3_v3(bbd->wanted_co, vec);
                }
        }
        else {
-               VECCOPY(bbd->wanted_co, pa->prev_state.ave);
+               copy_v3_v3(bbd->wanted_co, pa->prev_state.ave);
 
                /* may happen at birth */
-               if(Inp2f(bbd->wanted_co,bbd->wanted_co)==0.0f) {
+               if(dot_v2v2(bbd->wanted_co,bbd->wanted_co)==0.0f) {
                        bbd->wanted_co[0] = 2.0f*(0.5f - BLI_frand());
                        bbd->wanted_co[1] = 2.0f*(0.5f - BLI_frand());
                        bbd->wanted_co[2] = 2.0f*(0.5f - BLI_frand());
                }
                
                /* leveling */
-               if(asbr->level > 0.0f) {
-                       Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
-                       VecMulf(vec, asbr->level);
-                       VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
+               if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
+                       project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
+                       mul_v3_fl(vec, asbr->level);
+                       sub_v3_v3(bbd->wanted_co, vec);
                }
 
        }
@@ -627,9 +618,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
        int n, ret = 0;
 
        /* calculate own group strength */
-       int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
+       int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
        for(n=0; n<neighbors; n++) {
-               bpa = bbd->psys->particles[ptn[n].index].boid;
+               bpa = bbd->sim->psys->particles[ptn[n].index].boid;
                health += bpa->data.health;
        }
 
@@ -638,8 +629,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
        if(ptn){ MEM_freeN(ptn); ptn=NULL; }
 
        /* add other friendlies and calculate enemy strength and find closest enemy */
-       for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
-               ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
+       for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
+               ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
                if(epsys) {
                        epars = epsys->particles;
 
@@ -652,7 +643,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
                                health += bpa->data.health;
 
                                if(n==0 && pt->mode==PTARGET_MODE_ENEMY && ptn[n].dist < closest_dist) {
-                                       VECCOPY(closest_enemy, ptn[n].co);
+                                       copy_v3_v3(closest_enemy, ptn[n].co);
                                        closest_dist = ptn[n].dist;
                                        enemy_pa = epars + ptn[n].index;
                                }
@@ -667,20 +658,20 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
        }
        /* decide action if enemy presence found */
        if(e_strength > 0.0f) {
-               VecSubf(bbd->wanted_co, closest_enemy, pa->prev_state.co);
+               sub_v3_v3v3(bbd->wanted_co, closest_enemy, pa->prev_state.co);
 
                /* attack if in range */
                if(closest_dist <= bbd->part->boids->range + pa->size + enemy_pa->size) {
                        float damage = BLI_frand();
-                       float enemy_dir[3] = {bbd->wanted_co[0],bbd->wanted_co[1],bbd->wanted_co[2]};
+                       float enemy_dir[3];
 
-                       Normalize(enemy_dir);
+                       normalize_v3_v3(enemy_dir, bbd->wanted_co);
 
                        /* fight mode */
                        bbd->wanted_speed = 0.0f;
 
                        /* must face enemy to fight */
-                       if(Inpf(pa->prev_state.ave, enemy_dir)>0.5f) {
+                       if(dot_v3v3(pa->prev_state.ave, enemy_dir)>0.5f) {
                                bpa = enemy_pa->boid;
                                bpa->data.health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy);
                        }
@@ -695,7 +686,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
                if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) {
                        /* decide to flee */
                        if(closest_dist < fbr->flee_distance * fbr->distance) {
-                               VecMulf(bbd->wanted_co, -1.0f);
+                               negate_v3(bbd->wanted_co);
                                bbd->wanted_speed = val->max_speed;
                        }
                        else { /* wait for better odds */
@@ -735,7 +726,7 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *
        if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
                val->max_speed = boids->land_max_speed * bpa->data.health/boids->health;
                val->max_acc = boids->land_max_acc * val->max_speed;
-               val->max_ave = boids->land_max_ave * M_PI * bpa->data.health/boids->health;
+               val->max_ave = boids->land_max_ave * (float)M_PI * bpa->data.health/boids->health;
                val->min_speed = 0.0f; /* no minimum speed on land */
                val->personal_space = boids->land_personal_space;
                val->jump_speed = boids->land_jump_speed * bpa->data.health/boids->health;
@@ -743,78 +734,100 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *
        else {
                val->max_speed = boids->air_max_speed * bpa->data.health/boids->health;
                val->max_acc = boids->air_max_acc * val->max_speed;
-               val->max_ave = boids->air_max_ave * M_PI * bpa->data.health/boids->health;
+               val->max_ave = boids->air_max_ave * (float)M_PI * bpa->data.health/boids->health;
                val->min_speed = boids->air_min_speed * boids->air_max_speed;
                val->personal_space = boids->air_personal_space;
                val->jump_speed = 0.0f; /* no jumping in air */
        }
 }
-static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor)
+
+static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float ground_co[3], float ground_nor[3])
 {
        BoidParticle *bpa = pa->boid;
 
        if(bpa->data.mode == eBoidMode_Climbing) {
                SurfaceModifierData *surmd = NULL;
                float x[3], v[3];
-
+               
                surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface );
 
                /* take surface velocity into account */
-               effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
-               VecAddf(x, x, v);
+               closest_point_on_surface(surmd, pa->state.co, x, NULL, v);
+               add_v3_v3(x, v);
 
                /* get actual position on surface */
-               effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
+               closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL);
 
                return bpa->ground;
        }
        else {
                float zvec[3] = {0.0f, 0.0f, 2000.0f};
                ParticleCollision col;
+               ColliderCache *coll;
                BVHTreeRayHit hit;
-               ParticleEffectorCache *ec;
                float radius = 0.0f, t, ray_dir[3];
 
-               VECCOPY(col.co1, pa->state.co);
-               VECCOPY(col.co2, pa->state.co);
-               VecAddf(col.co1, col.co1, zvec);
-               VecSubf(col.co2, col.co2, zvec);
-               VecSubf(ray_dir, col.co2, col.co1);
-               col.t = 0.0f;
-               hit.index = -1;
-               hit.dist = col.ray_len = VecLength(ray_dir);
+               if(!bbd->sim->colliders)
+                       return NULL;
 
-               /* find out upmost deflector object */
-               for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
-                       if(ec->type & PSYS_EC_DEFLECT) {
-                               Object *eob = ec->ob;
+               /* first try to find below boid */
+               copy_v3_v3(col.co1, pa->state.co);
+               sub_v3_v3v3(col.co2, pa->state.co, zvec);
+               sub_v3_v3v3(ray_dir, col.co2, col.co1);
+               col.f = 0.0f;
+               hit.index = -1;
+               hit.dist = col.original_ray_length = len_v3(ray_dir);
+               col.pce.inside = 0;
 
-                               col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) );
-                               col.ob_t = eob;
+               for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
+                       col.current = coll->ob;
+                       col.md = coll->collmd;
+                       col.fac1 = col.fac2 = 0.f;
 
-                               if(col.md && col.md->bvhtree)
-                                       BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
-                       }
+                       if(col.md && col.md->bvhtree)
+                               BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
                }
                /* then use that object */
                if(hit.index>=0) {
-                       t = hit.dist/col.ray_len;
-                       VecLerpf(ground_co, col.co1, col.co2, t);
-                       VECCOPY(ground_nor, col.nor);
-                       Normalize(ground_nor);
-                       return col.ob;
+                       t = hit.dist/col.original_ray_length;
+                       interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+                       normalize_v3_v3(ground_nor, col.pce.nor);
+                       return col.hit;
                }
-               else {
-                       /* default to z=0 */
-                       VECCOPY(ground_co, pa->state.co);
-                       ground_co[2] = 0;
-                       ground_nor[0] = ground_nor[1] = 0.0f;
-                       ground_nor[2] = 1.0f;
-                       return NULL;
+
+               /* couldn't find below, so find upmost deflector object */
+               add_v3_v3v3(col.co1, pa->state.co, zvec);
+               sub_v3_v3v3(col.co2, pa->state.co, zvec);
+               sub_v3_v3(col.co2, zvec);
+               sub_v3_v3v3(ray_dir, col.co2, col.co1);
+               col.f = 0.0f;
+               hit.index = -1;
+               hit.dist = col.original_ray_length = len_v3(ray_dir);
+
+               for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
+                       col.current = coll->ob;
+                       col.md = coll->collmd;
+
+                       if(col.md && col.md->bvhtree)
+                               BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, BKE_psys_collision_neartest_cb, &col);
+               }
+               /* then use that object */
+               if(hit.index>=0) {
+                       t = hit.dist/col.original_ray_length;
+                       interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+                       normalize_v3_v3(ground_nor, col.pce.nor);
+                       return col.hit;
                }
+
+               /* default to z=0 */
+               copy_v3_v3(ground_co, pa->state.co);
+               ground_co[2] = 0;
+               ground_nor[0] = ground_nor[1] = 0.0f;
+               ground_nor[2] = 1.0f;
+               return NULL;
        }
 }
-static int boid_rule_applies(ParticleData *pa, BoidSettings *boids, BoidRule *rule)
+static int boid_rule_applies(ParticleData *pa, BoidSettings *UNUSED(boids), BoidRule *rule)
 {
        BoidParticle *bpa = pa->boid;
 
@@ -840,8 +853,8 @@ void boids_precalc_rules(ParticleSettings *part, float cfra)
 
                                if(flbr->ob && flbr->cfra != cfra) {
                                        /* save object locations for velocity calculations */
-                                       VECCOPY(flbr->oloc, flbr->loc);
-                                       VECCOPY(flbr->loc, flbr->ob->obmat[3]);
+                                       copy_v3_v3(flbr->oloc, flbr->loc);
+                                       copy_v3_v3(flbr->loc, flbr->ob->obmat[3]);
                                        flbr->cfra = cfra;
                                }
                        }
@@ -852,27 +865,27 @@ static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co,
 {
        BoidParticle *bpa = pa->boid;
        float nor[3], vel[3];
-       VECCOPY(nor, surface_nor);
+       copy_v3_v3(nor, surface_nor);
 
        /* gather apparent gravity */
-       VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0);
-       Normalize(bpa->gravity);
+       madd_v3_v3fl(bpa->gravity, surface_nor, -1.0f);
+       normalize_v3(bpa->gravity);
 
        /* raise boid it's size from surface */
-       VecMulf(nor, pa->size * boids->height);
-       VecAddf(pa->state.co, surface_co, nor);
+       mul_v3_fl(nor, pa->size * boids->height);
+       add_v3_v3v3(pa->state.co, surface_co, nor);
 
        /* remove normal component from velocity */
-       Projf(vel, pa->state.vel, surface_nor);
-       VecSubf(pa->state.vel, pa->state.vel, vel);
+       project_v3_v3v3(vel, pa->state.vel, surface_nor);
+       sub_v3_v3v3(pa->state.vel, pa->state.vel, vel);
 }
 static float boid_goal_signed_dist(float *boid_co, float *goal_co, float *goal_nor)
 {
        float vec[3];
 
-       VecSubf(vec, boid_co, goal_co);
+       sub_v3_v3v3(vec, boid_co, goal_co);
 
-       return Inpf(vec, goal_nor);
+       return dot_v3v3(vec, goal_nor);
 }
 /* wanted_co is relative to boid location */
 static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val, ParticleData *pa, float fuzziness)
@@ -886,12 +899,13 @@ static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val,
        if(boid_rules[rule->type](rule, bbd, val, pa)==0)
                return 0;
 
-       if(fuzziness < 0.0f || VecLenCompare(bbd->wanted_co, pa->prev_state.vel, fuzziness * VecLength(pa->prev_state.vel))==0)
+       if(fuzziness < 0.0f || compare_len_v3v3(bbd->wanted_co, pa->prev_state.vel, fuzziness * len_v3(pa->prev_state.vel))==0)
                return 1;
        else
                return 0;
 }
-static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa) {
+static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa)
+{
        BoidState *state = boids->states.first;
        BoidParticle *bpa = pa->boid;
 
@@ -920,11 +934,13 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
        BoidValues val;
        BoidState *state = get_boid_state(boids, pa);
        BoidParticle *bpa = pa->boid;
+       ParticleSystem *psys = bbd->sim->psys;
        int rand;
        //BoidCondition *cond;
 
        if(bpa->data.health <= 0.0f) {
                pa->alive = PARS_DYING;
+               pa->dietime = bbd->cfra;
                return;
        }
 
@@ -941,9 +957,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
        bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f;
 
        /* create random seed for every particle & frame */
-       BLI_srandom(bbd->psys->seed + p);
-       rand = BLI_rand();
-       BLI_srandom((int)bbd->cfra + rand);
+       rand = (int)(PSYS_FRAND(psys->seed + p) * 1000);
+       rand = (int)(PSYS_FRAND((int)bbd->cfra + rand) * 1000);
 
        set_boid_values(&val, bbd->part->boids, pa);
 
@@ -970,7 +985,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
                        int n = 0;
                        for(rule = state->rules.first; rule; rule=rule->next) {
                                if(apply_boid_rule(bbd, rule, &val, pa, -1.0f)) {
-                                       VecAddf(wanted_co, wanted_co, bbd->wanted_co);
+                                       add_v3_v3(wanted_co, bbd->wanted_co);
                                        wanted_speed += bbd->wanted_speed;
                                        n++;
                                        bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f;
@@ -978,11 +993,11 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
                        }
 
                        if(n > 1) {
-                               VecMulf(wanted_co, 1.0f/(float)n);
+                               mul_v3_fl(wanted_co, 1.0f/(float)n);
                                wanted_speed /= (float)n;
                        }
 
-                       VECCOPY(bbd->wanted_co, wanted_co);
+                       copy_v3_v3(bbd->wanted_co, wanted_co);
                        bbd->wanted_speed = wanted_speed;
                        break;
                }
@@ -992,18 +1007,18 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
        /* decide on jumping & liftoff */
        if(bpa->data.mode == eBoidMode_OnLand) {
                /* fuzziness makes boids capable of misjudgement */
-               float mul = 1.0 + state->rule_fuzziness;
+               float mul = 1.0f + state->rule_fuzziness;
                
                if(boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f) {
                        float cvel[3], dir[3];
 
-                       VECCOPY(dir, pa->prev_state.ave);
-                       Normalize2(dir);
+                       copy_v3_v3(dir, pa->prev_state.ave);
+                       normalize_v2(dir);
 
-                       VECCOPY(cvel, bbd->wanted_co);
-                       Normalize2(cvel);
+                       copy_v3_v3(cvel, bbd->wanted_co);
+                       normalize_v2(cvel);
 
-                       if(Inp2f(cvel, dir) > 0.95 / mul)
+                       if(dot_v2v2(cvel, dir) > 0.95f / mul)
                                bpa->data.mode = eBoidMode_Liftoff;
                }
                else if(val.jump_speed > 0.0f) {
@@ -1016,21 +1031,21 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
                                float z_v, ground_v, cur_v;
                                float len;
 
-                               VECCOPY(dir, pa->prev_state.ave);
-                               Normalize2(dir);
+                               copy_v3_v3(dir, pa->prev_state.ave);
+                               normalize_v2(dir);
 
-                               VECCOPY(cvel, bbd->wanted_co);
-                               Normalize2(cvel);
+                               copy_v3_v3(cvel, bbd->wanted_co);
+                               normalize_v2(cvel);
 
-                               len = Vec2Length(pa->prev_state.vel);
+                               len = len_v2(pa->prev_state.vel);
 
                                /* first of all, are we going in a suitable direction? */
                                /* or at a suitably slow speed */
-                               if(Inp2f(cvel, dir) > 0.95f / mul || len <= state->rule_fuzziness) {
+                               if(dot_v2v2(cvel, dir) > 0.95f / mul || len <= state->rule_fuzziness) {
                                        /* try to reach goal at highest point of the parabolic path */
-                                       cur_v = Vec2Length(pa->prev_state.vel);
-                                       z_v = sasqrt(-2.0f * bbd->part->acc[2] * bbd->wanted_co[2]);
-                                       ground_v = Vec2Length(bbd->wanted_co)*sasqrt(-0.5f * bbd->part->acc[2] / bbd->wanted_co[2]);
+                                       cur_v = len_v2(pa->prev_state.vel);
+                                       z_v = sasqrt(-2.0f * bbd->sim->scene->physics_settings.gravity[2] * bbd->wanted_co[2]);
+                                       ground_v = len_v2(bbd->wanted_co)*sasqrt(-0.5f * bbd->sim->scene->physics_settings.gravity[2] / bbd->wanted_co[2]);
 
                                        len = sasqrt((ground_v-cur_v)*(ground_v-cur_v) + z_v*z_v);
 
@@ -1039,13 +1054,13 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
 
                                                len = MIN2(len, val.jump_speed);
 
-                                               VECCOPY(jump_v, dir);
+                                               copy_v3_v3(jump_v, dir);
                                                jump_v[2] = z_v;
-                                               VecMulf(jump_v, ground_v);
+                                               mul_v3_fl(jump_v, ground_v);
 
-                                               Normalize(jump_v);
-                                               VecMulf(jump_v, len);
-                                               Vec2Addf(jump_v, jump_v, pa->prev_state.vel);
+                                               normalize_v3(jump_v);
+                                               mul_v3_fl(jump_v, len);
+                                               add_v2_v2v2(jump_v, jump_v, pa->prev_state.vel);
                                        }
                                }
                        }
@@ -1056,7 +1071,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
                        }
 
                        if(jump) {
-                               VECCOPY(pa->prev_state.vel, jump_v);
+                               copy_v3_v3(pa->prev_state.vel, jump_v);
                                bpa->data.mode = eBoidMode_Falling;
                        }
                }
@@ -1068,6 +1083,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
        BoidSettings *boids = bbd->part->boids;
        BoidParticle *bpa = pa->boid;
        BoidValues val;
+       EffectedPoint epoint;
        float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3];
        float dvec[3], bvec[3];
        float new_dir[3], new_speed;
@@ -1075,9 +1091,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
        float wanted_dir[3];
        float q[4], mat[3][3]; /* rotation */
        float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
-       float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f};
+       float force[3] = {0.0f, 0.0f, 0.0f};
        float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
-       int p = pa - bbd->psys->particles;
 
        set_boid_values(&val, boids, pa);
 
@@ -1088,12 +1103,12 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                pa_mass*=pa->size;
 
        /* if boids can't fly they fall to the ground */
-       if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f)
+       if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && psys_uses_gravity(bbd->sim))
                bpa->data.mode = eBoidMode_Falling;
 
        if(bpa->data.mode == eBoidMode_Falling) {
                /* Falling boids are only effected by gravity. */
-               acc[2] = bbd->part->acc[2];
+               acc[2] = bbd->sim->scene->physics_settings.gravity[2];
        }
        else {
                /* figure out acceleration */
@@ -1111,7 +1126,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                        bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
                        
                        /* level = how many particle sizes above ground */
-                       level = (pa->prev_state.co[2] - ground_co[2])/(2.0f * pa->size) - 0.5;
+                       level = (pa->prev_state.co[2] - ground_co[2])/(2.0f * pa->size) - 0.5f;
 
                        landing_level = - boids->landing_smoothness * pa->prev_state.vel[2] * pa_mass;
 
@@ -1128,49 +1143,48 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                        }
                }
 
-               VECCOPY(old_dir, pa->prev_state.ave);
-               VECCOPY(wanted_dir, bbd->wanted_co);
-               new_speed = Normalize(wanted_dir);
+               copy_v3_v3(old_dir, pa->prev_state.ave);
+               new_speed = normalize_v3_v3(wanted_dir, bbd->wanted_co);
 
                /* first check if we have valid direction we want to go towards */
                if(new_speed == 0.0f) {
-                       VECCOPY(new_dir, old_dir);
+                       copy_v3_v3(new_dir, old_dir);
                }
                else {
                        float old_dir2[2], wanted_dir2[2], nor[3], angle;
-                       Vec2Copyf(old_dir2, old_dir);
-                       Normalize2(old_dir2);
-                       Vec2Copyf(wanted_dir2, wanted_dir);
-                       Normalize2(wanted_dir2);
+                       copy_v2_v2(old_dir2, old_dir);
+                       normalize_v2(old_dir2);
+                       copy_v2_v2(wanted_dir2, wanted_dir);
+                       normalize_v2(wanted_dir2);
 
                        /* choose random direction to turn if wanted velocity */
                        /* is directly behind regardless of z-coordinate */
-                       if(Inp2f(old_dir2, wanted_dir2) < -0.99f) {
+                       if(dot_v2v2(old_dir2, wanted_dir2) < -0.99f) {
                                wanted_dir[0] = 2.0f*(0.5f - BLI_frand());
                                wanted_dir[1] = 2.0f*(0.5f - BLI_frand());
                                wanted_dir[2] = 2.0f*(0.5f - BLI_frand());
-                               Normalize(wanted_dir);
+                               normalize_v3(wanted_dir);
                        }
 
                        /* constrain direction with maximum angular velocity */
-                       angle = saacos(Inpf(old_dir, wanted_dir));
+                       angle = saacos(dot_v3v3(old_dir, wanted_dir));
                        angle = MIN2(angle, val.max_ave);
 
-                       Crossf(nor, old_dir, wanted_dir);
-                       VecRotToQuat(nor, angle, q);
-                       VECCOPY(new_dir, old_dir);
-                       QuatMulVecf(q, new_dir);
-                       Normalize(new_dir);
+                       cross_v3_v3v3(nor, old_dir, wanted_dir);
+                       axis_angle_to_quat( q,nor, angle);
+                       copy_v3_v3(new_dir, old_dir);
+                       mul_qt_v3(q, new_dir);
+                       normalize_v3(new_dir);
 
                        /* save direction in case resulting velocity too small */
-                       VecRotToQuat(nor, angle*dtime, q);
-                       VECCOPY(pa->state.ave, old_dir);
-                       QuatMulVecf(q, pa->state.ave);
-                       Normalize(pa->state.ave);
+                       axis_angle_to_quat( q,nor, angle*dtime);
+                       copy_v3_v3(pa->state.ave, old_dir);
+                       mul_qt_v3(q, pa->state.ave);
+                       normalize_v3(pa->state.ave);
                }
 
                /* constrain speed with maximum acceleration */
-               old_speed = VecLength(pa->prev_state.vel);
+               old_speed = len_v3(pa->prev_state.vel);
                
                if(bbd->wanted_speed < old_speed)
                        new_speed = MAX2(bbd->wanted_speed, old_speed - val.max_acc);
@@ -1178,12 +1192,12 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                        new_speed = MIN2(bbd->wanted_speed, old_speed + val.max_acc);
 
                /* combine direction and speed */
-               VECCOPY(new_vel, new_dir);
-               VecMulf(new_vel, new_speed);
+               copy_v3_v3(new_vel, new_dir);
+               mul_v3_fl(new_vel, new_speed);
 
                /* maintain minimum flying velocity if not landing */
                if(level >= landing_level) {
-                       float len2 = Inp2f(new_vel,new_vel);
+                       float len2 = dot_v2v2(new_vel,new_vel);
                        float root;
 
                        len2 = MAX2(len2, val.min_speed*val.min_speed);
@@ -1191,76 +1205,81 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
 
                        new_vel[2] = new_vel[2] < 0.0f ? -root : root;
 
-                       Normalize2(new_vel);
-                       Vec2Mulf(new_vel, sasqrt(len2));
+                       normalize_v2(new_vel);
+                       mul_v2_fl(new_vel, sasqrt(len2));
                }
 
                /* finally constrain speed to max speed */
-               new_speed = Normalize(new_vel);
-               VecMulf(new_vel, MIN2(new_speed, val.max_speed));
+               new_speed = normalize_v3(new_vel);
+               mul_v3_fl(new_vel, MIN2(new_speed, val.max_speed));
 
                /* get acceleration from difference of velocities */
-               VecSubf(acc, new_vel, pa->prev_state.vel);
+               sub_v3_v3v3(acc, new_vel, pa->prev_state.vel);
 
                /* break acceleration to components */
-               Projf(tan_acc, acc, pa->prev_state.ave);
-               VecSubf(nor_acc, acc, tan_acc);
+               project_v3_v3v3(tan_acc, acc, pa->prev_state.ave);
+               sub_v3_v3v3(nor_acc, acc, tan_acc);
        }
 
        /* account for effectors */
-       do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
+       pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
+       pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
 
        if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
-               float length = Normalize(force);
+               float length = normalize_v3(force);
 
                length = MAX2(0.0f, length - boids->land_stick_force);
 
-               VecMulf(force, length);
+               mul_v3_fl(force, length);
        }
        
-       VecAddf(acc, acc, force);
+       add_v3_v3(acc, force);
 
        /* store smoothed acceleration for nice banking etc. */
-       VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime);
-       VecMulf(bpa->data.acc, 1.0f / (1.0f + dtime));
+       madd_v3_v3fl(bpa->data.acc, acc, dtime);
+       mul_v3_fl(bpa->data.acc, 1.0f / (1.0f + dtime));
 
        /* integrate new location & velocity */
 
        /* by regarding the acceleration as a force at this stage we*/
        /* can get better control allthough it's a bit unphysical       */
-       VecMulf(acc, 1.0f/pa_mass);
+       mul_v3_fl(acc, 1.0f/pa_mass);
 
-       VECCOPY(dvec, acc);
-       VecMulf(dvec, dtime*dtime*0.5f);
+       copy_v3_v3(dvec, acc);
+       mul_v3_fl(dvec, dtime*dtime*0.5f);
        
-       VECCOPY(bvec, pa->prev_state.vel);
-       VecMulf(bvec, dtime);
-       VecAddf(dvec, dvec, bvec);
-       VecAddf(pa->state.co, pa->state.co, dvec);
+       copy_v3_v3(bvec, pa->prev_state.vel);
+       mul_v3_fl(bvec, dtime);
+       add_v3_v3(dvec, bvec);
+       add_v3_v3(pa->state.co, dvec);
 
-       VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime);
+       madd_v3_v3fl(pa->state.vel, acc, dtime);
 
-       if(bpa->data.mode != eBoidMode_InAir)
-               bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
+       //if(bpa->data.mode != eBoidMode_InAir)
+       bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
 
        /* change modes, constrain movement & keep track of down vector */
        switch(bpa->data.mode) {
                case eBoidMode_InAir:
                {
-                       float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
+                       float grav[3];
+
+                       grav[0]= 0.0f;
+                       grav[1]= 0.0f;
+                       grav[2]= bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f;
 
                        /* don't take forward acceleration into account (better banking) */
-                       if(Inpf(bpa->data.acc, pa->state.vel) > 0.0f) {
-                               Projf(dvec, bpa->data.acc, pa->state.vel);
-                               VecSubf(dvec, bpa->data.acc, dvec);
+                       if(dot_v3v3(bpa->data.acc, pa->state.vel) > 0.0f) {
+                               project_v3_v3v3(dvec, bpa->data.acc, pa->state.vel);
+                               sub_v3_v3v3(dvec, bpa->data.acc, dvec);
                        }
                        else {
-                               VECCOPY(dvec, bpa->data.acc);
+                               copy_v3_v3(dvec, bpa->data.acc);
                        }
 
                        /* gather apparent gravity */
-                       VECADDFAC(bpa->gravity, grav, dvec, -boids->banking);
-                       Normalize(bpa->gravity);
+                       madd_v3_v3v3fl(bpa->gravity, grav, dvec, -boids->banking);
+                       normalize_v3(bpa->gravity);
 
                        /* stick boid on goal when close enough */
                        if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) {
@@ -1269,21 +1288,33 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                                boid_find_ground(bbd, pa, ground_co, ground_nor);
                                boid_climb(boids, pa, ground_co, ground_nor);
                        }
-                       /* land boid when belowg ground */
-                       else if(boids->options & BOID_ALLOW_LAND && pa->state.co[2] <= ground_co[2] + pa->size * boids->height) {
-                               pa->state.co[2] = ground_co[2] + pa->size * boids->height;
-                               pa->state.vel[2] = 0.0f;
-                               bpa->data.mode = eBoidMode_OnLand;
+                       else if(pa->state.co[2] <= ground_co[2] + pa->size * boids->height) {
+                               /* land boid when below ground */
+                               if(boids->options & BOID_ALLOW_LAND) {
+                                       pa->state.co[2] = ground_co[2] + pa->size * boids->height;
+                                       pa->state.vel[2] = 0.0f;
+                                       bpa->data.mode = eBoidMode_OnLand;
+                               }
+                               /* fly above ground */
+                               else if(bpa->ground) {
+                                       pa->state.co[2] = ground_co[2] + pa->size * boids->height;
+                                       pa->state.vel[2] = 0.0f;
+                               }
                        }
                        break;
                }
                case eBoidMode_Falling:
                {
-                       float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f};
+                       float grav[3];
+
+                       grav[0]= 0.0f;
+                       grav[1]= 0.0f;
+                       grav[2]= bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f;
+
 
                        /* gather apparent gravity */
-                       VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime);
-                       Normalize(bpa->gravity);
+                       madd_v3_v3fl(bpa->gravity, grav, dtime);
+                       normalize_v3(bpa->gravity);
 
                        if(boids->options & BOID_ALLOW_LAND) {
                                /* stick boid on goal when close enough */
@@ -1294,7 +1325,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                                        boid_climb(boids, pa, ground_co, ground_nor);
                                }
                                /* land boid when really near ground */
-                               else if(pa->state.co[2] <= ground_co[2] + 1.01 * pa->size * boids->height){
+                               else if(pa->state.co[2] <= ground_co[2] + 1.01f * pa->size * boids->height){
                                        pa->state.co[2] = ground_co[2] + pa->size * boids->height;
                                        pa->state.vel[2] = 0.0f;
                                        bpa->data.mode = eBoidMode_OnLand;
@@ -1311,19 +1342,19 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                {
                        boid_climb(boids, pa, ground_co, ground_nor);
                        //float nor[3];
-                       //VECCOPY(nor, ground_nor);
+                       //copy_v3_v3(nor, ground_nor);
 
                        ///* gather apparent gravity to r_ve */
-                       //VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0);
-                       //Normalize(pa->r_ve);
+                       //madd_v3_v3fl(pa->r_ve, ground_nor, -1.0);
+                       //normalize_v3(pa->r_ve);
 
                        ///* raise boid it's size from surface */
-                       //VecMulf(nor, pa->size * boids->height);
-                       //VecAddf(pa->state.co, ground_co, nor);
+                       //mul_v3_fl(nor, pa->size * boids->height);
+                       //add_v3_v3v3(pa->state.co, ground_co, nor);
 
                        ///* remove normal component from velocity */
-                       //Projf(v, pa->state.vel, ground_nor);
-                       //VecSubf(pa->state.vel, pa->state.vel, v);
+                       //project_v3_v3v3(v, pa->state.vel, ground_nor);
+                       //sub_v3_v3v3(pa->state.vel, pa->state.vel, v);
                        break;
                }
                case eBoidMode_OnLand:
@@ -1336,7 +1367,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                                boid_climb(boids, pa, ground_co, ground_nor);
                        }
                        /* ground is too far away so boid falls */
-                       else if(pa->state.co[2]-ground_co[2] > 1.1 * pa->size * boids->height)
+                       else if(pa->state.co[2]-ground_co[2] > 1.1f * pa->size * boids->height)
                                bpa->data.mode = eBoidMode_Falling;
                        else {
                                /* constrain to surface */
@@ -1348,20 +1379,19 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
                                float grav[3];
                                /* Don't take gravity's strength in to account, */
                                /* otherwise amount of banking is hard to control. */
-                               VECCOPY(grav, ground_nor);
-                               VecMulf(grav, -1.0f);
-                               
-                               Projf(dvec, bpa->data.acc, pa->state.vel);
-                               VecSubf(dvec, bpa->data.acc, dvec);
+                               negate_v3_v3(grav, ground_nor);
+
+                               project_v3_v3v3(dvec, bpa->data.acc, pa->state.vel);
+                               sub_v3_v3v3(dvec, bpa->data.acc, dvec);
 
                                /* gather apparent gravity */
-                               VECADDFAC(bpa->gravity, grav, dvec, -boids->banking);
-                               Normalize(bpa->gravity);
+                               madd_v3_v3v3fl(bpa->gravity, grav, dvec, -boids->banking);
+                               normalize_v3(bpa->gravity);
                        }
                        else {
                                /* gather negative surface normal */
-                               VECADDFAC(bpa->gravity, bpa->gravity, ground_nor, -1.0f);
-                               Normalize(bpa->gravity);
+                               madd_v3_v3fl(bpa->gravity, ground_nor, -1.0f);
+                               normalize_v3(bpa->gravity);
                        }
                        break;
                }
@@ -1369,36 +1399,37 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
 
        /* save direction to state.ave unless the boid is falling */
        /* (boids can't effect their direction when falling) */
-       if(bpa->data.mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) {
-               VECCOPY(pa->state.ave, pa->state.vel);
-               Normalize(pa->state.ave);
+       if(bpa->data.mode!=eBoidMode_Falling && len_v3(pa->state.vel) > 0.1f*pa->size) {
+               copy_v3_v3(pa->state.ave, pa->state.vel);
+               pa->state.ave[2] *= bbd->part->boids->pitch;
+               normalize_v3(pa->state.ave);
        }
 
        /* apply damping */
        if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing))
-               VecMulf(pa->state.vel, 1.0f - 0.2f*bbd->part->dampfac);
+               mul_v3_fl(pa->state.vel, 1.0f - 0.2f*bbd->part->dampfac);
 
        /* calculate rotation matrix based on forward & down vectors */
        if(bpa->data.mode == eBoidMode_InAir) {
-               VECCOPY(mat[0], pa->state.ave);
+               copy_v3_v3(mat[0], pa->state.ave);
 
-               Projf(dvec, bpa->gravity, pa->state.ave);
-               VecSubf(mat[2], bpa->gravity, dvec);
-               Normalize(mat[2]);
+               project_v3_v3v3(dvec, bpa->gravity, pa->state.ave);
+               sub_v3_v3v3(mat[2], bpa->gravity, dvec);
+               normalize_v3(mat[2]);
        }
        else {
-               Projf(dvec, pa->state.ave, bpa->gravity);
-               VecSubf(mat[0], pa->state.ave, dvec);
-               Normalize(mat[0]);
+               project_v3_v3v3(dvec, pa->state.ave, bpa->gravity);
+               sub_v3_v3v3(mat[0], pa->state.ave, dvec);
+               normalize_v3(mat[0]);
 
-               VECCOPY(mat[2], bpa->gravity);
+               copy_v3_v3(mat[2], bpa->gravity);
        }
-       VecMulf(mat[2], -1.0f);
-       Crossf(mat[1], mat[2], mat[0]);
+       negate_v3(mat[2]);
+       cross_v3_v3v3(mat[1], mat[2], mat[0]);
        
        /* apply rotation */
-       Mat3ToQuat_is_ok(mat, q);
-       QuatCopy(pa->state.rot, q);
+       mat3_to_quat_is_ok( q,mat);
+       copy_qt_qt(pa->state.rot, q);
 }
 
 BoidRule *boid_new_rule(int type)
@@ -1436,7 +1467,7 @@ BoidRule *boid_new_rule(int type)
 
        rule->type = type;
        rule->flag |= BOIDRULE_IN_AIR|BOIDRULE_ON_LAND;
-       strcpy(rule->name, boidrule_type_items[type-1].name);
+       BLI_strncpy(rule->name, boidrule_type_items[type-1].name, sizeof(rule->name));
 
        return rule;
 }
@@ -1456,6 +1487,7 @@ void boid_default_settings(BoidSettings *boids)
 
        boids->landing_smoothness = 3.0f;
        boids->banking = 1.0f;
+       boids->pitch = 1.0f;
        boids->height = 1.0f;
 
        boids->health = 1.0f;
@@ -1471,7 +1503,7 @@ BoidState *boid_new_state(BoidSettings *boids)
 
        state->id = boids->last_state_id++;
        if(state->id)
-               sprintf(state->name, "State %i", state->id);
+               BLI_snprintf(state->name, sizeof(state->name), "State %i", state->id);
        else
                strcpy(state->name, "State");
 
@@ -1482,7 +1514,8 @@ BoidState *boid_new_state(BoidSettings *boids)
        return state;
 }
 
-BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state) {
+BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state)
+{
        BoidState *staten = MEM_dupallocN(state);
 
        BLI_duplicatelist(&staten->rules, &state->rules);