Cloth: Add support for "Self Collision Vertex Group".

Self collision vertex groups enable artists to exclude selected vertices from getting involved in self collisions. This speeds simulations and it also resolves some self collision issues.
This commit is contained in:
Daniel Genrich 2012-06-06 13:30:05 +00:00
parent d6ebba4c9e
commit 0499200e39
6 changed files with 49 additions and 4 deletions

@ -145,6 +145,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
cloth = context.cloth.collision_settings
md = context.cloth
ob = context.object
layout.active = cloth.use_collision and cloth_panel_enabled(md)
@ -163,6 +164,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
sub.active = cloth.use_self_collision
sub.prop(cloth, "self_collision_quality", slider=True, text="Quality")
sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="")
layout.prop(cloth, "group")

@ -56,7 +56,7 @@ struct CollisionTree;
/* Bits to or into the ClothVertex.flags. */
#define CLOTH_VERT_FLAG_PINNED 1
#define CLOTH_VERT_FLAG_COLLISION 2
#define CLOTH_VERT_FLAG_NOSELFCOLL 2 /* vertex NOT used for self collisions */
#define CLOTH_VERT_FLAG_PINNED_EM 3
/**

@ -143,6 +143,7 @@ void cloth_init(ClothModifierData *clmd )
clmd->coll_parms->collision_list = NULL;
clmd->coll_parms->self_loop_count = 1.0;
clmd->coll_parms->selfepsilon = 0.75;
clmd->coll_parms->vgroup_selfcol = 0;
/* These defaults are copied from softbody.c's
* softbody_calc_forces() function.
@ -756,10 +757,12 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*verte
int cloth_uses_vgroup(ClothModifierData *clmd)
{
return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) ||
(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)) &&
((clmd->sim_parms->vgroup_mass>0) ||
(clmd->sim_parms->vgroup_struct>0)||
(clmd->sim_parms->vgroup_bend>0)));
(clmd->sim_parms->vgroup_bend>0) ||
(clmd->coll_parms->vgroup_selfcol>0)));
}
/**
@ -815,6 +818,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
verts->bend_stiff = dvert->dw [j].weight;
}
}
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) {
if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) {
if( dvert->dw [j].weight > 0.0)
verts->flags |= CLOTH_VERT_FLAG_NOSELFCOLL;
}
}
/*
// for later
if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1))

@ -840,6 +840,10 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
continue;
}
}
if( ( cloth->verts[i].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) ||
( cloth->verts[j].flags & CLOTH_VERT_FLAG_NOSELFCOLL ) )
continue;
sub_v3_v3v3(temp, verts[i].tx, verts[j].tx);

@ -83,7 +83,7 @@ typedef struct ClothSimSettings
short shapekey_rest; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short reset;
short pad;
short pad;
struct EffectorWeights *effector_weights;
} ClothSimSettings;
@ -101,6 +101,9 @@ typedef struct ClothCollSettings
short self_loop_count; /* How many iterations for the selfcollision loop */
short loop_count; /* How many iterations for the collision loop. */
struct Group *group; /* Only use colliders from this group of objects */
short vgroup_selfcol; /* vgroup to paint which vertices are used for self collisions */
short pad;
int pad2;
} ClothCollSettings;

@ -155,6 +155,25 @@ static void rna_ClothSettings_bend_vgroup_set(PointerRNA *ptr, const char *value
rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_bend);
}
static void rna_CollSettings_selfcol_vgroup_get(PointerRNA *ptr, char *value)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
rna_object_vgroup_name_index_get(ptr, value, coll->vgroup_selfcol);
}
static int rna_CollSettings_selfcol_vgroup_length(PointerRNA *ptr)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
return rna_object_vgroup_name_index_length(ptr, coll->vgroup_selfcol);
}
static void rna_CollSettings_selfcol_vgroup_set(PointerRNA *ptr, const char *value)
{
ClothCollSettings *coll = (ClothCollSettings *)ptr->data;
rna_object_vgroup_name_index_set(ptr, value, &coll->vgroup_selfcol);
}
static PointerRNA rna_ClothSettings_rest_shape_key_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
@ -523,6 +542,13 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "vertex_group_self_collisions", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_CollSettings_selfcol_vgroup_get", "rna_CollSettings_selfcol_vgroup_length",
"rna_CollSettings_selfcol_vgroup_set");
RNA_def_property_ui_text(prop, "Selfcollision Vertex Group",
"Vertex group to define vertices which are not used during self collisions.");
RNA_def_property_update(prop, 0, "rna_cloth_update");
}
void RNA_def_cloth(BlenderRNA *brna)