[Bf-blender-cvs] [7cd6d9a] hair_immediate_fixes: Calculate blending weights for preview hairs by constructing a kd-tree of simulated hairs and using nearest neighbors.

Lukas Tönne noreply at git.blender.org
Fri Oct 10 10:32:16 CEST 2014


Commit: 7cd6d9aadacefbb561f7f3101fbf6f5ade3e7bbb
Author: Lukas Tönne
Date:   Thu Oct 9 12:52:52 2014 +0200
Branches: hair_immediate_fixes
https://developer.blender.org/rB7cd6d9aadacefbb561f7f3101fbf6f5ade3e7bbb

Calculate blending weights for preview hairs by constructing a kd-tree
of simulated hairs and using nearest neighbors.

===================================================================

M	source/blender/blenkernel/intern/particle_system.c

===================================================================

diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 2ff2950..18ba0af 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4063,6 +4063,7 @@ bool psys_hair_update_preview(ParticleSimulationData *sim)
 {
 	ParticleSystem *psys = sim->psys;
 	ParticleSettings *part = psys->part;
+	DerivedMesh *dm = sim->psmd->dm;
 	const float ratio = psys->hair_preview_factor * 0.01f;
 	/* target number of simulated hairs
 	 * NOTE: this has to be reached exactly, in order to allow
@@ -4076,35 +4077,72 @@ bool psys_hair_update_preview(ParticleSimulationData *sim)
 		return false;
 	
 	{ /* Random hair selection method */
+		KDTree *tree = BLI_kdtree_new(num_simulated); /* kdtree for finding nearest simulated hairs for blending */
 		RNG *rng = BLI_rng_new(98250 + psys->seed);
 		ParticleData *pa;
 		int cur_simulated = 0;
 		int i;
 		
+		/* construct a kd-tree of all simulated hairs */
 		pa = psys->particles;
 		for (i = 0; i < psys->totpart; ++i, ++pa) {
 			bool simulate = true;
-			/* only allow disabling if the target sim number
-			 * can be reached with the remaining hairs
-			 */
-			if (num_simulated - cur_simulated <= psys->totpart - i) {
+			if (cur_simulated == num_simulated) {
+				/* don't simulate more than the total number */
+				simulate = false;
+			}
+			else if (num_simulated - cur_simulated <= psys->totpart - i) {
+				/* only allow disabling if the target sim number
+				 * can be reached with the remaining hairs
+				 */
 				simulate = BLI_rng_get_float(rng) < ratio;
 			}
 			
 			if (simulate) {
+				float co[3];
+				
 				pa->flag &= ~PARS_HAIR_BLEND;
-				pa->blend_index[0] = -1;
-				pa->blend_index[1] = -1;
-				pa->blend_index[2] = -1;
-				pa->blend_index[3] = -1;
-				pa->blend_weight[0] = 0.0f;
-				pa->blend_weight[1] = 0.0f;
-				pa->blend_weight[2] = 0.0f;
-				pa->blend_weight[3] = 0.0f;
+				
+				psys_particle_on_dm(dm, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, 0, 0, 0, 0, 0);
+				BLI_kdtree_insert(tree, i, co);
+				
+				++cur_simulated;
 			}
 			else {
 				pa->flag |= PARS_HAIR_BLEND;
-				// XXX TODO
+			}
+		}
+		
+		BLI_kdtree_balance(tree);
+		
+		/* look up nearest simulated hairs for preview hairs and calculate blending weights */
+		pa = psys->particles;
+		for (i = 0; i < psys->totpart; ++i, ++pa) {
+			if (pa->flag & PARS_HAIR_BLEND) {
+				float co[3];
+				int maxw, w;
+				KDTreeNearest nearest[4];
+				float totdist, norm;
+				
+				psys_particle_on_dm(dm, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, 0, 0, 0, 0, 0);
+				maxw = BLI_kdtree_find_nearest_n(tree, co, nearest, 4);
+				
+				totdist = 0.0f;
+				for (w = 0; w < maxw; ++w)
+					totdist += nearest[w].dist;
+				norm = totdist > 0.0f ? 1.0f / totdist : 0.0f;
+				
+				for (w = 0; w < maxw; ++w) {
+					pa->blend_index[w] = nearest[w].index;
+					pa->blend_weight[w] = nearest[w].dist * norm;
+				}
+				/* clear unused weights */
+				for (w = maxw; w < 4; ++w) {
+					pa->blend_index[w] = -1;
+					pa->blend_weight[w] = 0.0f;
+				}
+			}
+			else {
 				pa->blend_index[0] = -1;
 				pa->blend_index[1] = -1;
 				pa->blend_index[2] = -1;
@@ -4116,6 +4154,7 @@ bool psys_hair_update_preview(ParticleSimulationData *sim)
 			}
 		}
 		
+		BLI_kdtree_free(tree);
 		BLI_rng_free(rng);
 	}




More information about the Bf-blender-cvs mailing list