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:
-rw-r--r--source/blender/blenkernel/intern/boids.c32
-rw-r--r--source/blender/blenkernel/intern/effect.c8
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c3
3 files changed, 32 insertions, 11 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);
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index b261d3365af..f4fea899005 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -593,7 +593,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
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 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
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 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
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 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
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) {
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index eebff8dfaef..a91c24471bb 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1502,7 +1502,8 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
//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)