Cloth: option to use dynamic base mesh

This adds the ability for cloth simulations to respect changes in the underlying mesh.
So you can for instance, animate shape keys, armatures, or add any deformation modifiers (above the cloth modifier).

This is mainly useful for (but not limited to) cartoon animations,
where your character might stretch or change shape, and you want the clothes to follow accordingly.

D1903 by @LucaRood
This commit is contained in:
Campbell Barton 2016-07-30 14:47:31 +10:00
parent ca93ebee7f
commit 7a4353160c
4 changed files with 30 additions and 2 deletions

View File

@ -114,10 +114,13 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
col = split.column()
col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
key = ob.data.shape_keys
if key:
sub = col.column()
sub.active = not cloth.use_dynamic_mesh
sub.label(text="Rest Shape Key:")
sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")

View File

@ -171,6 +171,7 @@ typedef enum {
CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12), /* edit cache in editmode */
CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS = (1 << 13), /* don't allow spring compression */
CLOTH_SIMSETTINGS_FLAG_SEW = (1 << 14), /* pull ends of loose edges together */
CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH = (1 << 15), /* make simulation respect deformations in the base object */
} CLOTH_SIMSETTINGS_FLAGS;
/* COLLISION FLAGS */

View File

@ -58,6 +58,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*verte
static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm );
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
static void cloth_update_springs( ClothModifierData *clmd );
static void cloth_update_verts( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_update_spring_lengths( ClothModifierData *clmd, DerivedMesh *dm );
static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
@ -368,10 +369,13 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true);
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH )
cloth_update_verts ( ob, clmd, result );
/* Support for dynamic vertex groups, changing from frame to frame */
cloth_apply_vgroup ( clmd, result );
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW )
if ( clmd->sim_parms->flags & (CLOTH_SIMSETTINGS_FLAG_SEW | CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) )
cloth_update_spring_lengths ( clmd, result );
cloth_update_springs( clmd );
@ -804,7 +808,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->springs = NULL;
clmd->clothObject->numsprings = -1;
if ( clmd->sim_parms->shapekey_rest )
if ( clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) )
shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
mvert = dm->getVertArray (dm);
@ -1180,6 +1184,20 @@ static void cloth_update_springs( ClothModifierData *clmd )
cloth_hair_update_bending_targets(clmd);
}
/* Update rest verts, for dynamically deformable cloth */
static void cloth_update_verts( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
{
unsigned int i = 0;
MVert *mvert = dm->getVertArray (dm);
ClothVertex *verts = clmd->clothObject->verts;
/* vertex count is already ensured to match */
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) {
copy_v3_v3(verts->xrest, mvert[i].co);
mul_m4_v3(ob->obmat, verts->xrest);
}
}
/* Update spring rest lenght, for dynamically deformable cloth */
static void cloth_update_spring_lengths( ClothModifierData *clmd, DerivedMesh *dm )
{

View File

@ -558,6 +558,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Rest Shape Key", "Shape key to use the rest spring lengths from");
RNA_def_property_update(prop, 0, "rna_cloth_update");
prop = RNA_def_property(srna, "use_dynamic_mesh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH);
RNA_def_property_ui_text(prop, "Dynamic Base Mesh", "Make simulation respect deformations in the base mesh");
RNA_def_property_update(prop, 0, "rna_cloth_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
/* unused */
/* unused still */