[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13815] trunk/blender/source/blender/ render/intern:

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Feb 22 14:21:42 CET 2008


Revision: 13815
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13815
Author:   blendix
Date:     2008-02-22 14:21:42 +0100 (Fri, 22 Feb 2008)

Log Message:
-----------

Bugfix: objects in groups with texture mapping Object now get texture
coordinates from the object as if they were in their original position,
untransformed by dupligroups or dupliverts. Otherwise the textures of
such objects would change depending on their position.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/include/render_types.h
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/texture.c

Modified: trunk/blender/source/blender/render/intern/include/render_types.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/render_types.h	2008-02-22 11:25:08 UTC (rev 13814)
+++ trunk/blender/source/blender/render/intern/include/render_types.h	2008-02-22 13:21:42 UTC (rev 13815)
@@ -276,6 +276,7 @@
 	short flag;
 
 	float dupliorco[3], dupliuv[2];
+	float (*duplitexmat)[4];
 
 	float *vectors;
 	int totvector;

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c	2008-02-22 11:25:08 UTC (rev 13814)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c	2008-02-22 13:21:42 UTC (rev 13815)
@@ -4100,6 +4100,48 @@
 	return NULL;
 }
 
+static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob)
+{
+	/* For duplis we need to have a matrix that transform the coordinate back
+	 * to it's original position, without the dupli transforms. We also check
+	 * the matrix is actually needed, to save memory on lots of dupliverts for
+	 * example */
+	static Object *lastob= NULL;
+	static int needtexmat= 0;
+
+	/* init */
+	if(!re) {
+		lastob= NULL;
+		needtexmat= 0;
+		return;
+	}
+
+	/* check if we actually need it */
+	if(lastob != dob->ob) {
+		Material ***material;
+		short a, *totmaterial;
+
+		lastob= dob->ob;
+		needtexmat= 0;
+
+		totmaterial= give_totcolp(dob->ob);
+		material= give_matarar(dob->ob);
+
+		if(totmaterial && material)
+			for(a= 0; a<*totmaterial; a++)
+				if((*material)[a] && (*material)[a]->texco & TEXCO_OBJECT)
+					needtexmat= 1;
+	}
+
+	if(needtexmat) {
+		float imat[4][4];
+
+		obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4);
+		Mat4Invert(imat, dob->mat);
+		MTC_Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0);
+	}
+}
+
 static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
 {
 	Object *ob= obr->ob;
@@ -4139,12 +4181,15 @@
 	re->totstrand += obr->totstrand;
 }
 
