[Bf-blender-cvs] [64d4d6b] master: Support limiting collisions by group for softbody and particles

Alexander Gavrilov noreply at git.blender.org
Sun Jul 31 10:57:34 CEST 2016


Commit: 64d4d6b134d5b36c43aa55e09ad92d8593a18269
Author: Alexander Gavrilov
Date:   Sun Jul 31 18:56:44 2016 +1000
Branches: master
https://developer.blender.org/rB64d4d6b134d5b36c43aa55e09ad92d8593a18269

Support limiting collisions by group for softbody and particles

This feature is extremely useful for layering multiple cloth objects,
and there is no reason there shouldn't be the same kind of feature for softbody.

===================================================================

M	release/scripts/startup/bl_ui/properties_particle.py
M	release/scripts/startup/bl_ui/properties_physics_softbody.py
M	source/blender/blenkernel/intern/library_query.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenkernel/intern/softbody.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/makesdna/DNA_object_force.h
M	source/blender/makesdna/DNA_particle_types.h
M	source/blender/makesrna/intern/rna_object_force.c
M	source/blender/makesrna/intern/rna_particle.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 08290f2..c2580d4 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -605,6 +605,8 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
             row.prop(part, "use_size_deflect")
             row.prop(part, "use_die_on_collision")
 
+            layout.prop(part, "collision_group")
+
             if part.physics_type == 'FLUID':
                 fluid = part.fluid
 
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index c96f455..a458af7 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -68,6 +68,8 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
         col.label(text="Simulation:")
         col.prop(softbody, "speed")
 
+        layout.prop(softbody, "collision_group")
+
 
 class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel):
     bl_label = "Soft Body Cache"
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 86602e6..d71e801 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -499,8 +499,12 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 					BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
 				}
 
-				if (object->soft && object->soft->effector_weights) {
-					CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_NOP);
+				if (object->soft) {
+					CALLBACK_INVOKE(object->soft->collision_group, IDWALK_NOP);
+
+					if (object->soft->effector_weights) {
+						CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_NOP);
+					}
 				}
 
 				BKE_sca_sensors_id_loop(&object->sensors, library_foreach_sensorsObjectLooper, &data);
@@ -715,6 +719,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 				CALLBACK_INVOKE(psett->dup_group, IDWALK_NOP);
 				CALLBACK_INVOKE(psett->dup_ob, IDWALK_NOP);
 				CALLBACK_INVOKE(psett->bb_ob, IDWALK_NOP);
+				CALLBACK_INVOKE(psett->collision_group, IDWALK_NOP);
 
 				for (i = 0; i < MAX_MTEX; i++) {
 					if (psett->mtex[i]) {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index c3f47fa..e7561ee 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3493,7 +3493,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
 	psys_update_effectors(sim);
 
 	if (part->type != PART_HAIR)
-		sim->colliders = get_collider_cache(sim->scene, sim->ob, NULL);
+		sim->colliders = get_collider_cache(sim->scene, sim->ob, part->collision_group);
 
 	/* initialize physics type specific stuff */
 	switch (part->phystype) {
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 8fec817..7aa899d 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -63,6 +63,7 @@ variables on the UI for now
 #include "DNA_curve_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_group_types.h"
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
@@ -496,59 +497,100 @@ static void ccd_mesh_free(ccd_Mesh *ccdm)
 	}
 }
 
-static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
+{
+	/* only with deflecting set */
+	if (ob->pd && ob->pd->deflect) {
+		void **val_p;
+		if (!BLI_ghash_ensure_p(hash, ob, &val_p)) {
+			ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
+			*val_p = ccdmesh;
+		}
+	}
+}
+
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
 {
-	Base *base= scene->base.first;
 	Object *ob;
 
 	if (!hash) return;
-	while (base) {
-		/*Only proceed for mesh object in same layer */
-		if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
-			ob= base->object;
-			if ((vertexowner) && (ob == vertexowner)) {
-				/* if vertexowner is given  we don't want to check collision with owner object */
-				base = base->next;
+
+	if (group) {
+		/* Explicit collision group */
+		for (GroupObject *go = group->gobject.first; go; go = go->next) {
+			ob = go->ob;
+
+			if (ob == vertexowner || ob->type != OB_MESH)
 				continue;
-			}
 
-			/*+++ only with deflecting set */
-			if (ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == NULL) {
-				ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
-				BLI_ghash_insert(hash, ob, ccdmesh);
-			}/*--- only with deflecting set */
+			ccd_build_deflector_hash_single(hash, ob);
+		}
+	}
+	else {
+		for (Base *base = scene->base.first; base; base = base->next) {
+			/*Only proceed for mesh object in same layer */
+			if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+				ob= base->object;
+				if ((vertexowner) && (ob == vertexowner)) {
+					/* if vertexowner is given  we don't want to check collision with owner object */
+					base = base->next;
+					continue;
+				}
+
+				ccd_build_deflector_hash_single(hash, ob);
+			}
+		}
+	}
+}
 
-		}/* mesh && layer*/
-		base = base->next;
-	} /* while (base) */
+static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
+{
+	if (ob->pd && ob->pd->deflect) {
+		ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
+		if (ccdmesh) {
+			ccd_mesh_update(ob, ccdmesh);
+		}
+	}
 }
 
