[Bf-blender-cvs] [026b847bd9f] fracture_modifier: refactored acceleration map, but might still have issues

Martin Felke noreply at git.blender.org
Fri Dec 29 01:47:04 CET 2017


Commit: 026b847bd9f830fc4cc3307f2154a8e55fa5225a
Author: Martin Felke
Date:   Fri Dec 29 01:46:36 2017 +0100
Branches: fracture_modifier
https://developer.blender.org/rB026b847bd9f830fc4cc3307f2154a8e55fa5225a

refactored acceleration map, but might still have issues

also attempted to improve triggering (make exacter, but slow and error prone)

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

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/BKE_fracture.h
M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/pointcache.c
M	source/blender/blenkernel/intern/rigidbody.c

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

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index da997a38f24..01d27357676 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -188,6 +188,10 @@ void RB_body_set_angular_sleep_thresh(rbRigidBody *body, float value);
 
 void RB_body_set_sleep_thresh(rbRigidBody *body, float linear, float angular);
 
+/* Force and Torque */
+void RB_body_get_total_force(rbRigidBody *body, float v_out[3]);
+void RB_body_get_total_torque(rbRigidBody *body, float v_out[3]);
+
 /* Linear Velocity */
 void RB_body_get_linear_velocity(rbRigidBody *body, float v_out[3]);
 void RB_body_set_linear_velocity(rbRigidBody *body, const float v_in[3]);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 13e884e180a..54306a1e5f8 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -721,6 +721,9 @@ struct myResultCallback : public btCollisionWorld::ClosestRayResultCallback
 	}
 };
 
+#define MIN2(a, b)  ((a) < (b) ? (a) : (b))
+#define MIN3(a, b, c)       (MIN2(MIN2((a), (b)), (c)))
+
 struct rbFilterCallback : public btOverlapFilterCallback
 {
 	int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate);
@@ -736,80 +739,55 @@ struct rbFilterCallback : public btOverlapFilterCallback
 
 		collides = collides && (rb0->col_groups & rb1->col_groups);
 		if (this->callback != NULL) {
-			int result = 0;
-#if 0
-			//cast ray from centroid of 1 rigidbody to another, do this only for mesh shapes (all other can use standard bbox)
+
 			int stype0 = rb0->body->getCollisionShape()->getShapeType();
 			int stype1 = rb1->body->getCollisionShape()->getShapeType();
-			bool nonMeshShape0 = (stype0 != GIMPACT_SHAPE_PROXYTYPE) && (stype0 != TRIANGLE_MESH_SHAPE_PROXYTYPE);
-			bool nonMeshShape1 = (stype1 != GIMPACT_SHAPE_PROXYTYPE) && (stype1 != TRIANGLE_MESH_SHAPE_PROXYTYPE);
+			bool meshShape0 = (stype0 == GIMPACT_SHAPE_PROXYTYPE) || (stype0 == TRIANGLE_MESH_SHAPE_PROXYTYPE);
+			bool meshShape1 = (stype1 == GIMPACT_SHAPE_PROXYTYPE) || (stype1 == TRIANGLE_MESH_SHAPE_PROXYTYPE);
 
-			if ((rb0->meshIsland != NULL) ^ (rb1->meshIsland != NULL))
+			if (rb0->blenderOb != rb1->blenderOb && (meshShape0 || meshShape1))
 			{
 				btVector3 v0, v1;
-				rbRigidBody* rb2 = NULL;
-				bool valid = false;
+				v0 = rb0->body->getWorldTransform().getOrigin();
+				v1 = rb1->body->getWorldTransform().getOrigin();
+				float maxbound1 = MIN3(rb0->bbox->x(), rb0->bbox->y(), rb0->bbox->z());
+				float maxbound2 = MIN3(rb1->bbox->x(), rb1->bbox->y(), rb1->bbox->z());
+				float bound = maxbound1;
 
-				if (rb0->meshIsland != NULL)
+				if (maxbound2 < maxbound1)
 				{
-					v0 = rb0->body->getWorldTransform().getOrigin();
-					v1 = rb1->body->getWorldTransform().getOrigin();
-				}
-				else if (rb1->meshIsland != NULL)
-				{
-					v0 = rb1->body->getWorldTransform().getOrigin();
-					v1 = rb0->body->getWorldTransform().getOrigin();
+					bound = maxbound2;
 				}
 
 				myResultCallback cb(v0, v1);
 				rb0->world->dynamicsWorld->rayTest(v0, v1, cb);
-				if (cb.m_collisionObject != NULL)
+				if (cb.m_collisionObject)
 				{
-					rb2 = (rbRigidBody*)cb.m_collisionObject->getUserPointer();
-				}
-				else
-				{
-					valid = false;
-				}
-
-				if (rb0->meshIsland != NULL && rb2 != NULL)
-				{
-					valid = rb2->blenderOb != rb0->blenderOb;
-				}
-				else if (rb1->meshIsland != NULL && rb2 != NULL)
-				{
-					valid = rb2->blenderOb != rb1->blenderOb;
-				}
-
-				if (rb0->meshIsland != NULL)
-				{
-					valid = valid || nonMeshShape1;
-				}
-				else if (rb1->meshIsland != NULL)
-				{
-					valid = valid || nonMeshShape0;
-				}
-
+					float dist_sq = (v0 - cb.m_collisionObject->getWorldTransform().getOrigin()).length2();
+					//float dist_sq2 = (v0 - v1).length2();
+					float dist_sq2 = bound * bound;
+					if (dist_sq < dist_sq2)
+					{
+						int result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland,
+						                            rb0->blenderOb, rb1->blenderOb, activate);
 
-				if (valid)
-				{
-					result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb);
+						collides = collides && (bool)result;
+					}
+					else
+					{
+						collides = false;
+					}
 				}
