[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26212] trunk/blender/source/blender: Small fixes for particles.

Janne Karhu jhkarh at gmail.com
Sat Jan 23 16:45:02 CET 2010


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)





More information about the Bf-blender-cvs mailing list