[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12445] branches/particles/source/blender: Particles (peach requirement), reference original faces rather then the indicies of the faces given to it by the previous modifier .

Campbell Barton cbarton at metavr.com
Wed Oct 31 20:54:36 CET 2007


Revision: 12445
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12445
Author:   campbellbarton
Date:     2007-10-31 20:54:36 +0100 (Wed, 31 Oct 2007)

Log Message:
-----------
Particles (peach requirement), reference original faces rather then the indicies of the faces given to it by the previous modifier.
This has the advantage that particles dont depend on the state of the modifier stack.

(work in progress)
* particles can be mapped from the original face to a subsurf mesh. ( a subsurf'd shape can emit particles, when the particles is after the subsurf )
* a new customdata layer has been added (like UV's) to store coords so a derived mesh face can know where it came from without referencing the original face.
* some new path funcs added to do this mapping.

Pointing directly onto a subsurf mesh is not working, and mapping hair dosnt work either - emitting particles

Modified Paths:
--------------
    branches/particles/source/blender/blenkernel/BKE_modifier.h
    branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
    branches/particles/source/blender/blenkernel/intern/customdata.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/blenkernel/intern/pointcache.c
    branches/particles/source/blender/blenlib/BLI_arithb.h
    branches/particles/source/blender/blenlib/intern/arithb.c
    branches/particles/source/blender/makesdna/DNA_customdata_types.h
    branches/particles/source/blender/makesdna/DNA_meshdata_types.h

Modified: branches/particles/source/blender/blenkernel/BKE_modifier.h
===================================================================
--- branches/particles/source/blender/blenkernel/BKE_modifier.h	2007-10-31 17:25:41 UTC (rev 12444)
+++ branches/particles/source/blender/blenkernel/BKE_modifier.h	2007-10-31 19:54:36 UTC (rev 12445)
@@ -283,6 +283,7 @@
                                      int *lastPossibleCageIndex_r);
 
 int           modifiers_isSoftbodyEnabled(struct Object *ob);
+int           modifiers_isParticleEnabled(struct Object *ob);
 struct Object *modifiers_isDeformedByArmature(struct Object *ob);
 struct Object *modifiers_isDeformedByLattice(struct Object *ob);
 int           modifiers_usesArmature(struct Object *ob, struct bArmature *arm);

Modified: branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/DerivedMesh.c	2007-10-31 17:25:41 UTC (rev 12444)
+++ branches/particles/source/blender/blenkernel/intern/DerivedMesh.c	2007-10-31 19:54:36 UTC (rev 12445)
@@ -1958,6 +1958,7 @@
 		 */
 
 		if(mti->type == eModifierTypeType_OnlyDeform) {
+			
 			/* No existing verts to deform, need to build them. */
 			if(!deformedVerts) {
 				if(dm) {
@@ -1999,7 +2000,12 @@
 
 			/* 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->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos);
 
 			if(ndm) {

Modified: branches/particles/source/blender/blenkernel/intern/customdata.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/customdata.c	2007-10-31 17:25:41 UTC (rev 12444)
+++ branches/particles/source/blender/blenkernel/intern/customdata.c	2007-10-31 19:54:36 UTC (rev 12445)
@@ -280,6 +280,83 @@
 		tf[i] = default_tf;
 }
 
+static void layerCopy_origspace_face(const void *source, void *dest, int count)
+{
+	const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
+	OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest;
+	int i;
+
+	for(i = 0; i < count; ++i)
+		dest_tf[i] = source_tf[i];
+}
+
+static void layerInterp_origspace_face(void **sources, float *weights,
+							  float *sub_weights, int count, void *dest)
+{
+	OrigSpaceFace *osf = dest;
+	int i, j, k;
+	float uv[4][2];
+	float *sub_weight;
+
+	if(count <= 0) return;
+
+	memset(uv, 0, sizeof(uv));
+
+	sub_weight = sub_weights;
+	for(i = 0; i < count; ++i) {
+		float weight = weights ? weights[i] : 1;
+		OrigSpaceFace *src = sources[i];
+
+		for(j = 0; j < 4; ++j) {
+			if(sub_weights) {
+				for(k = 0; k < 4; ++k, ++sub_weight) {
+					float w = (*sub_weight) * weight;
+					float *tmp_uv = src->uv[k];
+
+					uv[j][0] += tmp_uv[0] * w;
+					uv[j][1] += tmp_uv[1] * w;
+				}
+			} else {
+				uv[j][0] += src->uv[j][0] * weight;
+				uv[j][1] += src->uv[j][1] * weight;
+			}
+		}
+	}
+
+	*osf = *(OrigSpaceFace *)sources[0];
+	for(j = 0; j < 4; ++j) {
+		osf->uv[j][0] = uv[j][0];
+		osf->uv[j][1] = uv[j][1];
+	}
+}
+
+static void layerSwap_origspace_face(void *data, int *corner_indices)
+{
+	OrigSpaceFace *osf = data;
+	float uv[4][2];
+	int j;
+
+	for(j = 0; j < 4; ++j) {
+		uv[j][0] = osf->uv[corner_indices[j]][0];
+		uv[j][1] = osf->uv[corner_indices[j]][1];
+	}
+	memcpy(osf->uv, uv, sizeof(osf->uv));
+}
+
+static void layerDefault_origspace_face(void *data, int count)
+{
+	static OrigSpaceFace default_osf = {{{0, 1}, {0, 0}, {1, 0}, {1, 1}}};
+	OrigSpaceFace *osf = (OrigSpaceFace*)data;
+	int i;
+
+	for(i = 0; i < count; i++)
+		osf[i] = default_osf;
+}
+/* --------- */
+
+
+
+
 static void layerInterp_mcol(void **sources, float *weights,
                              float *sub_weights, int count, void *dest)
 {
@@ -370,11 +447,13 @@
 	{sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
 	{sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
 	{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+	{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
+	 layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
 };
 
 const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 	"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
-	"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty","CDMIntProperty","CDMStringProperty"};
+	"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty","CDMIntProperty","CDMStringProperty", "CDOrigSpace"};
 
 const CustomDataMask CD_MASK_BAREMESH =
 	CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -387,8 +466,8 @@
 	CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 const CustomDataMask CD_MASK_DERIVEDMESH =
 	CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
-	CD_MASK_MCOL | CD_MASK_ORIGINDEX|
-	CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
+	CD_MASK_MCOL | CD_MASK_ORIGINDEX |
+	CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE;
 
 static const LayerTypeInfo *layerType_getInfo(int type)
 {
@@ -706,7 +785,6 @@
 {
 	CustomDataLayer *layer;
 	const LayerTypeInfo *typeInfo= layerType_getInfo(type);
-	
 	layer = customData_add_layer__internal(data, type, alloctype, layerdata,
 	                                       totelem, typeInfo->defaultname);
 

Modified: branches/particles/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/modifier.c	2007-10-31 17:25:41 UTC (rev 12444)
+++ branches/particles/source/blender/blenkernel/intern/modifier.c	2007-10-31 19:54:36 UTC (rev 12445)
@@ -4967,6 +4967,7 @@
 	/* need to keep this to recognise a bit later in copy_object */
 	tpsmd->psys = psmd->psys;
 }
+
 CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
 {
 	ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
@@ -4980,7 +4981,11 @@
 			break;
 		}
 	}
-
+	
+	/* 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);
+	
 	return dataMask;
 }
 static int is_last_displist(Object *ob)
@@ -6673,6 +6678,13 @@
 	return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
+int modifiers_isParticleEnabled(Object *ob)
+{
+	ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
+
+	return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
+}
+
 LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
 {
 	LinkNode *dataMasks = NULL;

Modified: branches/particles/source/blender/blenkernel/intern/particle.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/particle.c	2007-10-31 17:25:41 UTC (rev 12444)
+++ branches/particles/source/blender/blenkernel/intern/particle.c	2007-10-31 19:54:36 UTC (rev 12445)
@@ -777,7 +777,7 @@
 /* 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)
-{	
+{
 	if(index < 0){ /* 'no dm' error has happened! */
 		PARTICLE_ERROR(nor, vec);
 		return;
@@ -819,39 +819,99 @@
 		/* Need to support constructive modifiers, this is a bit more tricky
 			we need a customdata layer like UV's so we can position the particle */
 		
-		/* todo add custom data layer to support subsurf */
-		PARTICLE_ERROR(nor, vec);
-		/*
-		float temp1[3], temp2[3];
-		switch(from){
-			case PART_FROM_FACE:
-			case PART_FROM_VOLUME:
-			{
-				MFace *mface=dm->getFaceData(dm,index,CD_MFACE);
-				MTFace *mtface=0;
-				MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
-				int uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
-	
-				if(uv_index>=0){
-					CustomDataLayer *layer=&dm->faceData.layers[uv_index];
-					mtface= &((MTFace*)layer->data)[index];
+		/* 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);
+			
+			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)
+			 * since the fuv is the position on the face on the original mesh */
+			float fuv_mod[2];
+			
+			/* Not for quads, use for our abuse of LineIntersectsTriangleUV */
+			float p1[3], p2[3], v0[3], v1[3], v2[3], lambda;
+			
+			p1[0] = p2[0] = fuv[0];
+			p1[1] = p2[1] = fuv[1];
+			p1[2] = 1.0f;
+			p2[2] = -1.0f;
+			v0[2] = v1[2] = v2[2] = 0.0;
+			
+			
+			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);
+				return;
+			}
+			
+			layer_osf = &dm->faceData.layers[osf_index];
+			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];
+					

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list