[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19646] trunk/blender/source/blender: Mesh effector surface option:

Janne Karhu jhkarh at utu.fi
Fri Apr 10 21:40:22 CEST 2009


Revision: 19646
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19646
Author:   jhk
Date:     2009-04-10 21:40:21 +0200 (Fri, 10 Apr 2009)

Log Message:
-----------
Mesh effector surface option:
- Most mesh particle effectors can now have their effection point taken per particle as the nearest point on the mesh surface.
- This is activated with the "surface" button in the effector field panel.
- Activating the option adds a "surface" entry to the modifier stack where the state of the mesh is read from.

For an example of usage see http://www.youtube.com/watch?v=3XkO1EAmJks.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_modifier_types.h
    trunk/blender/source/blender/makesdna/DNA_object_force.h
    trunk/blender/source/blender/src/buttons_editing.c
    trunk/blender/source/blender/src/buttons_object.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2009-04-10 19:40:21 UTC (rev 19646)
@@ -6016,6 +6016,82 @@
 }
 
 
+
+/* Surface */
+
+static void surfaceModifier_initData(ModifierData *md) 
+{
+	SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+	
+	surmd->bvhtree = NULL;
+}
+
+static void surfaceModifier_freeData(ModifierData *md)
+{
+	SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+	
+	if (surmd)
+	{
+		if(surmd->bvhtree) {
+			free_bvhtree_from_mesh(surmd->bvhtree);
+			MEM_freeN(surmd->bvhtree);
+		}
+
+		surmd->dm->release(surmd->dm);
+		
+		surmd->bvhtree = NULL;
+		surmd->dm = NULL;
+	}
+}
+
+static int surfaceModifier_dependsOnTime(ModifierData *md)
+{
+	return 1;
+}
+
+static void surfaceModifier_deformVerts(
+					  ModifierData *md, Object *ob, DerivedMesh *derivedData,
+       float (*vertexCos)[3], int numVerts)
+{
+	SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+	DerivedMesh *dm = NULL;
+	float current_time = 0;
+	unsigned int numverts = 0, i = 0;
+	
+	if(surmd->dm)
+		surmd->dm->release(surmd->dm);
+
+	/* if possible use/create DerivedMesh */
+	if(derivedData) surmd->dm = CDDM_copy(derivedData);
+	else if(ob->type==OB_MESH) surmd->dm = CDDM_from_mesh(ob->data, ob);
+	
+	if(!ob->pd)
+	{
+		printf("surfaceModifier_deformVerts: Should not happen!\n");
+		return;
+	}
+	
+	if(surmd->dm)
+	{
+		CDDM_apply_vert_coords(surmd->dm, vertexCos);
+		CDDM_calc_normals(surmd->dm);
+		
+		numverts = surmd->dm->getNumVerts ( surmd->dm );
+
+		/* convert to global coordinates */
+		for(i = 0; i<numverts; i++)
+			Mat4MulVecfl(ob->obmat, CDDM_get_vert(surmd->dm, i)->co);
+
+		if(surmd->bvhtree)
+			free_bvhtree_from_mesh(surmd->bvhtree);
+		else
+			surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+
+		bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
+	}
+}
+
+
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -8217,6 +8293,14 @@
 		mti->deformVerts = collisionModifier_deformVerts;
 		// mti->copyData = collisionModifier_copyData;
 
+		mti = INIT_TYPE(Surface);
+		mti->type = eModifierTypeType_OnlyDeform;
+		mti->initData = surfaceModifier_initData;
+		mti->flags = eModifierTypeFlag_AcceptsMesh;
+		mti->dependsOnTime = surfaceModifier_dependsOnTime;
+		mti->freeData = surfaceModifier_freeData; 
+		mti->deformVerts = surfaceModifier_deformVerts;
+
 		mti = INIT_TYPE(Boolean);
 		mti->type = eModifierTypeType_Nonconstructive;
 		mti->flags = eModifierTypeFlag_AcceptsMesh

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2009-04-10 19:40:21 UTC (rev 19646)
@@ -77,6 +77,7 @@
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_scene.h"
+#include "BKE_bvhutils.h"
 
 #include "PIL_time.h"
 
@@ -2447,7 +2448,6 @@
 			
 			if(ec->rng)
 				rng_free(ec->rng);
-			
 		}
 
 		BLI_freelistN(lb);
@@ -2544,6 +2544,7 @@
 	ParticleData *epa;
 	ParticleKey estate;
 	PartDeflect *pd;
+	SurfaceModifierData *surmd = NULL;
 	ListBase *lb=&psys->effectors;
 	ParticleEffectorCache *ec;
 	float distance, vec_to_part[3];
@@ -2571,8 +2572,34 @@
 				if(psys->part->type!=PART_HAIR && psys->part->integrator)
 					where_is_object_time(eob,cfra);
 
