Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/physics')
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp8
-rw-r--r--source/blender/physics/intern/implicit.h2
-rw-r--r--source/blender/physics/intern/implicit_blender.c34
3 files changed, 35 insertions, 9 deletions
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)