-				else
-				{
-					//just check for ghost flags and collision groups there
-					result = this->callback(NULL, NULL, NULL, rb0->blenderOb, rb1->blenderOb);
+				else {
+					collides = false;
 				}
 			}
-			else
-			{
-				result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb);
-			}
+			else {
+				int result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland,
+				                            rb0->blenderOb, rb1->blenderOb, activate && (rb0->blenderOb != rb1->blenderOb));
 
-			collides = collides && (bool)result;
-#endif
-			result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb, activate);
-			collides = collides && (bool)result;
+				collides = collides && (bool)result;
+			}
 		}
 
 		return collides;
@@ -1360,6 +1338,21 @@ void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
 
 /* ............ */
 
+void RB_body_get_total_force(rbRigidBody *object, float v_out[3])
+{
+	btRigidBody *body = object->body;
+
+	copy_v3_btvec3(v_out, body->getTotalForce());
+}
+
+void RB_body_get_total_torque(rbRigidBody *object, float v_out[3])
+{
+	btRigidBody *body = object->body;
+
+	copy_v3_btvec3(v_out, body->getTotalTorque());
+}
+
+
 void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
 {
 	btRigidBody *body = object->body;
diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h
index 82f1b9031b4..a1f0b009b9e 100644
--- a/source/blender/blenkernel/BKE_fracture.h
+++ b/source/blender/blenkernel/BKE_fracture.h
@@ -126,5 +126,6 @@ short BKE_fracture_collect_materials(struct Object* o, struct Object* ob, int ma
 
 void BKE_bm_mesh_hflag_flush_vert(struct BMesh *bm, const char hflag);
 void BKE_meshisland_constraint_create(struct FractureModifierData* fmd, struct MeshIsland *mi1, struct MeshIsland *mi2, int con_type, float thresh);
+void BKE_update_acceleration_map(struct FractureModifierData *fmd, struct MeshIsland* mi, struct Object* ob, int ctime, float acc);
 
 #endif /* BKE_FRACTURE_H */
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index 85fe91270c6..751ea619f35 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -3647,3 +3647,59 @@ void BKE_meshisland_constraint_create(FractureModifierData* fmd, MeshIsland *mi1
 	mi2->participating_constraints[mi2->participating_constraint_count] = rbsc;
 	mi2->participating_constraint_count++;
 }
+
+void BKE_update_acceleration_map(FractureModifierData *fmd, MeshIsland* mi, Object* ob, int ctime, float acc)
+{
+	const int acc_defgrp_index = defgroup_name_index(ob, fmd->acceleration_defgrp_name);
+	DerivedMesh *dm = fmd->visible_mesh_cached;
+	MDeformVert *dvert = NULL, *dv = NULL;
+	MDeformWeight *dw = NULL;
+	float weight = 0.0f, denom;
+	int i = 0, w = 0;
+	int totvert = dm->getNumVerts(dm);
+
+	dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+
+	if (dvert == NULL)
+	{
+		dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC,
+	                             NULL, totvert);
+	}
+
+	//calculate weight from force...
+	denom = fmd->max_acceleration - fmd->min_acceleration;
+
+	//sanity check
+	if (denom == 0.0f)
+		denom = 1.0f;
+
+	//if (mi->acc_sequence)
+	{
+		weight = (acc - fmd->min_acceleration) / denom;
+
+		if (ctime == mi->start_frame)
+			weight = 0.0f;
+
+		for (i = 0; i < mi->vertex_count; i++)
+		{
+			dv = dvert + mi->vertex_indices[i];
+			if (dv) {
+				if (dv->dw == NULL && acc_defgrp_index >= 0) {
+					defvert_add_index_notest(dv, acc_defgrp_index, 0.0f);
+				}
+
+				for (dw = dv->dw, w = 0; w < dv->totweight; dw++, w++)
+				{
+					if (dw->def_nr == acc_defgrp_index) {
+
+						if (weight >= 0.0f && weight <= 1.0f) {
+							dw->weight = weight;
+						}
+
+						dw->weight *= fmd->acceleration_fade;
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 4841fa1444d..14c481105fe 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1324,6 +1324,37 @@ static int  ptcache_rigidbody_write(int index, void *rb_v, void **data, int cfra
 	{
 		if ((!fmd || fmd->fracture_mode != MOD_FRACTURE_DYNAMIC) && rbo->type == RBO_TYPE_ACTIVE)
 		{
+			MeshIsland *mi = NULL;
+
+			if (fmd && fmd->acceleration_defgrp_name[0])
+			{
+				mi = find_meshisland(fmd, rbo->meshisland_index);
+				if (cfra >= mi->start_frame && cfra <= mi->frame_count) {
+					float lastvel = 0.0f;
+					float vel = 0.0f;
+					float linvel[3] = {0.0f, 0.0f, 0.0f};
+					float angvel[3] = {0.0f, 0.0f, 0.0f};
+					float acc = 0.0f;
+
+					//rough framewise estimate of total force
+					if (mi->rigidbody->physics_object)
+					{
+						RB_body_get_linear_velocity(mi->rigidbody->physics_object, linvel);
+						RB_body_get_angular_velocity(mi->rigidbody->physics_object, angvel);
+						vel = len_v3(linvel) + len_v3(angvel);
+					}
+
+					if (cfra >= mi->start_frame + 1)
+					{
+						lastvel = mi->acc_sequence[cfra - mi->start_frame - 1];
+					}
+
+					acc = fabsf(vel - lastvel);
+
+					mi->acc_sequence[cfra - mi->start_frame] = acc;
+					BKE_update_acceleration_map(fmd, mi, ob, cfra, acc);
+				}
+			}
 
 #ifdef WITH_BULLET
 			RB_body_get_position(rbo->physics_object, rbo->pos);
@@ -1336,7 +1367,7 @@ static int  ptcache_rigidbody_write(int index, void *rb_v, void **data, int cfra
 		{
 			//MeshIsland *mi = BLI_findlink(&fmd->meshIslands, rbo->meshisland_index);
 			MeshIsland *mi = find_meshisland(fmd, rbo->meshisland_index);
-			int frame = (int)floor(cfra);
+			int frame = cfra;
 
 //			if (!mi)
 //				return 0;
@@ -1399,6 +143

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list