[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13156] trunk/blender/source/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Jan 7 17:26:43 CET 2008


Revision: 13156
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13156
Author:   blendix
Date:     2008-01-07 17:26:41 +0100 (Mon, 07 Jan 2008)

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

Particle object and group visualization now also work for hair, to
make for example feathers. Also made dupliparts work within groups.

One issue still is that in particle editmode, the duplis can interfere
with brushes and selection, though tweaking the dupli object position
can alleviate the problem.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/anim.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/src/drawobject.c
    trunk/blender/source/blender/src/editparticle.c

Modified: trunk/blender/source/blender/blenkernel/intern/anim.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim.c	2008-01-07 15:44:45 UTC (rev 13155)
+++ trunk/blender/source/blender/blenkernel/intern/anim.c	2008-01-07 16:26:41 UTC (rev 13156)
@@ -47,6 +47,7 @@
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
@@ -76,7 +77,7 @@
 
 #define MAX_DUPLI_RECUR 4
 
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level);
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level);
 
 void free_path(Path *path)
 {
@@ -327,7 +328,7 @@
 			
 			if(go->ob->transflag & OB_DUPLI) {
 				Mat4CpyMat4(dob->ob->obmat, dob->mat);
-				object_duplilist_recursive((ID *)group, go->ob, lb, &ob->obmat, level+1);
+				object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1);
 				Mat4CpyMat4(dob->ob->obmat, dob->omat);
 			}
 		}
@@ -412,12 +413,12 @@
 		float tmpmat[4][4];
 		Mat4CpyMat4(tmpmat, vdd->ob->obmat);
 		Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
-		object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, &obmat, vdd->level+1);
+		object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1);
 		Mat4CpyMat4(vdd->ob->obmat, tmpmat);
 	}
 }
 
-static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level)
+static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
 {
 	Object *ob, *ob_iter;
 	Base *base = NULL;
@@ -473,11 +474,11 @@
 					/* par_space_mat - only used for groups so we can modify the space dupli's are in
 					   when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
 					*/
-					if (par_space_mat) {
-						Mat4MulMat4(vdd.obmat, ob->obmat, *par_space_mat);
-					} else {
+					if(par_space_mat)
+						Mat4MulMat4(vdd.obmat, ob->obmat, par_space_mat);
+					else
 						Mat4CpyMat4(vdd.obmat, ob->obmat);
-					}
+
 					vdd.id= id;
 					vdd.level= level;
 					vdd.lb= lb;
@@ -512,7 +513,7 @@
 	dm->release(dm);
 }
 
-static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_mat)[][4], int level)
+static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level)
 {
 	Object *ob, *ob_iter;
 	Base *base = NULL;
@@ -583,11 +584,10 @@
 					/* par_space_mat - only used for groups so we can modify the space dupli's are in
 					   when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
 					*/
-					if (par_space_mat) {
-						Mat4MulMat4(ob__obmat, ob->obmat, *par_space_mat);
-					} else {
+					if(par_space_mat)
+						Mat4MulMat4(ob__obmat, ob->obmat, par_space_mat);
+					else
 						Mat4CpyMat4(ob__obmat, ob->obmat);
-					}
 					
 					Mat3CpyMat4(imat, ob->parentinv);
 						
@@ -638,7 +638,7 @@
 							float tmpmat[4][4];
 							Mat4CpyMat4(tmpmat, ob->obmat);
 							Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
-							object_duplilist_recursive((ID *)id, ob, lb, &ob->obmat, level+1);
+							object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1);
 							Mat4CpyMat4(ob->obmat, tmpmat);
 						}
 					}
@@ -660,17 +660,44 @@
 	dm->release(dm);
 }
 