-				/* use center of object for distance calculus */
-				VecSubf(vec_to_part, state->co, eob->obmat[3]);
+				if(pd && pd->flag&PFIELD_SURFACE) {
+					surmd = (SurfaceModifierData *)modifiers_findByType ( eob, eModifierType_Surface );
+				}
+				if(surmd) {
+					/* closest point in the object surface is an effector */
+					BVHTreeNearest nearest;
+					float velocity[3];
+
+					nearest.index = -1;
+					nearest.dist = FLT_MAX;
+
+					/* using velocity corrected location allows for easier sliding over effector surface */
+					VecCopyf(velocity, state->vel);
+					VecMulf(velocity, psys_get_timestep(psys->part));
+					VecAddf(vec_to_part, state->co, velocity);
+
+					BLI_bvhtree_find_nearest(surmd->bvhtree->tree, vec_to_part, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
+
+					if(nearest.index != -1) {
+						VecSubf(vec_to_part, state->co, nearest.co);
+					}
+					else
+						vec_to_part[0] = vec_to_part[1] = vec_to_part[2] = 0.0f;
+				}
+				else 
+					/* use center of object for distance calculus */
+					VecSubf(vec_to_part, state->co, eob->obmat[3]);
+
 				distance = VecLength(vec_to_part);
 
 				falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2009-04-10 19:40:21 UTC (rev 19646)
@@ -3207,6 +3207,12 @@
 			collmd->mfaces = NULL;
 			
 		}
+		else if (md->type==eModifierType_Surface) {
+			SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+
+			surmd->dm = NULL;
+			surmd->bvhtree = NULL;
+		}
 		else if (md->type==eModifierType_Hook) {
 			HookModifierData *hmd = (HookModifierData*) md;
 

Modified: trunk/blender/source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2009-04-10 19:40:21 UTC (rev 19646)
@@ -39,6 +39,7 @@
 	eModifierType_Fluidsim,
 	eModifierType_Mask,
 	eModifierType_SimpleDeform,
+	eModifierType_Surface,
 	NUM_MODIFIER_TYPES
 } ModifierType;
 
@@ -418,6 +419,14 @@
 	struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
 } CollisionModifierData;
 
+typedef struct SurfaceModifierData {
+	ModifierData	modifier;
+
+	struct DerivedMesh *dm;
+
+	struct BVHTreeFromMesh *bvhtree; /* bounding volume hierarchy of the mesh faces */
+} SurfaceModifierData;
+
 typedef enum {
 	eBooleanModifierOp_Intersect,
 	eBooleanModifierOp_Union,

Modified: trunk/blender/source/blender/makesdna/DNA_object_force.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_object_force.h	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/makesdna/DNA_object_force.h	2009-04-10 19:40:21 UTC (rev 19646)
@@ -225,6 +225,7 @@
 #define PFIELD_USEMAXR			512
 #define PFIELD_USEMINR			1024
 #define PFIELD_TEX_ROOTCO		2048
+#define PFIELD_SURFACE			4096
 
 /* pd->falloff */
 #define PFIELD_FALL_SPHERE		0

Modified: trunk/blender/source/blender/src/buttons_editing.c
===================================================================
--- trunk/blender/source/blender/src/buttons_editing.c	2009-04-10 18:47:33 UTC (rev 19645)
+++ trunk/blender/source/blender/src/buttons_editing.c	2009-04-10 19:40:21 UTC (rev 19646)
@@ -1031,7 +1031,7 @@
 		/* Only allow adding through appropriate other interfaces */
 		if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
 		
-		if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim)) continue;
+		if(ELEM4(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Surface, eModifierType_Fluidsim)) continue;
 
 		if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
 		   (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@ -1771,7 +1771,7 @@
 		uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
 
 		/* Softbody not allowed in this situation, enforce! */
-		if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
+		if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
 			uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
 			but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
 			if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
@@ -1813,7 +1813,7 @@
 		
 		// deletion over the deflection panel
 		// fluid particle modifier can't be deleted here
-		if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
+		if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && md->type!=eModifierType_Surface && !modifier_is_fluid_particles(md))
 		{
 			but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
 			uiButSetFunc(but, modifiers_del, ob, md);
@@ -1884,6 +1884,8 @@
 			height = 31;
 		} else if (md->type==eModifierType_Collision) {
 			height = 31;
+		} else if (md->type==eModifierType_Surface) {
+			height = 31;
 		} else if (md->type==eModifierType_Fluidsim) {
 			height = 31;
 		} else if (md->type==eModifierType_Boolean) {
@@ -1924,7 +1926,7 @@
 
 		y -= 18;
 
-		if (!isVirtual && (md->type!=eModifierType_Collision)) {
+		if (!isVirtual && (md->type!=eModifierType_Collision) && (md->type!=eModifierType_Surface)) {
 			uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); /* only here obdata, the rest of modifiers is ob level */
 
 			uiBlockBeginAlign(block);
@@ -2369,6 +2371,8 @@
 
 		} else if (md->type==eModifierType_Collision) {
 			uiDefBut(block, LABEL, 1, "See Collision panel.",	lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+		} else if (md->type==eModifierType_Surface) {
+			uiDefBut(block, LABEL, 1, "See Fields panel.",	lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
 		} else if (md->type==eModifierType_Fluidsim) {
 			uiDefBut(block, LABEL, 1, "See Fluidsim panel.",	lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list