[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34670] trunk/blender/source/blender: Bug fix: Particles in dupligroups were mostly drawn properly in 3d view, but rendering them was a real mess.

Janne Karhu jhkarh at gmail.com
Sun Feb 6 16:50:01 CET 2011


Revision: 34670
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34670
Author:   jhk
Date:     2011-02-06 15:50:00 +0000 (Sun, 06 Feb 2011)
Log Message:
-----------
Bug fix: Particles in dupligroups were mostly drawn properly in 3d view, but rendering them was a real mess.
* After countless different bugs particles should now render correctly inside dupligroups.
* Only particles with metaball visualization are still problematic, this is mostly due to the ancient metaball code.
* I'll also add a test file for some of the situations, so that hopefully these cases stay fixed :)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/anim.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/makesdna/DNA_particle_types.h
    trunk/blender/source/blender/render/intern/source/convertblender.c

Modified: trunk/blender/source/blender/blenkernel/intern/anim.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim.c	2011-02-06 11:17:22 UTC (rev 34669)
+++ trunk/blender/source/blender/blenkernel/intern/anim.c	2011-02-06 15:50:00 UTC (rev 34670)
@@ -1156,7 +1156,7 @@
 	dm->release(dm);
 }
 
-static void new_particle_duplilist(ListBase *lb, ID *UNUSED(id), Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
+static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
 {
 	GroupObject *go;
 	Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
@@ -1375,7 +1375,7 @@
 				/* Normal particles and cached hair live in global space so we need to
 				 * remove the real emitter's transformation before 2nd order duplication.
 				 */
-				if(par_space_mat)
+				if(par_space_mat && GS(id->name) != ID_GR)
 					mul_m4_m4m4(mat, pamat, psys->imat);
 				else
 					copy_m4_m4(mat, pamat);
@@ -1391,7 +1391,7 @@
 				if(part->draw & PART_DRAW_GLOBAL_OB)
 					VECADD(mat[3], mat[3], vec);
 
-				dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated);
+				dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated);
 				copy_m4_m4(dob->omat, oldobmat);
 				if(G.rendering)
 					psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2011-02-06 11:17:22 UTC (rev 34669)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2011-02-06 15:50:00 UTC (rev 34670)
@@ -1194,12 +1194,12 @@
 	key->time = hkey->time;
 }
 
-static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, float frs_sec, ParticleInterpolationData *pind, ParticleKey *result)
+static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, ParticleInterpolationData *pind, ParticleKey *result)
 {
 	PTCacheEditPoint *point = pind->epoint;
 	ParticleKey keys[4];
 	int point_vel = (point && point->keys->vel);
-	float real_t, dfra, keytime;
+	float real_t, dfra, keytime, invdt;
 
 	/* billboards wont fill in all of these, so start cleared */
 	memset(keys, 0, sizeof(keys));
@@ -1338,11 +1338,12 @@
 
 	dfra = keys[2].time - keys[1].time;
 	keytime = (real_t - keys[1].time) / dfra;
+	invdt = dfra * 0.04f * psys->part->timetweak;
 
 	/* convert velocity to timestep size */
 	if(pind->keyed || pind->cache || point_vel){
-		mul_v3_fl(keys[1].vel, dfra / frs_sec);
-		mul_v3_fl(keys[2].vel, dfra / frs_sec);
+		mul_v3_fl(keys[1].vel, invdt);
+		mul_v3_fl(keys[2].vel, invdt);
 		interp_qt_qtqt(result->rot,keys[1].rot,keys[2].rot,keytime);
 	}
 
@@ -1353,7 +1354,7 @@
 
 	/* the velocity needs to be converted back from cubic interpolation */
 	if(pind->keyed || pind->cache || point_vel)
-		mul_v3_fl(result->vel, frs_sec / dfra);
+		mul_v3_fl(result->vel, 1.f/invdt);
 }
 /************************************************/
 /*			Particles on a dm					*/
@@ -2954,7 +2955,7 @@
 			time = (float)k / (float)steps;
 			t = birthtime + time * (dietime - birthtime);
 			result.time = -t;
-			do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, &result);
+			do_particle_interpolation(psys, p, pa, t, &pind, &result);
 			copy_v3_v3(ca->co, result.co);
 
 			/* dynamic hair is in object space */
@@ -3133,7 +3134,7 @@
 			time = (float)k / (float)steps;
 			t = birthtime + time * (dietime - birthtime);
 			result.time = -t;
-			do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
+			do_particle_interpolation(psys, i, pa, t, &pind, &result);
 			copy_v3_v3(ca->co, result.co);
 
 			 /* non-hair points are already in global space */
@@ -3954,7 +3955,7 @@
 	ParticleThreadContext ctx; /* fake thread context for child modifiers */
 	ParticleInterpolationData pind;
 
