[Bf-blender-cvs] [fcad67e] fracture_modifier: fake trigger, disable animated checkbox on collision, (but this should be done by hand, earlier, to get better impact speeds)

Martin Felke noreply at git.blender.org
Thu Nov 6 02:37:25 CET 2014


Commit: fcad67e0872abe7a9d0793a4a7e0daf742f6c065
Author: Martin Felke
Date:   Thu Nov 6 02:33:21 2014 +0100
Branches: fracture_modifier
https://developer.blender.org/rBfcad67e0872abe7a9d0793a4a7e0daf742f6c065

fake trigger, disable animated checkbox on collision, (but this should be done by hand, earlier, to get better impact speeds)

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

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/makesdna/DNA_rigidbody_types.h

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

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 49e2d80..08e6b90 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -73,7 +73,7 @@ typedef struct rbConstraint rbConstraint;
 
 /* Create a new dynamics world instance */
 // TODO: add args to set the type of constraint solvers, etc.
-rbDynamicsWorld *RB_dworld_new(const float gravity[3]);
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, int (*callback)(void *, void *, void *));
 
 /* Delete the given dynamics world, and free any extra data it may require */
 void RB_dworld_delete(rbDynamicsWorld *world);
@@ -105,7 +105,7 @@ void RB_dworld_export(rbDynamicsWorld *world, const char *filename);
 /* Setup ---------------------------- */
 
 /* Add RigidBody to dynamics world */
-void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *body, int col_groups);
+void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *body, int col_groups, void* meshIsland);
 
 /* Remove RigidBody from dynamics world */
 void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index a85254a..fe92f38 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -80,10 +80,13 @@ struct rbDynamicsWorld {
 	btBroadphaseInterface *pairCache;
 	btConstraintSolver *constraintSolver;
 	btOverlapFilterCallback *filterCallback;
+	void *blenderWorld;
 };
 struct rbRigidBody {
 	btRigidBody *body;
 	int col_groups;
+	void *meshIsland;
+	rbDynamicsWorld *world;
 };
 
 struct rbVert {
@@ -108,6 +111,12 @@ struct rbCollisionShape {
 
 struct rbFilterCallback : public btOverlapFilterCallback
 {
+	int (*callback)(void* world, void* island1, void* island2);
+
+	rbFilterCallback(int (*callback)(void* world, void* island1, void* island2)) {
+		this->callback = callback;
+	}
+
 	virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
 	{
 		rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
@@ -117,6 +126,10 @@ struct rbFilterCallback : public btOverlapFilterCallback
 		collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
 		collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
 		collides = collides && (rb0->col_groups & rb1->col_groups);
+		if (this->callback != NULL) {
+			int result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland);
+			collides = collides && (bool)result;
+		}
 		
 		return collides;
 	}
@@ -141,7 +154,8 @@ static inline void copy_quat_btquat(float quat[4], const btQuaternion &btquat)
 
 /* Setup ---------------------------- */
 
-rbDynamicsWorld *RB_dworld_new(const float gravity[3])
+//yuck, but need a handle for the world somewhere for collision callback...
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, int (*callback)(void *, void *, void *))
 {
 	rbDynamicsWorld *world = new rbDynamicsWorld;
 	
@@ -153,7 +167,7 @@ rbDynamicsWorld *RB_dworld_new(const float gravity[3])
 	
 	world->pairCache = new btDbvtBroadphase();
 	
-	world->filterCallback = new rbFilterCallback();
+	world->filterCallback = new rbFilterCallback(callback);
 	world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
 
 	/* constraint solving */
@@ -164,6 +178,7 @@ rbDynamicsWorld *RB_dworld_new(const float gravity[3])
 	                                                   world->pairCache,
 	                                                   world->constraintSolver,
 	                                                   world->collisionConfiguration);
+	world->blenderWorld = blenderWorld;
 
 	RB_dworld_set_gravity(world, gravity);
 	
@@ -250,10 +265,12 @@ void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
 
 /* Setup ---------------------------- */
 
-void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
+void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups, void* meshIsland)
 {
 	btRigidBody *body = object->body;
 	object->col_groups = col_groups;
+	object->meshIsland = meshIsland;
+	object->world = world;
 	
 	world->dynamicsWorld->addRigidBody(body);
 }
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index f1a1da0..9225099 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -72,6 +72,8 @@
 
 #ifdef WITH_BULLET
 
+static void validateShard(RigidBodyWorld *rbw, MeshIsland *mi, Object *ob, int rebuild);
+
 static bool isModifierActive(FractureModifierData *rmd) {
 	return ((rmd != NULL) && (rmd->modifier.mode & (eModifierMode_Realtime | eModifierMode_Render)) && (rmd->refresh == false));
 }
@@ -1117,7 +1119,7 @@ void BKE_rigidbody_validate_sim_shard(RigidBodyWorld *rbw, MeshIsland *mi, Objec
 		BKE_rigidbody_validate_sim_shard_shape(mi, ob, true);
 	
 	if (rbo->physics_object) {
-		if (rebuild == false)
+		if (rebuild == false || mi->rigidbody->flag & RBO_FLAG_KINEMATIC_REBUILD)
 			RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
 	}
 	if (!rbo->physics_object || rebuild) {
@@ -1156,9 +1158,10 @@ void BKE_rigidbody_validate_sim_shard(RigidBodyWorld *rbw, MeshIsland *mi, Objec
 	}
 
 	if (rbw && rbw->physics_world && rbo->physics_object)
-		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
+		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups, mi);
 
 	rbo->flag &= ~RBO_FLAG_NEEDS_VALIDATE;
+	rbo->flag &= ~RBO_FLAG_KINEMATIC_REBUILD;
 }
 
 