-static void add_render_object(Render *re, Object *ob, Object *par, int index, int timeoffset, int instanceable, int vectorlay)
+static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, int timeoffset, int vectorlay)
 {
 	ObjectRen *obr;
+	ObjectInstanceRen *obi;
 	ParticleSystem *psys;
-	int show_emitter, allow_render= 1, psysindex;
+	int show_emitter, allow_render= 1, index, psysindex;
 
+	index= (dob)? dob->index: 0;
+
 	/* the emitter has to be processed first (render levels of modifiers) */
 	/* so here we only check if the emitter should be rendered */
 	if(ob->particlesystem.first) {
@@ -4162,7 +4207,7 @@
 	/* one render object for the data itself */
 	if(allow_render) {
 		obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
-		if(instanceable) {
+		if((dob && !dob->animated) || (ob->flag & OB_RENDER_DUPLI)) {
 			obr->flag |= R_INSTANCEABLE;
 			Mat4CpyMat4(obr->obmat, ob->obmat);
 		}
@@ -4171,8 +4216,10 @@
 		init_render_object_data(re, obr, timeoffset);
 
 		/* only add instance for objects that have not been used for dupli */
-		if(!(ob->transflag & OB_RENDER_DUPLI))
-			RE_addRenderInstance(re, obr, ob, par, index, 0, NULL);
+		if(!(ob->transflag & OB_RENDER_DUPLI)) {
+			obi= RE_addRenderInstance(re, obr, ob, par, index, 0, NULL);
+			if(dob) set_dupli_tex_mat(re, obi, dob);
+		}
 		else
 			find_dupli_instances(re, obr);
 	}
@@ -4182,7 +4229,7 @@
 		psysindex= 1;
 		for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
 			obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
-			if(instanceable) {
+			if((dob && !dob->animated) || (ob->flag & OB_RENDER_DUPLI)) {
 				obr->flag |= R_INSTANCEABLE;
 				Mat4CpyMat4(obr->obmat, ob->obmat);
 			}
@@ -4192,8 +4239,10 @@
 			psys_render_restore(ob, psys);
 
 			/* only add instance for objects that have not been used for dupli */
-			if(!(ob->transflag & OB_RENDER_DUPLI))
-				RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL);
+			if(!(ob->transflag & OB_RENDER_DUPLI)) {
+				obi= RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL);
+				if(dob) set_dupli_tex_mat(re, obi, dob);
+			}
 			else
 				find_dupli_instances(re, obr);
 		}
@@ -4202,7 +4251,7 @@
 
 /* par = pointer to duplicator parent, needed for object lookup table */
 /* index = when duplicater copies same object (particle), the counter */
-static void init_render_object(Render *re, Object *ob, Object *par, int index, int timeoffset, int instanceable, int vectorlay)
+static void init_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, int timeoffset, int vectorlay)
 {
 	static double lasttime= 0.0;
 	double time;
@@ -4211,7 +4260,7 @@
 	if(ob->type==OB_LAMP)
 		add_render_lamp(re, ob);
 	else if(render_object_type(ob->type))
-		add_render_object(re, ob, par, index, timeoffset, instanceable, vectorlay);
+		add_render_object(re, ob, par, dob, timeoffset, vectorlay);
 	else {
 		MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
 		MTC_Mat4Invert(ob->imat, mat);
@@ -4432,8 +4481,10 @@
 	ObjectInstanceRen *obi;
 	Scene *sce;
 	float mat[4][4];
-	int lay, vectorlay;
+	int lay, vectorlay, redoimat= 0;
 
+	set_dupli_tex_mat(NULL, NULL, NULL); /* init */
+
 	for(SETLOOPER(re->scene, base)) {
 		ob= base->object;
 		/* imat objects has to be done here, since displace can have texture using Object map-input */
@@ -4457,13 +4508,15 @@
 		if(ob->flag & OB_DONE) {
 			if(ob->transflag & OB_RENDER_DUPLI)
 				if(allow_render_object(ob, nolamps, onlyselected, actob))
-					init_render_object(re, ob, NULL, 0, timeoffset, 1, vectorlay);
+					init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
 		}
 		else if((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
 			if((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
 				DupliObject *dob;
 				ListBase *lb;
 
+				redoimat= 1;
+
 				dupli_render_particle_set(re, ob, timeoffset, 0, 1);
 				lb= object_duplilist(sce, ob);
 				dupli_render_particle_set(re, ob, timeoffset, 0, 0);
@@ -4495,6 +4548,7 @@
 						if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) {
 							Mat4MulMat4(mat, dob->mat, re->viewmat);
 							obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
+							set_dupli_tex_mat(re, obi, dob);
 
 							if(dob->type != OB_DUPLIGROUP) {
 								VECCOPY(obi->dupliorco, dob->orco);
@@ -4508,7 +4562,7 @@
 							}
 						}
 						else
-							init_render_object(re, obd, ob, dob->index, timeoffset, !dob->animated, vectorlay);
+							init_render_object(re, obd, ob, dob, timeoffset, vectorlay);
 
 						psysindex= 1;
 						for(psys=obd->particlesystem.first; psys; psys=psys->next) {
@@ -4524,6 +4578,8 @@
 									if(obd->transflag & OB_RENDER_DUPLI)
 										find_dupli_instances(re, obr);
 								}
+
+								set_dupli_tex_mat(re, obi, dob);
 							}
 						}
 						
@@ -4533,22 +4589,31 @@
 						}
 					}
 					else
-						init_render_object(re, obd, ob, dob->index, timeoffset, !dob->animated, vectorlay);
+						init_render_object(re, obd, ob, dob, timeoffset, vectorlay);
 					
 					if(re->test_break()) break;
 				}
 				free_object_duplilist(lb);
 
 				if(allow_render_object(ob, nolamps, onlyselected, actob))
-					init_render_object(re, ob, NULL, 0, timeoffset, 0, vectorlay);
+					init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
 			}
 			else if(allow_render_object(ob, nolamps, onlyselected, actob))
-				init_render_object(re, ob, NULL, 0, timeoffset, 0, vectorlay);
+				init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
 		}
 
 		if(re->test_break()) break;
 	}
 
+	/* imat objects has to be done again, since groups can mess it up */
+	if(redoimat) {
+		for(SETLOOPER(re->scene, base)) {
+			ob= base->object;
+			MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+			MTC_Mat4Invert(ob->imat, mat);
+		}
+	}
+
 	if(!re->test_break())
 		RE_makeRenderInstances(re);
 }

Modified: trunk/blender/source/blender/render/intern/source/texture.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/texture.c	2008-02-22 11:25:08 UTC (rev 13814)
+++ trunk/blender/source/blender/render/intern/source/texture.c	2008-02-22 13:21:42 UTC (rev 13815)
@@ -1475,6 +1475,8 @@
 					dx= dxt;
 					dy= dyt;
 					VECCOPY(tempvec, shi->co);
+					if(shi->obi->duplitexmat)
+						MTC_Mat4MulVecfl(shi->obi->duplitexmat, tempvec);
 					MTC_Mat4MulVecfl(ob->imat, tempvec);
 					if(shi->osatex) {
 						VECCOPY(dxt, shi->dxco);





More information about the Bf-blender-cvs mailing list