Revision: 26212
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26212
Author:   jhk
Date:     2010-01-23 16:45:01 +0100 (Sat, 23 Jan 2010)

Log Message:
-----------
Small fixes for particles.
* Particle collision with size was broken since raytrace optimizations by 
jaguarandi, now the collision code falls back to old slower method when the 
collision ray has a radius.
* Single goal/avoid object now works for boids.
* Some tiny improvements on collision avoidance for boids.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/boids.c
    trunk/blender/source/blender/blenkernel/intern/effect.c
    trunk/blender/source/blender/blenlib/intern/BLI_kdopbvh.c

Modified: trunk/blender/source/blender/blenkernel/intern/boids.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/boids.c      2010-01-23 
14:29:56 UTC (rev 26211)
+++ trunk/blender/source/blender/blenkernel/intern/boids.c      2010-01-23 
15:45:01 UTC (rev 26212)
@@ -77,6 +77,7 @@
        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;
@@ -91,7 +92,7 @@
 
                if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != 
bpa->ground)) {
                        if(gabr->ob == eob) {
-                               /* TODO: objects without any effector and 
effectors with multiple points */
+                               /* 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);
@@ -105,7 +106,7 @@
                }
                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(eff, &efd, &epoint, 0)) {
+               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)
@@ -125,11 +126,21 @@
                }
        }
 
+       /* 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 = eff->ob;
-               PartDeflect *pd = eob->pd;
-               float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f;
+               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 */
@@ -219,10 +230,19 @@
                }
                /* 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);
+                       /* avoid head-on collision */
+                       if(dot_v3v3(col.nor, pa->prev_state.ave) < -0.99) {
+                               /* 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 {
+                               VECCOPY(bbd->wanted_co, col.nor);
+                       }
 
                        mul_v3_fl(bbd->wanted_co, (1.0f - t) * 
val->personal_space * pa->size);
 

Modified: trunk/blender/source/blender/blenkernel/intern/effect.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/effect.c     2010-01-23 
14:29:56 UTC (rev 26211)
+++ trunk/blender/source/blender/blenkernel/intern/effect.c     2010-01-23 
15:45:01 UTC (rev 26212)
@@ -593,7 +593,7 @@
        float cfra = eff->scene->r.cfra;
        int ret = 0;
 
-       if(eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) {
+       if(eff->pd && eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) {
                /* closest point in the object surface is an effector */
                float vec[3];
 
@@ -606,7 +606,7 @@
 
                efd->size = 0.0f;
        }
-       else if(eff->pd->shape==PFIELD_SHAPE_POINTS) {
+       else if(eff->pd && eff->pd->shape==PFIELD_SHAPE_POINTS) {
 
                if(eff->ob->derivedFinal) {
                        DerivedMesh *dm = eff->ob->derivedFinal;
@@ -667,7 +667,7 @@
                normalize_v3(efd->nor);
 
                /* for vortex the shape chooses between old / new force */
-               if(eff->pd->shape == PFIELD_SHAPE_PLANE) {
+               if(eff->pd && eff->pd->shape == PFIELD_SHAPE_PLANE) {
                        /* efd->loc is closes point on effector xy-plane */
                        float temp[3];
                        sub_v3_v3v3(temp, point->loc, ob->obmat[3]);
@@ -698,7 +698,7 @@
                efd->distance = len_v3(efd->vec_to_point);
 
                /* rest length for harmonic effector, will have to see later if 
this could be extended to other effectors */
-               if(eff->pd->forcefield == PFIELD_HARMONIC && eff->pd->f_size)
+               if(eff->pd && eff->pd->forcefield == PFIELD_HARMONIC && 
eff->pd->f_size)
                        mul_v3_fl(efd->vec_to_point, 
(efd->distance-eff->pd->f_size)/efd->distance);
 
                if(eff->flag & PE_USE_NORMAL_DATA) {

Modified: trunk/blender/source/blender/blenlib/intern/BLI_kdopbvh.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/BLI_kdopbvh.c   2010-01-23 
14:29:56 UTC (rev 26211)
+++ trunk/blender/source/blender/blenlib/intern/BLI_kdopbvh.c   2010-01-23 
15:45:01 UTC (rev 26212)
@@ -1502,7 +1502,8 @@
 
        //ray-bv is really fast.. and simple tests revealed its worth to test it
        //before calling the ray-primitive functions
-       float dist = fast_ray_nearest_hit(data, node);
+       /* XXX: temporary solution for particles untill fast_ray_nearest_hit 
supports ray.radius */
+       float dist = (data->ray.radius > 0.0f) ? ray_nearest_hit(data, 
node->bv) : fast_ray_nearest_hit(data, node);
        if(dist >= data->hit.dist) return;
 
        if(node->totnode == 0)


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to