[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12459] branches/particles/source/blender: work in progress commit, no more particles refering to verts, subsurf level change updates hair

Campbell Barton cbarton at metavr.com
Sat Nov 3 19:17:22 CET 2007


Revision: 12459
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12459
Author:   campbellbarton
Date:     2007-11-03 19:17:22 +0100 (Sat, 03 Nov 2007)

Log Message:
-----------
work in progress commit, no more particles refering to verts, subsurf level change updates hair

Modified Paths:
--------------
    branches/particles/source/blender/blenkernel/BKE_particle.h
    branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
    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/makesdna/DNA_particle_types.h
    branches/particles/source/blender/src/editparticle.c

Modified: branches/particles/source/blender/blenkernel/BKE_particle.h
===================================================================
--- branches/particles/source/blender/blenkernel/BKE_particle.h	2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/BKE_particle.h	2007-11-03 18:17:22 UTC (rev 12459)
@@ -247,7 +247,7 @@
 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 deform_only, int from, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan);
+void psys_particle_on_dm(struct DerivedMesh *dm, int deform_only, 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, Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);

Modified: branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/DerivedMesh.c	2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/DerivedMesh.c	2007-11-03 18:17:22 UTC (rev 12459)
@@ -2184,6 +2184,11 @@
 			/* set the DerivedMesh to only copy needed data */
 			DM_set_only_copy(dm, (CustomDataMask)curr->link);
 
+			/* TODO PARTICLE - this is probably a bad place to add the layer, find a new place to do this */
+			if (modifiers_isParticleEnabled(ob) && (CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))==0) {
+				CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm));
+			}
+			
 			ndm = mti->applyModifierEM(md, ob, em, dm);
 
 			if (ndm) {

Modified: branches/particles/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/modifier.c	2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/modifier.c	2007-11-03 18:17:22 UTC (rev 12459)
@@ -4984,7 +4984,7 @@
 	
 	/* TODO - Particles only need this if they are after a non deform modifier, for now do it always
 	These should be calculated on the fly */
-	dataMask |= (1 << CD_MASK_ORIGSPACE);
+	dataMask |= CD_MASK_ORIGSPACE;
 	
 	return dataMask;
 }
@@ -5095,6 +5095,9 @@
 		if(psmd->flag & eParticleSystemFlag_Loaded)
 			psmd->flag &= ~eParticleSystemFlag_Loaded;
 		else{
+			/* TODO PARTICLE - Added this so changing subsurf under hair updates it
+			should it be done elsewhere? - Campbell */
+			psys->recalc |= PSYS_RECALC_HAIR;
 			psys->recalc |= PSYS_DISTR;
 			psmd->flag |= eParticleSystemFlag_DM_changed;
 		}
@@ -5105,8 +5108,8 @@
 		psmd->flag |= eParticleSystemFlag_psys_updated;
 		psmd->flag &= ~eParticleSystemFlag_DM_changed;
 	}
+}
 
-}
 static void particleSystemModifier_deformVertsEM(
                 ModifierData *md, Object *ob, EditMesh *editData,
                 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
@@ -5430,7 +5433,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,deform_only,psys->part->from,pa->num,pa->fuv,cur->co,0,0,0);
+		psys_particle_on_dm(dm,deform_only,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);
 	}

Modified: branches/particles/source/blender/blenkernel/intern/particle.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/particle.c	2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/particle.c	2007-11-03 18:17:22 UTC (rev 12459)
@@ -55,6 +55,7 @@
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
+#include "BLI_linklist.h"
 
 #include "BKE_anim.h"
 
@@ -594,6 +595,9 @@
 		//}
 	}
 }
+
+
+
 /************************************************/
 /*			Particles on a dm					*/
 /************************************************/
@@ -773,9 +777,64 @@
 	}
 	return 0.0;
 }
