diff options
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 6 | ||||
-rw-r--r-- | source/blender/physics/intern/BPH_mass_spring.cpp | 8 | ||||
-rw-r--r-- | source/blender/physics/intern/implicit.h | 2 | ||||
-rw-r--r-- | source/blender/physics/intern/implicit_blender.c | 34 |
5 files changed, 42 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index ccb45cb4de2..beb4f226aea 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -65,6 +65,7 @@ typedef struct ClothHairData { float loc[3]; float rot[3][3]; float rest_target[3]; /* rest target direction for each segment */ + float radius; float bending_stiffness; } ClothHairData; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bcd0a0318fb..93eb273fc00 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3007,6 +3007,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int int k, hair_index; float hairmat[4][4]; float max_length; + float hair_radius; dm = *r_dm; if (!dm) { @@ -3034,6 +3035,9 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int psys->clmd->sim_parms->vgroup_mass = 1; + /* XXX placeholder for more flexible future hair settings */ + hair_radius = part->size; + /* make vgroup for pin roots etc.. */ hair_index = 1; LOOP_PARTICLES { @@ -3063,6 +3067,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int copy_v3_v3(hair->loc, root_mat[3]); copy_m3_m4(hair->rot, root_mat); + hair->radius = hair_radius; hair->bending_stiffness = bending_stiffness; add_v3_v3v3(mvert->co, co, co); @@ -3083,6 +3088,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int copy_v3_v3(hair->loc, root_mat[3]); copy_m3_m4(hair->rot, root_mat); + hair->radius = hair_radius; hair->bending_stiffness = bending_stiffness; copy_v3_v3(mvert->co, co); diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index cb30529870f..98a04de8927 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -497,10 +497,16 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB /* Hair has only edges */
if (cloth->numfaces == 0) {
+ ClothHairData *hairdata = clmd->hairdata;
+ ClothHairData *hair_ij, *hair_kl;
+
for (LinkNode *link = cloth->springs; link; link = link->next) {
ClothSpring *spring = (ClothSpring *)link->link;
if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL)
- BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, winvec);
+
+ hair_ij = &hairdata[spring->ij];
+ hair_kl = &hairdata[spring->kl];
+ BPH_mass_spring_force_edge_wind(data, si_ij, si_kl, hair_ij->radius, hair_kl->radius, winvec);
}
}
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index 7081dd507a9..1c9dccb08ed 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -111,7 +111,7 @@ void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float /* Wind force, acting on a face */ void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3]); /* Wind force, acting on an edge */ -void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, const float (*winvec)[3]); +void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3]); /* Linear spring force between two points */ bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, float restlen, float stiffness, float damping, bool no_compress, float clamp_force, diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c index cb115a2c10a..e6320507db0 100644 --- a/source/blender/physics/intern/implicit_blender.c +++ b/source/blender/physics/intern/implicit_blender.c @@ -1461,21 +1461,41 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3 } } -void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3]) +static void edge_wind_vertex(const float dir[3], float length, float radius, const float wind[3], float f[3], float UNUSED(dfdx[3][3]), float UNUSED(dfdv[3][3])) { - const float effector_scale = 0.01; - float win[3], dir[3], nor[3], length; + const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */ + float cos_alpha, sin_alpha, cross_section; + float windlen = len_v3(wind); + + if (windlen == 0.0f) { + zero_v3(f); + return; + } + + /* angle of wind direction to edge */ + cos_alpha = dot_v3v3(wind, dir) / windlen; + sin_alpha = sqrt(1.0 - cos_alpha*cos_alpha); + cross_section = radius * (M_PI * radius * sin_alpha + length * cos_alpha); + + mul_v3_v3fl(f, wind, density * cross_section); +} + +void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3]) +{ + float win[3], dir[3], length; + float f[3], dfdx[3][3], dfdv[3][3]; sub_v3_v3v3(dir, data->X[v1], data->X[v2]); length = normalize_v3(dir); world_to_root_v3(data, v1, win, winvec[v1]); - madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir)); - madd_v3_v3fl(data->F[v1], nor, effector_scale * length); + edge_wind_vertex(dir, length, radius1, win, f, dfdx, dfdv); + add_v3_v3(data->F[v1], f); world_to_root_v3(data, v2, win, winvec[v2]); - madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir)); - madd_v3_v3fl(data->F[v2], nor, effector_scale * length); + /* use -length to invert edge direction */ + edge_wind_vertex(dir, length, radius2, win, f, dfdx, dfdv); + add_v3_v3(data->F[v2], f); } BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k) |