[Bf-blender-cvs] [666a9385c4] cloth-improvements: Implement collision impulse clamping (to prevent explosions)
Luca Rood
noreply at git.blender.org
Sat Mar 18 23:47:07 CET 2017
Commit: 666a9385c4bf2b6cf1b8cd8719f3b22e7f77b764
Author: Luca Rood
Date: Sat Mar 18 16:53:12 2017 -0300
Branches: cloth-improvements
https://developer.blender.org/rB666a9385c4bf2b6cf1b8cd8719f3b22e7f77b764
Implement collision impulse clamping (to prevent explosions)
===================================================================
M release/scripts/startup/bl_ui/properties_physics_cloth.py
M source/blender/blenkernel/intern/collision.c
M source/blender/makesdna/DNA_cloth_types.h
M source/blender/makesrna/intern/rna_cloth.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index c4464a79cf..a141e7e643 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -260,6 +260,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
sub = col.column()
sub.active = cloth.use_collision
sub.prop(cloth, "distance_min", slider=True, text="Distance")
+ sub.prop(cloth, "impulse_clamp")
sub.prop(cloth, "group")
layout.separator()
@@ -279,6 +280,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
sub.active = cloth.use_self_collision
sub.prop(cloth, "self_friction", text="Friction")
sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
+ sub.prop(cloth, "self_impulse_clamp")
sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="Vertex Group")
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index d7fad86355..d6df750682 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -444,7 +444,7 @@ static void free_impulse_clusters(ImpulseCluster *clusters)
/* This allows inserting impulses one by one into the cluster array, and immediately computing the clustering,
* but the clustering isn't exact, because of not knowing all impulses beforehand.
* Seems to be good enough however, and is much faster than the true hclust below... */
-static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const float impulse[3], const float clustang)
+static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const float impulse[3], const float clustang, const float clamp)
{
ImpulseCluster *imp;
ImpulseCluster *close = NULL;
@@ -455,7 +455,7 @@ static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const flo
mag = normalize_v3_v3(dir, impulse);
- if (mag < FLT_EPSILON) {
+ if ((mag < FLT_EPSILON) || (mag > clamp)) {
return;
}
@@ -640,8 +640,8 @@ DO_INLINE void collision_interpolateOnTriangle (float to[3], float v1[3], float
VECADDMUL(to, v3, w3);
}
-static int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd, Object *collob,
- CollPair *collpair, CollPair *collision_end, ImpulseCluster **vert_imp_clusters)
+static int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd, Object *collob, CollPair *collpair,
+ CollPair *collision_end, ImpulseCluster **vert_imp_clusters, const float dt)
{
int result = 0;
Cloth *cloth1;
@@ -792,15 +792,15 @@ static int cloth_collision_response_static(ClothModifierData *clmd, CollisionMod
if (result) {
if (cloth1->verts[collpair->ap1].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap1], i1, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap1], i1, (M_PI / 20), (clmd->coll_parms->clamp * dt));
}
if (cloth1->verts[collpair->ap2].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap2], i2, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap2], i2, (M_PI / 20), (clmd->coll_parms->clamp * dt));
}
if (cloth1->verts[collpair->ap3].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap3], i3, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap3], i3, (M_PI / 20), (clmd->coll_parms->clamp * dt));
}
}
}
@@ -809,7 +809,7 @@ static int cloth_collision_response_static(ClothModifierData *clmd, CollisionMod
}
static int cloth_selfcollision_response_static(ClothModifierData *clmd, CollPair *collpair, CollPair *collision_end,
- ImpulseCluster **vert_imp_clusters)
+ ImpulseCluster **vert_imp_clusters, const float dt)
{
int result = 0;
Cloth *cloth1;
@@ -960,15 +960,15 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd, CollPair
if (result) {
if (cloth1->verts[collpair->ap1].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap1], i1, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap1], i1, (M_PI / 20), (clmd->coll_parms->self_clamp * dt));
}
if (cloth1->verts[collpair->ap2].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap2], i2, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap2], i2, (M_PI / 20), (clmd->coll_parms->self_clamp * dt));
}
if (cloth1->verts[collpair->ap3].impulse_count > 0) {
- insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap3], i3, M_PI / 20);
+ insert_impulse_in_cluster_array(&vert_imp_clusters[collpair->ap3], i3, (M_PI / 20), (clmd->coll_parms->self_clamp * dt));
}
}
}
@@ -1252,7 +1252,7 @@ static void cloth_bvh_selfcollisions_nearcheck(ClothModifierData * clmd, CollPai
}
static int cloth_bvh_objcollisions_resolve (ClothModifierData * clmd, Object **collobjs, CollPair **collisions,
- CollPair **collisions_index, const unsigned int numcollobj)
+ CollPair **collisions_index, const unsigned int numcollobj, const float dt)
{
Cloth *cloth = clmd->clothObject;
int i = 0, j = 0, mvert_num = 0;
@@ -1278,7 +1278,7 @@ static int cloth_bvh_objcollisions_resolve (ClothModifierData * clmd, Object **c
CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
if ( collmd->bvhtree ) {
- result += cloth_collision_response_static(clmd, collmd, collob, collisions[i], collisions_index[i], vert_imp_clusters);
+ result += cloth_collision_response_static(clmd, collmd, collob, collisions[i], collisions_index[i], vert_imp_clusters, dt);
}
}
@@ -1310,7 +1310,7 @@ static int cloth_bvh_objcollisions_resolve (ClothModifierData * clmd, Object **c
return ret;
}
-static int cloth_bvh_selfcollisions_resolve(ClothModifierData * clmd, CollPair *collisions, CollPair *collisions_index)
+static int cloth_bvh_selfcollisions_resolve(ClothModifierData * clmd, CollPair *collisions, CollPair *collisions_index, const float dt)
{
Cloth *cloth = clmd->clothObject;
int i = 0, j = 0, mvert_num = 0;
@@ -1329,7 +1329,7 @@ static int cloth_bvh_selfcollisions_resolve(ClothModifierData * clmd, CollPair *
for (j = 0; j < iter; j++) { /* 5 is just a value that ensures convergence */
result = 0;
- result += cloth_selfcollision_response_static (clmd, collisions, collisions_index, vert_imp_clusters);
+ result += cloth_selfcollision_response_static (clmd, collisions, collisions_index, vert_imp_clusters, dt);
// apply impulses in parallel
if (result) {
@@ -1439,7 +1439,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
MEM_SAFE_FREE(overlap);
}
- ret += cloth_bvh_objcollisions_resolve(clmd, collobjs, collisions, collisions_index, numcollobj);
+ ret += cloth_bvh_objcollisions_resolve(clmd, collobjs, collisions, collisions_index, numcollobj, dt);
ret2 += ret;
for (i = 0; i < numcollobj; i++) {
@@ -1474,7 +1474,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
if (result && overlap) {
cloth_bvh_selfcollisions_nearcheck (clmd, &collisions, &collisions_index, result, overlap);
- ret += cloth_bvh_selfcollisions_resolve ( clmd, collisions, collisions_index);
+ ret += cloth_bvh_selfcollisions_resolve ( clmd, collisions, collisions_index, dt);
ret2 += ret;
}
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 42a3f76cd5..d814763ac1 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -132,6 +132,8 @@ typedef struct ClothCollSettings {
float friction; /* Friction/damping applied on contact with other object.*/
float damping; /* Collision restitution on contact with other object.*/
float selfepsilon; /* for selfcollision */
+ float clamp; /* Impulse clamp for object collisions */
+ float self_clamp; /* Impulse clamp for self collisions */
int flags; /* collision flags defined in BKE_cloth.h */
short loop_count; /* How many iterations for the collision loop. */
short pad[3];
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 85fc5627a2..85995c2d40 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -996,6 +996,12 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
"How many object collision response iterations should be done. (higher is smoother but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "impulse_clamp", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "clamp");
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_text(prop, "Impulse Clamping", "Don't use collision impulses above this magnitude (0.0 to disable clamping)");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* self collision */
prop = RNA_def_property(srna, "use_self_collision", PROP_BOOLEAN, PROP_NONE);
@@ -1033,6 +1039,12 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Response Quality",
"How many self collision response iterations should be done. (higher is better quality but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop = RNA_def_property(srna, "self_impulse_clamp", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "self_clamp");
+ RNA_def_pro
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list