[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19552] trunk/blender/source/blender/ blenkernel: Fix for: [#18371] VParent breaks fur effects.

Janne Karhu jhkarh at utu.fi
Mon Apr 6 02:10:52 CEST 2009


Revision: 19552
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19552
Author:   jhk
Date:     2009-04-06 02:10:52 +0200 (Mon, 06 Apr 2009)

Log Message:
-----------
Fix for: [#18371] VParent breaks fur effects.
-Virtual parents were not randomly selected due to optimization in child particle distribution code.
-Wave-kink had a wrong matrix multiplication.
-Amount of virtual parents wasn't scaled properly to the amount of children rendered.
-Calculating virtual parents is now thread safe.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h	2009-04-06 00:04:04 UTC (rev 19551)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h	2009-04-06 00:10:52 UTC (rev 19552)
@@ -173,7 +173,7 @@
 
 	/* path caching */
 	int editupdate, between, steps;
-	int totchild, totparent;
+	int totchild, totparent, parent_pass;
 
 	float cfra;
 

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2009-04-06 00:04:04 UTC (rev 19551)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2009-04-06 00:10:52 UTC (rev 19552)
@@ -1461,7 +1461,7 @@
 		case PART_KINK_WAVE:
 			vec[axis]=1.0;
 			if(obmat)
-				Mat4MulVecfl(obmat,vec);
+				Mat4Mul3Vecfl(obmat,vec);
 
 			if(par_rot)
 				QuatMulVecf(par_rot,vec);
@@ -1805,10 +1805,13 @@
 	int from=PART_FROM_FACE;
 	totparent=(int)(totchild*part->parents*0.3);
 
+	if(G.rendering && part->child_nbr && part->ren_child_nbr)
+		totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
 	tree=BLI_kdtree_new(totparent);
 
 	for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
-		psys_particle_on_emitter(psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
+		psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
 		BLI_kdtree_insert(tree, p, orco, NULL);
 	}
 
@@ -1872,6 +1875,10 @@
 
 	if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
 		totparent=(int)(totchild*part->parents*0.3);
+		
+		if(G.rendering && part->child_nbr && part->ren_child_nbr)
+			totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
 		/* part->parents could still be 0 so we can't test with totparent */
 		between=1;
 	}
@@ -1904,6 +1911,7 @@
 	ctx->steps= steps;
 	ctx->totchild= totchild;
 	ctx->totparent= totparent;
+	ctx->parent_pass= 0;
 	ctx->cfra= cfra;
 
 	psys->lattice = psys_get_lattice(ob, psys);
@@ -1941,14 +1949,14 @@
 	ParticleCacheKey *state, *par = NULL, *key[4];
 	ParticleData *pa=NULL;
 	ParticleTexture ptex;
-	float *cpa_fuv=0;
+	float *cpa_fuv=0, *par_rot=0;
 	float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
 	float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
 	float pa_rough1, pa_rough2, pa_roughe;
 	float length, pa_length, pa_clump, pa_kink, pa_effector;
 	float max_length = 1.0f, cur_length = 0.0f;
 	float eff_length, eff_vec[3];
-	int k, cpa_num, guided=0;
+	int k, cpa_num, guided = 0;
 	short cpa_from;
 
 	if(part->flag & PART_BRANCHING) {
@@ -2138,15 +2146,16 @@
 		t=(float)k/(float)ctx->steps;
 
 		if(ctx->totparent){
-			if(i>=ctx->totparent)
-				/* this is not threadsafe, but should only happen for
-				 * branching particles particles, which are not threaded */
+			if(i>=ctx->totparent) {
+				/* this is now threadsafe, virtual parents are calculated before rest of children */
 				par = cache[cpa->parent] + k;
+			}
 			else
 				par=0;
 		}
 		else if(cpa->parent>=0){
 			par=pcache[cpa->parent]+k;
+			par_rot = par->rot;
 		}
 
 		/* apply different deformations to the child path */
@@ -2156,7 +2165,7 @@
 
 		if(guided==0){
 			if(part->kink)
-				do_prekink((ParticleKey*)state, (ParticleKey*)par, par->rot, t,
+				do_prekink((ParticleKey*)state, (ParticleKey*)par, par_rot, t,
 				part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat);
 					
 			do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump);
@@ -2255,10 +2264,15 @@
 	ParticleSystem *psys= ctx->psys;
 	ParticleCacheKey **cache= psys->childcache;
 	ChildParticle *cpa;
-	int i, totchild= ctx->totchild;
+	int i, totchild= ctx->totchild, first= 0;
+
+	if(thread->tot > 1){
+		first= ctx->parent_pass? 0 : ctx->totparent;
+		totchild= ctx->parent_pass? ctx->totparent : ctx->totchild;
+	}
 	
-	cpa= psys->child + thread->num;
-	for(i=thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
+	cpa= psys->child + first + thread->num;
+	for(i=first+thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
 		psys_thread_create_path(thread, cpa, cache[i], i);
 
 	return 0;
@@ -2297,6 +2311,22 @@
 	totthread= pthreads[0].tot;
 
 	if(totthread > 1) {
+
+		/* make virtual child parents thread safe by calculating them first */
+		if(totparent) {
+			BLI_init_threads(&threads, exec_child_path_cache, totthread);
+			
+			for(i=0; i<totthread; i++) {
+				pthreads[i].ctx->parent_pass = 1;
+				BLI_insert_thread(&threads, &pthreads[i]);
+			}
+
+			BLI_end_threads(&threads);
+
+			for(i=0; i<totthread; i++)
+				pthreads[i].ctx->parent_pass = 0;
+		}
+
 		BLI_init_threads(&threads, exec_child_path_cache, totthread);
 
 		for(i=0; i<totthread; i++)
@@ -3495,6 +3525,10 @@
 		
 		if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
 			totparent=(int)(totchild*part->parents*0.3);
+			
+			if(G.rendering && part->child_nbr && part->ren_child_nbr)
+				totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+			
 			/* part->parents could still be 0 so we can't test with totparent */
 			between=1;
 		}

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2009-04-06 00:04:04 UTC (rev 19551)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2009-04-06 00:10:52 UTC (rev 19552)
@@ -1301,7 +1301,8 @@
 	MEM_freeN(sum);
 
 	/* for hair, sort by origindex, allows optimizations in rendering */
-	if(part->type == PART_HAIR) {
+	/* however with virtual parents the children need to be in random order */
+	if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) {
 		COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
 		if(COMPARE_ORIG_INDEX)
 			qsort(index, totpart, sizeof(int), compare_orig_index);





More information about the Bf-blender-cvs mailing list