-static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSystem *psys, int level)
+static void particle_dupli_path_rotation(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4])
 {
+	float loc[3], nor[3], vec[3], side[3];
+
+	VecSubf(vec, (cache+1)->co, cache->co);
+	Normalize(vec);
+
+	if(pa)
+		psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+	else
+		psys_particle_on_emitter(ob, psmd,
+			(part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+			cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+	
+	Crossf(side, nor, vec);
+	Normalize(side);
+	Crossf(nor, vec, side);
+
+	Mat4One(mat);
+	VECCOPY(mat[0], vec);
+	VECCOPY(mat[1], side);
+	VECCOPY(mat[2], nor);
+}
+
+static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level)
+{
 	GroupObject *go;
-	Object *ob, **oblist=0;
+	Object *ob=0, **oblist=0;
 	ParticleSettings *part;
 	ParticleData *pa;
 	ParticleKey state;
+	ParticleCacheKey *cache;
+	ParticleSystemModifierData *psmd;
 	float ctime, pa_time;
-	float tmat[4][4], mat[3][3], obrotmat[3][3], parotmat[3][3], size=0.0;
+	float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0;
+	float obmat[4][4], (*obmatlist)[4][4]=0;
 	float xvec[3] = {-1.0, 0.0, 0.0}, *q;
-	int lay, a, k, step_nbr = 0, counter;
+	int lay, a, b, k, step_nbr = 0, counter, hair = 0;
 	int totpart, totchild, totgroup=0, pa_num;
 
 	if(psys==0) return;
@@ -678,9 +705,8 @@
 	/* simple preventing of too deep nested groups */
 	if(level>MAX_DUPLI_RECUR) return;
 	
-	if (GS(id->name)!=ID_SCE) return; /* No support for groups YET! TODO */
-	
 	part=psys->part;
+	psmd= psys_get_modifier(par, psys);
 
 	if(part==0) return;
 
@@ -700,6 +726,9 @@
 		else
 			step_nbr = 0;
 
+		if(psys->flag & PSYS_HAIR_DONE)
+			hair= (totchild == 0 || psys->childcache) && psys->pathcache;
+
 		psys->lattice = psys_get_lattice(par, psys);
 
 		if(part->draw_as==PART_DRAW_GR) {
@@ -712,10 +741,17 @@
 			}
 
 			oblist= MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
+			obmatlist= MEM_callocN(totgroup*sizeof(float)*4*4, "dupgroup obmat list");
 			go= part->dup_group->gobject.first;
-			for(a=0; a<totgroup; a++, go=go->next)
+			for(a=0; a<totgroup; a++, go=go->next) {
 				oblist[a]=go->ob;
+				Mat4CpyMat4(obmatlist[a], go->ob->obmat);
+			}
 		}
+		else {
+			ob = part->dup_ob;
+			Mat4CpyMat4(obmat, ob->obmat);
+		}
 
 		if(totchild==0 || part->draw & PART_DRAW_PARENT)
 			a=0;
@@ -724,7 +760,8 @@
 
 		for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) {
 			if(a<totpart) {
-				if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
+				if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP))
+					continue;
 
 				pa_num=pa->num;
 
@@ -742,61 +779,91 @@
 
 			if(part->draw_as==PART_DRAW_GR) {
 				if(part->draw&PART_DRAW_RAND_GR)
-					ob = oblist[BLI_rand() % totgroup];
+					b= BLI_rand() % totgroup;
 				else if(part->from==PART_FROM_PARTICLE)
-					ob = oblist[pa_num % totgroup];
+					b= pa_num % totgroup;
 				else
-					ob = oblist[a % totgroup];
+					b= a % totgroup;
+
+				ob = oblist[b];
+				Mat4CpyMat4(obmat, obmatlist[b]);
 			}