-	float t, frs_sec = sim->scene->r.frs_sec;
+	float t;
 	float co[3], orco[3];
 	float hairmat[4][4];
 	int totpart = psys->totpart;
@@ -3982,7 +3983,7 @@
 		 * account when subdividing for instance */
 		pind.dm = psys_in_edit_mode(sim->scene, psys) ? NULL : psys->hair_out_dm;
 		init_particle_interpolation(sim->ob, psys, pa, &pind);
-		do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
+		do_particle_interpolation(psys, p, pa, t, &pind, state);
 
 		if(!keyed && !cached) {
 			if((pa->flag & PARS_REKEY)==0) {

Modified: trunk/blender/source/blender/makesdna/DNA_particle_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_particle_types.h	2011-02-06 11:17:22 UTC (rev 34669)
+++ trunk/blender/source/blender/makesdna/DNA_particle_types.h	2011-02-06 15:50:00 UTC (rev 34670)
@@ -459,7 +459,7 @@
 #define PSYS_ENABLED		16	/* deprecated */
 #define PSYS_HAIR_UPDATED	32  /* signal for updating hair particle mode */
 #define PSYS_DRAWING		64
-//#define PSYS_SOFT_BAKE		128
+#define PSYS_USE_IMAT		128
 #define PSYS_DELETE			256	/* remove particlesystem as soon as possible */
 #define PSYS_HAIR_DONE		512
 #define PSYS_KEYED			1024

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c	2011-02-06 11:17:22 UTC (rev 34669)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c	2011-02-06 15:50:00 UTC (rev 34670)
@@ -1492,13 +1492,13 @@
 	StrandBound *sbound= 0;
 	StrandRen *strand=0;
 	RNG *rng= 0;
-	float loc[3],loc1[3],loc0[3],mat[4][4],nmat[3][3],co[3],nor[3];
+	float loc[3],loc1[3],loc0[3],mat[4][4],nmat[3][3],co[3],nor[3],duplimat[4][4];
 	float strandlen=0.0f, curlen=0.0f;
 	float hasize, pa_size, r_tilt, r_length;
 	float pa_time, pa_birthtime, pa_dietime;
 	float random, simplify[2], pa_co[3];
 	const float cfra= BKE_curframe(re->scene);
-	int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0;
+	int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0, use_duplimat = 0;
 	int totchild=0;
 	int seed, path_nbr=0, orco1=0, num;
 	int totface, *origindex = 0;
@@ -1638,6 +1638,12 @@
 	copy_m3_m4(nmat, ob->imat);
 	transpose_m3(nmat);
 
+	if(psys->flag & PSYS_USE_IMAT) {
+		/* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */
+		mul_m4_m4m4(duplimat, psys->imat, ob->obmat);
+		use_duplimat = 1;
+	}
+
 /* 2.6 setup strand rendering */
 	if(part->ren_as == PART_DRAW_PATH && psys->pathcache){
 		path_nbr=(int)pow(2.0,(double) part->ren_step);
@@ -1949,6 +1955,9 @@
 					if(psys->parent)
 						mul_m4_v3(psys->parent->obmat, state.co);
 
+					if(use_duplimat)
+						mul_m4_v4(duplimat, state.co);
+
 					if(part->ren_as == PART_DRAW_BB) {
 						bb.random = random;
 						bb.size = pa_size;
@@ -1971,6 +1980,9 @@
 				if(psys->parent)
 					mul_m4_v3(psys->parent->obmat, state.co);
 
+				if(use_duplimat)
+					mul_m4_v4(duplimat, state.co);
+
 				if(part->ren_as == PART_DRAW_BB) {
 					bb.random = random;
 					bb.size = pa_size;
@@ -4345,7 +4357,7 @@
 	int i;
 
 	if(obr->psysindex) {
-		if((!obr->prev || obr->prev->ob != ob) && ob->type==OB_MESH) {
+		if((!obr->prev || obr->prev->ob != ob || (obr->prev->flag & R_INSTANCEABLE)==0) && ob->type==OB_MESH) {
 			/* the emitter mesh wasn't rendered so the modifier stack wasn't
 			 * evaluated with render settings */
 			DerivedMesh *dm;
@@ -4437,8 +4449,11 @@
 			}
 			if(obr->lay & vectorlay)
 				obr->flag |= R_NEED_VECTORS;
+			if(dob)
+				psys->flag |= PSYS_USE_IMAT;
 			init_render_object_data(re, obr, timeoffset);
 			psys_render_restore(ob, psys);
+			psys->flag &= ~PSYS_USE_IMAT;
 
 			/* only add instance for objects that have not been used for dupli */
 			if(!(ob->transflag & OB_RENDER_DUPLI)) {




More information about the Bf-blender-cvs mailing list