[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12611] branches/particles/source/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Sat Nov 17 01:10:36 CET 2007


Revision: 12611
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12611
Author:   blendix
Date:     2007-11-17 01:10:35 +0100 (Sat, 17 Nov 2007)

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

Particle Branch
===============

- Fix add brush on triangles, and make it work on derived meshes
  again (might have broken the latter myself).
- Fix memory leak deleting particles.
- Fix writing past end of path cache array with 0 particles.
- Fix particle mapping for triangles in the base mesh, only worked
  for quads.
- Add orientation mapping, previously only the position was mapped
  correctly to e.g. subsurf, but the direction of the particle was
  still wrong. This changes the way the hair -> object or global
  matrix is computed, I tried to make it compatible, but might break
  existing particle systems.
- Fix crash with e.g. build modifier before a particle system.

Modified Paths:
--------------
    branches/particles/source/blender/blenkernel/BKE_particle.h
    branches/particles/source/blender/blenkernel/intern/modifier.c
    branches/particles/source/blender/blenkernel/intern/particle.c
    branches/particles/source/blender/blenkernel/intern/particle_system.c
    branches/particles/source/blender/render/intern/source/convertblender.c
    branches/particles/source/blender/src/editparticle.c
    branches/particles/source/blender/src/transform_conversions.c

Modified: branches/particles/source/blender/blenkernel/BKE_particle.h
===================================================================
--- branches/particles/source/blender/blenkernel/BKE_particle.h	2007-11-16 15:46:59 UTC (rev 12610)
+++ branches/particles/source/blender/blenkernel/BKE_particle.h	2007-11-17 00:10:35 UTC (rev 12611)
@@ -191,7 +191,7 @@
 
 void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
 
-void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan);
+void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
 
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
@@ -227,7 +227,7 @@
 //void psys_face_mat(struct DerivedMesh *dm, struct ParticleData *pa, float mat[][4]);
 void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
 //void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
-void psys_mat_hair_to_object(struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
+void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
 void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
 
 struct KDTreeNode *alloc_kdtree(int nodes);
@@ -244,13 +244,13 @@
 void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
 
 int psys_intersect_dm(struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint);
-void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan);
+void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan);
 
 /* particle_system.c */
 void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
 void reset_particle(struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob, float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
 
-int psys_particle_dm_face_lookup(struct DerivedMesh *dm, int index, float *fuv, struct LinkNode *node);
+int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fuv, struct LinkNode *node);
 
 /* ParticleEffectorCache->type */
 #define PSYS_EC_EFFECTOR	1

Modified: branches/particles/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/modifier.c	2007-11-16 15:46:59 UTC (rev 12610)
+++ branches/particles/source/blender/blenkernel/intern/modifier.c	2007-11-17 00:10:35 UTC (rev 12611)
@@ -5378,7 +5378,8 @@
 	return 0.0;
 }
 static void explodeModifier_createFacepa(ExplodeModifierData *emd,
-										 ParticleSystemModifierData *psmd, DerivedMesh *dm)
+										 ParticleSystemModifierData *psmd,
+										 Object *ob, DerivedMesh *dm)
 {
 	ParticleSystem *psys=psmd->psys;
 	MFace *fa=0, *mface=0;
@@ -5428,7 +5429,7 @@
 	/* make tree of emitter locations */
 	tree=alloc_kdtree(totpart);
 	for(p=0,pa=psys->particles,cur=tree; p<totpart; p++,pa++,cur++){
-		psys_particle_on_dm(dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,cur->co,0,0,0);
+		psys_particle_on_dm(ob,dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,cur->co,0,0,0);
 		cur->nbr=p;
 		if(p) insert_into_kdtree(tree,cur);
 	}
@@ -6000,7 +6001,7 @@
 	for(i=0, pa=pars; i<=totpart; i++, pa++){
 
 		if(i!=totpart){
-			psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,loc0,nor,0,0);
+			psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,loc0,nor,0,0);
 			Mat4MulVecfl(ob->obmat,loc0);
 
 			state.time=cfra;
@@ -6187,7 +6188,7 @@
 			if(emd->flag & eExplodeFlag_CalcFaces)
 				emd->flag &= ~eExplodeFlag_CalcFaces;
 
-			explodeModifier_createFacepa(emd,psmd,derivedData);
+			explodeModifier_createFacepa(emd,psmd,ob,derivedData);
 		}
 
 		/* 2. create new mesh */

Modified: branches/particles/source/blender/blenkernel/intern/particle.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/particle.c	2007-11-16 15:46:59 UTC (rev 12610)
+++ branches/particles/source/blender/blenkernel/intern/particle.c	2007-11-17 00:10:35 UTC (rev 12611)
@@ -561,7 +561,7 @@
 		
 		return mumv*v1 + muv*v2 + uv*v3 + umv*v4;
 	}
