forked from bartvdbraak/blender
Randomness factor for hair bending stiffness.
This helps to create some variation in a hair system, which can otherwise become very uniform and boring. It's yet another confusing setting in a system that should have been nodified, but only option for now (broken windows ...) Conflicts: source/blender/blenkernel/intern/particle_system.c source/blender/physics/intern/BPH_mass_spring.cpp
This commit is contained in:
parent
64a4d4ed25
commit
d031831a05
@ -313,8 +313,10 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
|
||||
col = split.column()
|
||||
col.label(text="Structure")
|
||||
col.prop(cloth, "mass")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(cloth, "bending_stiffness", text="Stiffness")
|
||||
sub = col.column(align=True)
|
||||
subsub = sub.row(align=True)
|
||||
subsub.prop(cloth, "bending_stiffness", text="Stiffness")
|
||||
subsub.prop(psys.settings, "bending_random", text="Random")
|
||||
sub.prop(cloth, "bending_damping", text="Damping")
|
||||
# XXX has no noticable effect with stiff hair structure springs
|
||||
#col.prop(cloth, "spring_damping", text="Damping")
|
||||
|
@ -61,11 +61,12 @@ typedef enum eClothVertexFlag {
|
||||
CLOTH_VERT_FLAG_NOSELFCOLL = 2, /* vertex NOT used for self collisions */
|
||||
} eClothVertexFlag;
|
||||
|
||||
typedef struct ClothHairRoot {
|
||||
typedef struct ClothHairData {
|
||||
float loc[3];
|
||||
float rot[3][3];
|
||||
float rest_target[3]; /* rest target direction for each segment */
|
||||
} ClothHairRoot;
|
||||
float bending_stiffness;
|
||||
} ClothHairData;
|
||||
|
||||
typedef struct ClothSolverResult {
|
||||
int status;
|
||||
|
@ -1072,15 +1072,15 @@ static void cloth_update_bending_targets(ClothModifierData *clmd)
|
||||
prev_mn = -1;
|
||||
for (search = cloth->springs; search; search = search->next) {
|
||||
ClothSpring *spring = search->link;
|
||||
ClothHairRoot *hair_ij, *hair_kl;
|
||||
ClothHairData *hair_ij, *hair_kl;
|
||||
bool is_root = spring->kl != prev_mn;
|
||||
|
||||
if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hair_ij = &clmd->roots[spring->ij];
|
||||
hair_kl = &clmd->roots[spring->kl];
|
||||
hair_ij = &clmd->hairdata[spring->ij];
|
||||
hair_kl = &clmd->hairdata[spring->kl];
|
||||
if (is_root) {
|
||||
/* initial hair frame from root orientation */
|
||||
copy_m3_m3(hair_frame, hair_ij->rot);
|
||||
@ -1144,15 +1144,15 @@ static void cloth_update_bending_rest_targets(ClothModifierData *clmd)
|
||||
prev_mn = -1;
|
||||
for (search = cloth->springs; search; search = search->next) {
|
||||
ClothSpring *spring = search->link;
|
||||
ClothHairRoot *hair_ij, *hair_kl;
|
||||
ClothHairData *hair_ij, *hair_kl;
|
||||
bool is_root = spring->kl != prev_mn;
|
||||
|
||||
if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hair_ij = &clmd->roots[spring->ij];
|
||||
hair_kl = &clmd->roots[spring->kl];
|
||||
hair_ij = &clmd->hairdata[spring->ij];
|
||||
hair_kl = &clmd->hairdata[spring->kl];
|
||||
if (is_root) {
|
||||
/* initial hair frame from root orientation */
|
||||
copy_m3_m3(hair_frame, hair_ij->rot);
|
||||
@ -1198,6 +1198,16 @@ static void cloth_update_springs( ClothModifierData *clmd )
|
||||
else if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
|
||||
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
|
||||
}
|
||||
else if (spring->type == CLOTH_SPRING_TYPE_BENDING_ANG) {
|
||||
ClothVertex *v1 = &cloth->verts[spring->ij];
|
||||
ClothVertex *v2 = &cloth->verts[spring->kl];
|
||||
if (clmd->hairdata) {
|
||||
/* copy extra hair data to generic cloth vertices */
|
||||
v1->bend_stiff = clmd->hairdata[spring->ij].bending_stiffness;
|
||||
v2->bend_stiff = clmd->hairdata[spring->kl].bending_stiffness;
|
||||
}
|
||||
spring->stiffness = (v1->bend_stiff + v2->bend_stiff) / 2.0f;
|
||||
}
|
||||
else if (spring->type == CLOTH_SPRING_TYPE_GOAL) {
|
||||
/* Warning: Appending NEW goal springs does not work because implicit solver would need reset! */
|
||||
|
||||
|
@ -2993,11 +2993,12 @@ static MDeformVert *hair_set_pinning(MDeformVert *dvert, float weight)
|
||||
return dvert;
|
||||
}
|
||||
|
||||
static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairRoot **r_roots)
|
||||
static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairData **r_hairdata)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
DerivedMesh *dm;
|
||||
ClothHairRoot *roots;
|
||||
ClothHairData *hairdata;
|
||||
MVert *mvert;
|
||||
MEdge *medge;
|
||||
MDeformVert *dvert;
|
||||
@ -3016,9 +3017,9 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
|
||||
medge = CDDM_get_edges(dm);
|
||||
dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
|
||||
|
||||
roots = *r_roots;
|
||||
if (!roots) {
|
||||
*r_roots = roots = MEM_mallocN(sizeof(ClothHairRoot) * totpoint, "hair roots");
|
||||
hairdata = *r_hairdata;
|
||||
if (!hairdata) {
|
||||
*r_hairdata = hairdata = MEM_mallocN(sizeof(ClothHairData) * totpoint, "hair data");
|
||||
}
|
||||
|
||||
/* calculate maximum segment length */
|
||||
@ -3037,6 +3038,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
|
||||
hair_index = 1;
|
||||
LOOP_PARTICLES {
|
||||
float root_mat[4][4];
|
||||
float bending_stiffness;
|
||||
bool use_hair;
|
||||
|
||||
pa->hair_index = hair_index;
|
||||
@ -3046,8 +3048,10 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
|
||||
mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
|
||||
normalize_m4(root_mat);
|
||||
|
||||
bending_stiffness = 1.0f - part->bending_random * psys_frand(psys, p + 666);
|
||||
|
||||
for (k=0, key=pa->hair; k<pa->totkey; k++,key++) {
|
||||
ClothHairRoot *root;
|
||||
ClothHairData *hair;
|
||||
float *co, *co_next;
|
||||
|
||||
co = key->co;
|
||||
@ -3055,9 +3059,11 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
|
||||
|
||||
/* create fake root before actual root to resist bending */
|
||||
if (k==0) {
|
||||
root = &psys->clmd->roots[pa->hair_index - 1];
|
||||
copy_v3_v3(root->loc, root_mat[3]);
|
||||
copy_m3_m4(root->rot, root_mat);
|
||||
hair = &psys->clmd->hairdata[pa->hair_index - 1];
|
||||
copy_v3_v3(hair->loc, root_mat[3]);
|
||||
copy_m3_m4(hair->rot, root_mat);
|
||||
|
||||
hair->bending_stiffness = bending_stiffness;
|
||||
|
||||
add_v3_v3v3(mvert->co, co, co);
|
||||
sub_v3_v3(mvert->co, co_next);
|
||||
@ -3073,9 +3079,11 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
|
||||
}
|
||||
|
||||
/* store root transform in cloth data */
|
||||
root = &psys->clmd->roots[pa->hair_index + k];
|
||||
copy_v3_v3(root->loc, root_mat[3]);
|
||||
copy_m3_m4(root->rot, root_mat);
|
||||
hair = &psys->clmd->hairdata[pa->hair_index + k];
|
||||
copy_v3_v3(hair->loc, root_mat[3]);
|
||||
copy_m3_m4(hair->rot, root_mat);
|
||||
|
||||
hair->bending_stiffness = bending_stiffness;
|
||||
|
||||
copy_v3_v3(mvert->co, co);
|
||||
mul_m4_v3(hairmat, mvert->co);
|
||||
@ -3137,14 +3145,14 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
|
||||
}
|
||||
}
|
||||
|
||||
if (!psys->hair_in_dm || !psys->clmd->roots || realloc_roots) {
|
||||
if (psys->clmd->roots) {
|
||||
MEM_freeN(psys->clmd->roots);
|
||||
psys->clmd->roots = NULL;
|
||||
if (!psys->hair_in_dm || !psys->clmd->hairdata || realloc_roots) {
|
||||
if (psys->clmd->hairdata) {
|
||||
MEM_freeN(psys->clmd->hairdata);
|
||||
psys->clmd->hairdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->roots);
|
||||
hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->hairdata);
|
||||
|
||||
if (psys->hair_out_dm)
|
||||
psys->hair_out_dm->release(psys->hair_out_dm);
|
||||
|
@ -3934,7 +3934,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
|
||||
if (psys->clmd) {
|
||||
psys->clmd = newdataadr(fd, psys->clmd);
|
||||
psys->clmd->clothObject = NULL;
|
||||
psys->clmd->roots = NULL;
|
||||
psys->clmd->hairdata = NULL;
|
||||
|
||||
psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
|
||||
psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
|
||||
@ -4664,7 +4664,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
ClothModifierData *clmd = (ClothModifierData *)md;
|
||||
|
||||
clmd->clothObject = NULL;
|
||||
clmd->roots = NULL;
|
||||
clmd->hairdata = NULL;
|
||||
|
||||
clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
|
||||
clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
|
||||
|
@ -565,7 +565,7 @@ typedef struct ClothModifierData {
|
||||
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
|
||||
struct ListBase ptcaches;
|
||||
/* XXX nasty hack, remove once hair can be separated from cloth modifier data */
|
||||
struct ClothHairRoot *roots;
|
||||
struct ClothHairData *hairdata;
|
||||
/* grid geometry values of hair continuum */
|
||||
float hair_grid_min[3];
|
||||
float hair_grid_max[3];
|
||||
|
@ -234,6 +234,10 @@ typedef struct ParticleSettings {
|
||||
/* keyed particles */
|
||||
int keyed_loops;
|
||||
|
||||
/* hair dynamics */
|
||||
float bending_random;
|
||||
int pad3;
|
||||
|
||||
struct MTex *mtex[18]; /* MAX_MTEX */
|
||||
|
||||
struct Group *dup_group;
|
||||
|
@ -2318,6 +2318,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Segments", "Number of hair segments");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop = RNA_def_property(srna, "bending_random", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "bending_random");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Random Bending Stiffness", "Random stiffness of hairs");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
/*TODO: not found in UI, readonly? */
|
||||
prop = RNA_def_property(srna, "keys_step", PROP_INT, PROP_NONE);
|
||||
|
@ -178,7 +178,7 @@ static void copyData(ModifierData *md, ModifierData *target)
|
||||
tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
|
||||
tclmd->point_cache->step = 1;
|
||||
tclmd->clothObject = NULL;
|
||||
tclmd->roots = NULL;
|
||||
tclmd->hairdata = NULL;
|
||||
tclmd->solver_result = NULL;
|
||||
tclmd->debug_data = NULL;
|
||||
}
|
||||
@ -209,8 +209,8 @@ static void freeData(ModifierData *md)
|
||||
BKE_ptcache_free_list(&clmd->ptcaches);
|
||||
clmd->point_cache = NULL;
|
||||
|
||||
if (clmd->roots)
|
||||
MEM_freeN(clmd->roots);
|
||||
if (clmd->hairdata)
|
||||
MEM_freeN(clmd->hairdata);
|
||||
|
||||
if (clmd->solver_result)
|
||||
MEM_freeN(clmd->solver_result);
|
||||
|
@ -114,11 +114,11 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
unsigned int numverts = cloth->numverts, i;
|
||||
ClothHairRoot *cloth_roots = clmd->roots;
|
||||
ClothHairData *cloth_hairdata = clmd->hairdata;
|
||||
Implicit_Data *id = cloth->implicit;
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
ClothHairRoot *root = &cloth_roots[i];
|
||||
ClothHairData *root = &cloth_hairdata[i];
|
||||
|
||||
BPH_mass_spring_set_rest_transform(id, i, root->rot);
|
||||
BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
|
||||
|
Loading…
Reference in New Issue
Block a user