+
+/* 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)
+{
+	MFace *mface=dm->getFaceData(dm,index,CD_MFACE);
+	int *origindex, *oi, totface, i;
+	OrigSpaceFace *osface=dm->getFaceDataArray(dm, CD_ORIGSPACE);
+	origindex = oi = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+	totface = dm->getNumFaces(dm);
+	
+	if (osface==NULL) {
+		/* Assume we dont need osface data */
+		if (index < totface) {
+			printf("\tNO CD_ORIGSPACE, assuming not needed\n");
+			return index;
+		} else {
+			printf("\tNO CD_ORIGSPACE, error out of range\n");
+			return -1;
+		}
+	}
+	
+	if (node) { /* we have a linked list of faces that we use, faster! */
+		int node_index;
+		OrigSpaceFace *osface_node;
+		for(;node;node=node->next) {
+			node_index = (int *)node->link;
+			osface_node = osface+node_index;
+			if (*(oi+node_index) == 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 i;
+					}
+				} else if (IsectPT2Df(fuv, osface_node->uv[0], osface_node->uv[1], osface_node->uv[2])) {
+					return i;
+				}
+			}
+		}
+	} else { /* if we have no node, try every face */
+		for (i=0; i<totface; i++, 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 i;
+					}
+				} else if (IsectPT2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2])) {
+					return i;
+				}
+			}
+		}
+	}
+	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 deform_only, int from, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan)
+void psys_particle_on_dm(DerivedMesh *dm, int deform_only, 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);
@@ -784,7 +843,7 @@
 	
 	if (deform_only) {
 		/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
-		float temp1[3], temp2[3];
+		float temp1[3];
 		if(from == PART_FROM_VERT) {
 			dm->getVertCo(dm,index,vec);
 			if(nor){
@@ -821,15 +880,15 @@
 		/* Only face supported at the moment */
 		if (from==PART_FROM_FACE) {
 			/* find a face on the derived mesh that uses this face */
-			MFace *mface=dm->getFaceDataArray(dm,CD_MFACE);
 			MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+			MFace *mface;
 			
 			int *origindex, *oi, totface, i;
 			MTFace *mtface=0;
 			OrigSpaceFace *osface=0;
 			int uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
 			int osf_index=CustomData_get_layer_index(&dm->faceData,CD_ORIGSPACE);
-			int foundface=0; /* its possibe we dont fine the face we came from - it could have even been removed by a modifier */
+			
 			CustomDataLayer *layer_uv, *layer_osf;
 			
 			/* we need to modify the original fuv for its uv in relation to the derived mesh face)
@@ -849,7 +908,6 @@
 			origindex = oi = dm->getFaceDataArray(dm, CD_ORIGINDEX);
 			totface = dm->getNumFaces(dm);
 			
-
 			/* For this to work we need origindex and OrigSpace coords */
 			if (origindex==NULL || osf_index<0) {
 				PARTICLE_ERROR(nor, vec);
@@ -860,53 +918,45 @@
 			if (uv_index>=0)
 				layer_uv=&dm->faceData.layers[uv_index];
 			
-			//printf("Lookup on particle %i\n", index);
-			for (i=0; i<totface; i++, oi++, mface++) {
-				// 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) {
-					/* check that this intersects - Its possible this misses :/ - could also check its not between */
-					
-					/* uv's are optional */
-					if (uv_index>=0)
-						mtface= &((MTFace*)layer_uv->data)[i];
-					
-					osface= &((OrigSpaceFace*)layer_osf->data)[i];
-					
-					if ( mface->v4 ) {
-						if (IsectPQ2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3])) {
-							/* quads use a totaly different way of calculating the fuv_mod */
-							PointInQuad2DUV(osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3], fuv, fuv_mod);
-							psys_interpolate_face(mvert,mface,mtface,fuv_mod,vec,nor,utan,vtan);
-							foundface = 1;
-							break;
-						}
-					} else if (IsectPT2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2])) {
-						/* generate a new fuv, (this is possibly a non optimal solution,
-						 * since we only need 2d calculation but use 3d func's)
-						 * 
-						 * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
-						 * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
-						 * .This means the new values will be correct in relation to the derived meshes face.
-						 */
-						Vec2Copyf(v0, osface->uv[0]);
-						Vec2Copyf(v1, osface->uv[1]);
-						Vec2Copyf(v2, osface->uv[2]);
-						
-						/* Doing this in 3D is not nice */
-						LineIntersectsTriangleUV(p1, p2, v0, v1, v2, &lambda, fuv_mod);
-						//fuv_mod[1] = 1.0f-fuv_mod[1];
-						psys_interpolate_face(mvert,mface,mtface,fuv_mod,vec,nor,utan,vtan);
-						foundface = 1;
-						break;
-					}
-				}
+			if (index_dmcache == -1) {
+				i = psys_particle_dm_face_lookup(dm, index, fuv, (LinkNode*)NULL);
+			} else {
+				i = index_dmcache;
 			}
 			

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list