[Bf-blender-cvs] [69159cb] hair_system: Secondary penalty force for collisions to prevent penetrations.

Lukas Tönne noreply at git.blender.org
Fri Aug 8 15:58:56 CEST 2014


Commit: 69159cb7bc24c2f06892d8346efb4e42b409cf90
Author: Lukas Tönne
Date:   Fri Aug 8 15:57:41 2014 +0200
Branches: hair_system
https://developer.blender.org/rB69159cb7bc24c2f06892d8346efb4e42b409cf90

Secondary penalty force for collisions to prevent penetrations.

The first component only cancels out the relative velocity, but does
not prevent further penetration of hair into other objects. This second
force component actively pushes the hair outward based on the distance
from a collision margin.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/hair/intern/HAIR_collision.cpp
M	source/blender/hair/intern/HAIR_solver.cpp
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesrna/intern/rna_hair.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 681d39e..7d36122 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1250,6 +1250,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col2 = row.column()
         col2.prop(params, "restitution")
         col2.prop(params, "friction")
+        col2.prop(params, "margin")
         col2 = row.column()
         col2.prop(params, "drag")
         
diff --git a/source/blender/hair/intern/HAIR_collision.cpp b/source/blender/hair/intern/HAIR_collision.cpp
index 3707614..4cb61e9 100644
--- a/source/blender/hair/intern/HAIR_collision.cpp
+++ b/source/blender/hair/intern/HAIR_collision.cpp
@@ -59,9 +59,10 @@ PointContactInfo::PointContactInfo(const btManifoldPoint &bt_point, const btColl
 }
 
 struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
-	HairContactResultCallback(PointContactCache &cache) :
+	HairContactResultCallback(const HairParams &params, PointContactCache &cache) :
 	    cache(&cache),
-	    point_index(0)
+	    point_index(0),
+	    margin(params.margin)
 	{
 	}
 
@@ -69,7 +70,7 @@ struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
 	                         const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0,
 	                         const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)
 	{
-		if (cp.getDistance() < 0.f) {
+		if (cp.getDistance() < margin) {
 			const btCollisionObject *ob0 = colObj0Wrap->getCollisionObject();
 			const btCollisionObject *ob1 = colObj1Wrap->getCollisionObject();
 			
@@ -78,7 +79,7 @@ struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
 			
 //			const btVector3 &ptA = cp.getPositionWorldOnA();
 //			const btVector3 &ptB = cp.getPositionWorldOnB();
-//			Debug::collision_contact(float3(ptA.x(), ptA.y(), ptA.z()), float3(ptB.x(), ptB.y(), ptB.z()));
+//			Debug::collision_contact(debug_data, float3(ptA.x(), ptA.y(), ptA.z()), float3(ptB.x(), ptB.y(), ptB.z()));
 		}
 		
 		/* note: return value is unused
@@ -89,6 +90,7 @@ struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
 	
 	PointContactCache *cache;
 	int point_index;
+	float margin;
 };
 
 void Solver::cache_point_contacts(PointContactCache &cache) const
@@ -116,7 +118,7 @@ void Solver::cache_point_contacts(PointContactCache &cache) const
 		btCollisionObject *ob1 = (btCollisionObject *)pair.m_pProxy1->m_clientObject;
 		btCollisionObject *other = ob0 == ghost ? ob1 : ob0;
 		
-		HairContactResultCallback cb(cache);
+		HairContactResultCallback cb(m_params, cache);
 		
 		Point *point = m_data->points;
 		int totpoints = m_data->totpoints;
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 69372a6..e96be0c 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -200,11 +200,6 @@ static void calc_root_animation(float t0, float t1, float t, Curve *curve, float
 	}
 }
 
-static float3 calc_velocity(Curve *curve, Point *point, float time, Point::State &state)
-{
-	return state.vel;
-}
-
 /* XXX could cache rest_length in SolverData */
 
 static float3 calc_stretch_force(const HairParams &params, const Point *point0, const Point *point1, float time)
@@ -347,7 +342,10 @@ static void do_collision(const HairParams &params, const SolverForces &forces, f
 			/* estimate for velocity change to prevent collision (3.2, (8)) */
 			float3 dv_a = dot_v3v3(info.restitution * (obj_v0 - v0) + (obj_v1 - v0), info.world_normal_body) * info.world_normal_body;
 			
-			point->force_accum = point->force_accum + dv_a * restitution_scale;
+			float3 dv_b = (params.margin - info.distance) * restitution_scale * info.world_normal_body - v0;
+			
+			float3 dv(max_ff(dv_a[0], dv_b[0]), max_ff(dv_a[1], dv_b[1]), max_ff(dv_a[2], dv_b[2]));
+			point->force_accum = point->force_accum + dv * restitution_scale;
 //			Debug::collision_contact(point->cur.co, point->cur.co + point->force_accum);
 		}
 	}
@@ -490,6 +488,14 @@ void Solver::step_threaded(float time, float timestep, DebugThreadDataVector *de
 	/* filter and cache Bullet contact information */
 	PointContactCache contacts;
 	cache_point_contacts(contacts);
+	{
+		debug_thread_data->push_back(DebugThreadData());
+		DebugThreadData *thread_data = &debug_thread_data->back();
+		for (int i = 0; i < contacts.size(); ++i) {
+			const PointContactInfo &info = contacts[i];
+			Debug::collision_contact(thread_data, info.world_point_hair, info.world_point_body);
+		}
+	}
 	
 	typedef std::vector<SolverTaskData> SolverTaskVector;
 	
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index faeb3b0..023ee5b 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -69,6 +69,8 @@ typedef struct HairParams {
 	/* collision settings */
 	float restitution;
 	float friction;
+	float margin;
+	int pad;
 } HairParams;
 
 typedef struct HairSystem {
diff --git a/source/blender/makesrna/intern/rna_hair.c b/source/blender/makesrna/intern/rna_hair.c
index 7495996..dbc8dbd 100644
--- a/source/blender/makesrna/intern/rna_hair.c
+++ b/source/blender/makesrna/intern/rna_hair.c
@@ -126,6 +126,13 @@ static void rna_def_hair_params(BlenderRNA *brna)
 	RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
 	RNA_def_property_float_default(prop, 0.0f);
 	RNA_def_property_ui_text(prop, "Restitution", "Amount of energy retained after collision");
+
+	prop = RNA_def_property(srna, "margin", PROP_FLOAT, PROP_DISTANCE);
+	RNA_def_property_float_sdna(prop, NULL, "margin");
+	RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+	RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.01f, 3);
+	RNA_def_property_float_default(prop, 0.02f);
+	RNA_def_property_ui_text(prop, "Margin", "Collision margin to avoid penetration");
 }
 
 static void rna_def_hair_system(BlenderRNA *brna)




More information about the Bf-blender-cvs mailing list