-	else{
+	else {
 		/* mirror triangle uv coordinates when on other side */
 		if(u + v > 1.0f) {
 			u= 1.0f-u;
@@ -785,19 +785,45 @@
 	return 0.0;
 }
 
+/* conversion of pa->fuv to origspace layer coordinates */
+static void psys_uv_to_origspace(int quad, float *fuv, float *uv)
+{
+	uv[0]= fuv[0];
+	uv[1]= fuv[1];
+
+	if(!quad) {
+		/* mirror triangle uv coordinates when on other side */
+		if(uv[0]+uv[1] > 1.0f) {
+			uv[0]= 1.0f-uv[0];
+			uv[1]= 1.0f-uv[1];
+		}
+
+		uv[1]= 1.0f-uv[0]-uv[1];
+	}
+	else
+		uv[1]= 1.0f-uv[1];
+}
+
 /* find the derived mesh face for a particle, set the mf passed.
 This is slow, can be optimized but only for many lookups, return the face lookup index*/
-int psys_particle_dm_face_lookup(DerivedMesh *dm, int index, float *fuv, struct LinkNode *node)
+int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *fuv, struct LinkNode *node)
 {
-	MFace *mface = dm->getFaceData(dm,index,CD_MFACE);
-	int *origindex, *oi, totface, dmface_index;
-	OrigSpaceFace *osface=dm->getFaceDataArray(dm, CD_ORIGSPACE);
-	origindex = oi = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+	Mesh *me= (Mesh*)ob->data;
+	MFace *mface;
+	OrigSpaceFace *osface;
+	int *origindex;
+	int quad, findex, totface;
+	float uv[2], (*faceuv)[2];
+
+	mface = dm->getFaceDataArray(dm, CD_MFACE);
+	origindex = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+	osface = dm->getFaceDataArray(dm, CD_ORIGSPACE);
+
 	totface = dm->getNumFaces(dm);
 	
-	if (osface==NULL) {
+	if(osface==NULL || origindex==NULL) {
 		/* Assume we dont need osface data */
-		if (index < totface) {
+		if (index <totface) {
 			printf("\tNO CD_ORIGSPACE, assuming not needed\n");
 			return index;
 		} else {
@@ -805,41 +831,51 @@
 			return -1;
 		}
 	}
+	else if(index >= me->totface)
+		return -1; /* index not in the original mesh */
+
+	psys_uv_to_origspace(me->mface[index].v4, fuv, uv);
 	
-	if (node) { /* we have a linked list of faces that we use, faster! */
-		OrigSpaceFace *osface_node;
-		for(;node;node=node->next) {
-			dmface_index = (int)node->link;
-			osface_node = osface + dmface_index;
-			if ( mface->v4 ) { /* check that this intersects - Its possible this misses :/ - could also check its not between */
-				if (IsectPQ2Df(fuv, osface_node->uv[0], osface_node->uv[1], osface_node->uv[2], osface_node->uv[3])) {
-					return dmface_index;
-				}
-			} else if (IsectPT2Df(fuv, osface_node->uv[0], osface_node->uv[1], osface_node->uv[2])) {
-				return dmface_index;
+	if(node) { /* we have a linked list of faces that we use, faster! */
+		for(;node; node=node->next) {
+			findex= (int)node->link;
+			faceuv= osface[findex].uv;
+			quad= mface[findex].v4;
+
+			/* check that this intersects - Its possible this misses :/ -
+			 * could also check its not between */
+			if(quad) {
+				if(IsectPQ2Df(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
+					return findex;
 			}
+			else if(IsectPT2Df(uv, faceuv[0], faceuv[1], faceuv[2]))
+				return findex;
 		}
-	} else { /* if we have no node, try every face */
-		mface = dm->getFaceDataArray(dm,CD_MFACE);
-		for (dmface_index=0; dmface_index<totface; dmface_index++, oi++, mface++, osface++) {
-					//printf("\tTesting dm_index:%i orig_index:%i looking for %i fuv(%f, %f)\n", i, *oi, index, fuv[0], fuv[1]);
-			if (*oi == index) {
-				if ( mface->v4 ) { /* check that this intersects - Its possible this misses :/ - could also check its not between */
-					if (IsectPQ2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3])) {
-						return dmface_index;
-					}
-				} else if (IsectPT2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2])) {
-					return dmface_index;
+	}
+	else { /* if we have no node, try every face */
+		for(findex=0; findex<totface; findex++) {
+			if(origindex[findex] == index) {
+				faceuv= osface[findex].uv;
+				quad= mface[findex].v4;
+
+				/* check that this intersects - Its possible this misses :/ -
+				 * could also check its not between */
+				if(quad) {
+					if(IsectPQ2Df(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
+						return findex;
 				}
+				else if(IsectPT2Df(uv, faceuv[0], faceuv[1], faceuv[2]))
+					return findex;
 			}
 		}
 	}
+
 	return -1;
 }
 
 /* interprets particle data to get a point on a mesh in object space */
 #define PARTICLE_ERROR(_nor, _vec) _vec[0]=_vec[1]=_vec[2]=0.0; if(_nor){ _nor[0]=_nor[1]=0.0; _nor[2]=1.0; }
-void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan)
+void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan)
 {
 	if(index < 0){ /* 'no dm' error has happened! */
 		PARTICLE_ERROR(nor, vec);
@@ -885,42 +921,34 @@
 		/* Only face supported at the moment */
 		if (from==PART_FROM_FACE) {
 			/* find a face on the derived mesh that uses this face */
-			MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+			Mesh *me= (Mesh*)ob->data;
+			MVert *mvert;
 			MFace *mface;
+			MTFace *mtface;
+			OrigSpaceFace *osface;
+			int *origindex;
+			int i, totface;
 			
-			int *origindex, *oi, totface, i;
-			MTFace *mtface=0;
-			OrigSpaceFace *osface=0;
-			int uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list