-			else
-				ob = part->dup_ob;
 
 			for(k=0; k<=step_nbr; k++, counter++) {
-				if(step_nbr) {
+				if(hair) {
+					if(a < totpart) {
+						cache = psys->pathcache[a];
+						particle_dupli_path_rotation(par, part, psmd, pa, 0, cache, pamat);
+					}
+					else {
+						ChildParticle *cpa= psys->child+(a-totpart);
+						cache = psys->childcache[a-totpart];
+						particle_dupli_path_rotation(par, part, psmd, 0, cpa, cache, pamat);
+					}
+
+					VECCOPY(pamat[3], cache->co);
+				}
+				else if(step_nbr) {
 					state.time = (float)k / (float)step_nbr;
 					psys_get_particle_on_path(par, psys, a, &state, 0);
+
+					QuatToMat4(state.rot, pamat);
+					VECCOPY(pamat[3], state.co);
+					pamat[3][3]= 1.0f;
 				}
 				else {
 					state.time = -1.0;
 					if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
 						continue;
+
+					QuatToMat4(state.rot, pamat);
+					VECCOPY(pamat[3], state.co);
+					pamat[3][3]= 1.0f;
 				}
 
-				QuatToMat3(state.rot, parotmat);
-
 				if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
-					for(go= part->dup_group->gobject.first; go; go= go->next) {
+					for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
 
-						Mat4CpyMat4(tmat, go->ob->obmat);
-						Mat4MulMat43(tmat, go->ob->obmat, parotmat);
+						Mat4MulMat4(tmat, obmatlist[b], pamat);
 						Mat4MulFloat3((float *)tmat, size);
+						if(par_space_mat)
+							Mat4MulMat4(mat, tmat, par_space_mat);
+						else
+							Mat4CpyMat4(mat, tmat);
 
-						VECADD(tmat[3], go->ob->obmat[3], state.co);
-
-						new_dupli_object(lb, go->ob, tmat, par->lay, counter, OB_DUPLIPARTS);
+						new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS);
 					}
 				}
 				else {
 					/* to give ipos in object correct offset */
 					where_is_object_time(ob, ctime-pa_time);
 					
-					q = vectoquat(xvec, ob->trackflag, ob->upflag);
-					QuatToMat3(q, obrotmat);
+					if(!hair) {
+						q = vectoquat(xvec, ob->trackflag, ob->upflag);
+						QuatToMat4(q, obrotmat);
+						obrotmat[3][3]= 1.0f;
 
-					Mat3MulMat3(mat, parotmat, obrotmat);
-					Mat4CpyMat4(tmat, ob->obmat);
-					Mat4MulMat43(tmat, ob->obmat, mat);
+						Mat4MulMat4(mat, obrotmat, pamat);
+					}
+					else
+						Mat4CpyMat4(mat, pamat);
+
+					Mat4MulMat4(tmat, obmat, mat);
 					Mat4MulFloat3((float *)tmat, size);
+					if(par_space_mat)
+						Mat4MulMat4(mat, tmat, par_space_mat);
+					else
+						Mat4CpyMat4(mat, tmat);
 
-					VECCOPY(tmat[3], state.co);
-
-					new_dupli_object(lb, ob, tmat, par->lay, counter, OB_DUPLIPARTS);
+					new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS);
 				}
 			}
 		}
 	}
 	if(oblist)
 		MEM_freeN(oblist);
+	if(obmatlist)
+		MEM_freeN(obmatlist);
 
 	if(psys->lattice) {
 		end_latt_deform();
@@ -877,7 +944,7 @@
 }
 
 /* ***************************** */
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float (*par_space_mat)[][4], int level)
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level)
 {	
 	if((ob->transflag & OB_DUPLI)==0)
 		return;
@@ -896,7 +963,7 @@
 	if(ob->transflag & OB_DUPLIPARTS) {
 		ParticleSystem *psys = ob->particlesystem.first;
 		for(; psys; psys=psys->next)
-			new_particle_duplilist(duplilist, id, ob, psys, level+1);
+			new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1);
 	}
 	else if(ob->transflag & OB_DUPLIVERTS) {
 		if(ob->type==OB_MESH) {

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list