-static void ccd_update_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
 {
-	Base *base= scene->base.first;
 	Object *ob;
 
 	if ((!hash) || (!vertexowner)) return;
-	while (base) {
-		/*Only proceed for mesh object in same layer */
-		if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
-			ob= base->object;
-			if (ob == vertexowner) {
-				/* if vertexowner is given  we don't want to check collision with owner object */
-				base = base->next;
+
+	if (group) {
+		/* Explicit collision group */
+		for (GroupObject *go = group->gobject.first; go; go = go->next) {
+			ob = go->ob;
+
+			if (ob == vertexowner || ob->type != OB_MESH)
 				continue;
-			}
 
-			/*+++ only with deflecting set */
-			if (ob->pd && ob->pd->deflect) {
-				ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
-				if (ccdmesh)
-					ccd_mesh_update(ob, ccdmesh);
-			}/*--- only with deflecting set */
+			ccd_update_deflector_hash_single(hash, ob);
+		}
+	}
+	else {
+		for (Base *base = scene->base.first; base; base = base->next) {
+			/*Only proceed for mesh object in same layer */
+			if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+				ob= base->object;
+				if (ob == vertexowner) {
+					/* if vertexowner is given  we don't want to check collision with owner object */
+					base = base->next;
+					continue;
+				}
 
-		}/* mesh && layer*/
-		base = base->next;
-	} /* while (base) */
+				ccd_update_deflector_hash_single(hash, ob);
+			}
+		}
+	}
 }
 
 
@@ -934,22 +976,32 @@ static void free_softbody_intern(SoftBody *sb)
 
 /* +++ dependency information functions*/
 
-static int are_there_deflectors(Scene *scene, unsigned int layer)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
 {
-	Base *base;
-
-	for (base = scene->base.first; base; base= base->next) {
-		if ( (base->lay & layer) && base->object->pd) {
-			if (base->object->pd->deflect)
+	if (group) {
+		for (GroupObject *go = group->gobject.first; go; go = go->next) {
+			if (go->ob->pd && go->ob->pd->deflect)
 				return 1;
 		}
 	}
+	else {
+		for (Base *base = scene->base.first; base; base= base->next) {
+			if ( (base->lay & layer) && base->object->pd) {
+				if (base->object->pd->deflect)
+					return 1;
+			}
+		}
+	}
+
 	return 0;
 }
 
-static int query_external_colliders(Scene *scene, Object *me)
+static int query_external_colliders(Scene *scene, Group *group, Object *me)
 {
-	return(are_there_deflectors(scene, me->lay));
+	return(are_there_deflectors(scene, group, me->lay));
 }
 /* --- dependency information functions*/
 
@@ -2197,7 +2249,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
 	/* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */
 
 	/* check conditions for various options */
-	do_deflector= query_external_colliders(scene, ob);
+	do_deflector= query_external_colliders(scene, sb->collision_group, ob);
 	/* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */
 	do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
 	do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2261,7 +2313,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
 		}
 
 		/* check conditions for various options */
-		do_deflector= query_external_colliders(scene, ob);
+		do_deflector= query_external_colliders(scene, sb->collision_group, ob);
 		do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
 		do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
 		do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -3472,11 +3524,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
 	 */
 	if (dtime < 0 || dtime > 10.5f) return;
 
-	ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
+	ccd_update_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
 
 	if (sb->scratch->needstobuildcollider) {
-		if (query_external_colliders(scene, ob)) {
-			ccd_build_deflector_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list