@@ -1231,7 +1234,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
 	}
 
 	if (rbw && rbw->physics_world)
-		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
+		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups, NULL);
 }
 
 /* --------------------- */
@@ -1590,6 +1593,74 @@ void BKE_rigidbody_validate_sim_shard_constraint(RigidBodyWorld *rbw, RigidBodyS
 	}
 }
 
+//this allows partial object activation, only some shards will be activated, called from bullet(!)
+static int filterCallback(void* world, void* island1, void* island2) {
+	MeshIsland* mi1, *mi2;
+	RigidBodyWorld *rbw = (RigidBodyWorld*)world;
+	Object* ob1, *ob2;
+	int ob_index1, ob_index2;
+	FractureModifierData *fmd1, *fmd2;
+
+	mi1 = (MeshIsland*)island1;
+	mi2 = (MeshIsland*)island2;
+
+	if (rbw == NULL)
+	{
+		return 1;
+	}
+
+	if ((mi1 == NULL) || (mi2 == NULL)) {
+		return 1;
+	}
+
+	//cache offset map is a dull name for that...
+	ob_index1 = rbw->cache_offset_map[mi1->linear_index];
+	ob_index2 = rbw->cache_offset_map[mi2->linear_index];
+
+	if (ob_index1 != ob_index2 &&
+	   ((mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) ||
+	   (mi2->rigidbody->flag & RBO_FLAG_KINEMATIC)))
+	{
+		float linvel[3], angvel[3];
+		MeshIsland *mi;
+		ob1 = rbw->objects[ob_index1];
+		fmd1 = (FractureModifierData*)modifiers_findByType(ob1, eModifierType_Fracture);
+		RB_body_get_linear_velocity(mi1->rigidbody->physics_object, linvel);
+		RB_body_get_angular_velocity(mi1->rigidbody->physics_object, angvel);
+		for (mi = fmd1->meshIslands.first; mi; mi = mi->next)
+		{
+			RigidBodyOb* rbo = mi->rigidbody;
+			if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+			{
+				rbo->flag &= ~RBO_FLAG_KINEMATIC;
+				rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
+				RB_body_set_linear_velocity(rbo->physics_object, linvel);
+				RB_body_set_angular_velocity(rbo->physics_object, angvel);
+			}
+		}
+
+		ob2 = rbw->objects[ob_index2];
+		fmd2 = (FractureModifierData*)modifiers_findByType(ob2, eModifierType_Fracture);
+		RB_body_get_linear_velocity(mi2->rigidbody->physics_object, linvel);
+		RB_body_get_angular_velocity(mi2->rigidbody->physics_object, angvel);
+
+		for (mi = fmd2->meshIslands.first; mi; mi = mi->next)
+		{
+			RigidBodyOb* rbo = mi->rigidbody;
+
+			if (mi->rigidbody->flag & RBO_FLAG_KINEMATIC)
+			{
+				rbo->flag &= ~RBO_FLAG_KINEMATIC;
+				rbo->flag |= RBO_FLAG_KINEMATIC_REBUILD;
+				RB_body_set_linear_velocity(rbo->physics_object, linvel);
+				RB_body_set_angular_velocity(rbo->physics_object, angvel);
+			}
+		}
+	}
+
+	return 1;
+}
+
 /* --------------------- */
 
 /* Create physics sim world given RigidBody world settings */
@@ -1604,7 +1675,7 @@ void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool re
 	if (rebuild || rbw->physics_world == NULL) {
 		if (rbw->physics_world)
 			RB_dworld_delete(rbw->physics_world);
-		rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity);
+		rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity, rbw, filterCallback);
 	}
 
 	RB_dworld_set_solver_iterations(rbw->physics_world, rbw->num_solver_iterations);
@@ -2327,7 +2398,7 @@ static void validateShard(RigidBodyWorld *rbw, MeshIsland *mi, Object *ob, int r
 		return;
 	}
 	
-	if (rebuild) { // && (mi->rigidbody->flag & RBO_FLAG_NEEDS_VALIDATE)) {
+	if (rebuild || (mi->rigidbody->flag & RBO_FLAG_KINEMATIC_REBUILD)) {
 		/* World has been rebuilt so rebuild object */
 		BKE_rigidbody_validate_sim_shard(rbw, mi, ob, true);
 	}
@@ -2837,8 +2908,30 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
 
 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
 {
+	GroupObject *go;
+
 	if (rbw)
 		rbw->pointcache->flag |= PTCACHE_OUTDATED;
+
+	/*restore kinematic state of shards if object is kinematic*/
+	for (go = rbw->group->gobject.first; go; go = go->next)	{
+		if ((go->ob) && (go->ob->rigidbody_object) && (go->ob->rigidbody_object->flag & RBO_FLAG_KINEMATIC))
+		{
+			FractureModifierData *fmd = (FractureModifierData*)modifiers_findByType(go->ob, eModifierType_Fracture);
+			if (fmd)
+			{
+				MeshIsland* mi;
+				for (mi = fmd->meshIslands.first; mi; mi = mi->next)
+				{
+					if (mi->rigidbody)
+					{
+						mi->rigidbody->flag |= RBO_FLAG_KINEMATIC;
+						mi->rigidbody->flag |= RBO_FLAG_NEEDS_VALIDATE;
+					}
+				}
+			}
+		}
+	}
 }
 
 
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blen

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list