|  |  |  | @@ -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 @@ static void group_duplilist(ListBase *lb, Object *ob, int level) | 
		
	
		
			
				|  |  |  |  | 			 | 
		
	
		
			
				|  |  |  |  | 			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 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n | 
		
	
		
			
				|  |  |  |  | 		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 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac | 
		
	
		
			
				|  |  |  |  | 					/* 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 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float (*par_spac | 
		
	
		
			
				|  |  |  |  | 	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 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ | 
		
	
		
			
				|  |  |  |  | 					/* 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 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ | 
		
	
		
			
				|  |  |  |  | 							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 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float (*par_space_ | 
		
	
		
			
				|  |  |  |  | 	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 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy | 
		
	
		
			
				|  |  |  |  | 	/* 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 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy | 
		
	
		
			
				|  |  |  |  | 		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,9 +741,16 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			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) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -724,7 +760,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		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 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, ParticleSy | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			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); | 
		
	
		
			
				|  |  |  |  | 					 | 
		
	
		
			
				|  |  |  |  | 					if(!hair) { | 
		
	
		
			
				|  |  |  |  | 						q = vectoquat(xvec, ob->trackflag, ob->upflag); | 
		
	
		
			
				|  |  |  |  | 					QuatToMat3(q, obrotmat); | 
		
	
		
			
				|  |  |  |  | 						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 font_duplilist(ListBase *lb, Object *par, int level) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* ***************************** */ | 
		
	
		
			
				|  |  |  |  | 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 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, | 
		
	
		
			
				|  |  |  |  | 	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) { | 
		
	
	
		
			
				
					
					|  |  |  |   |