Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Karhu <jhkarh@gmail.com>2010-01-23 18:45:01 +0300
committerJanne Karhu <jhkarh@gmail.com>2010-01-23 18:45:01 +0300
commit9feadd443a69484ec5b56af566d28758cc7ae119 (patch)
tree97355147e633ad439fb6d56f66b88413bc81dc1c /source/blender/blenkernel/intern/boids.c
parent1bb6ba0605d56f5fcb3a190a350659dd2e4ae600 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern/boids.c')
-rw-r--r--source/blender/blenkernel/intern/boids.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 838e595d83f..777c653beca 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -77,6 +77,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
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 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
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 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
}
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 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
}
}
+ /* 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 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
}
/* 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);