Fix for invalid access to undefined hair data in edge-only cloth meshes.
Cloth data is used both for hair and actual cloth, which makes things really difficult. The face number was used for distinguishing the two types (no faces == hair mesh), but the extra hair data necessary for hair sim is generated by particles and not available for edge-only cloth meshes. This really needs to be sanitized ... Conflicts: source/blender/physics/intern/BPH_mass_spring.cpp
This commit is contained in:
@@ -1054,13 +1054,16 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNode **edgelist)
|
||||
}
|
||||
}
|
||||
|
||||
static void cloth_update_bending_targets(ClothModifierData *clmd)
|
||||
static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
LinkNode *search = NULL;
|
||||
float hair_frame[3][3], dir_old[3], dir_new[3];
|
||||
int prev_mn; /* to find hair chains */
|
||||
|
||||
if (!clmd->hairdata)
|
||||
return;
|
||||
|
||||
/* XXX Note: we need to propagate frames from the root up,
|
||||
* but structural hair springs are stored in reverse order.
|
||||
* The bending springs however are then inserted in the same
|
||||
@@ -1126,13 +1129,16 @@ static void cloth_update_bending_targets(ClothModifierData *clmd)
|
||||
}
|
||||
}
|
||||
|
||||
static void cloth_update_bending_rest_targets(ClothModifierData *clmd)
|
||||
static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd)
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
LinkNode *search = NULL;
|
||||
float hair_frame[3][3], dir_old[3], dir_new[3];
|
||||
int prev_mn; /* to find hair roots */
|
||||
|
||||
if (!clmd->hairdata)
|
||||
return;
|
||||
|
||||
/* XXX Note: we need to propagate frames from the root up,
|
||||
* but structural hair springs are stored in reverse order.
|
||||
* The bending springs however are then inserted in the same
|
||||
@@ -1225,7 +1231,7 @@ static void cloth_update_springs( ClothModifierData *clmd )
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
cloth_update_bending_targets(clmd);
|
||||
cloth_hair_update_bending_targets(clmd);
|
||||
}
|
||||
|
||||
BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3])
|
||||
@@ -1504,7 +1510,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
}
|
||||
}
|
||||
|
||||
cloth_update_bending_rest_targets(clmd);
|
||||
cloth_hair_update_bending_rest_targets(clmd);
|
||||
}
|
||||
|
||||
/* note: the edges may already exist so run reinsert */
|
||||
|
@@ -51,6 +51,8 @@ extern "C" {
|
||||
#include "BPH_mass_spring.h"
|
||||
#include "implicit.h"
|
||||
|
||||
static float I3[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
|
||||
|
||||
/* Number of off-diagonal non-zero matrix blocks.
|
||||
* Basically there is one of these for each vertex-vertex interaction.
|
||||
*/
|
||||
@@ -118,10 +120,16 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
|
||||
Implicit_Data *id = cloth->implicit;
|
||||
|
||||
for (i = 0; i < numverts; 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);
|
||||
if (cloth_hairdata) {
|
||||
ClothHairData *root = &cloth_hairdata[i];
|
||||
BPH_mass_spring_set_rest_transform(id, i, root->rot);
|
||||
}
|
||||
else
|
||||
BPH_mass_spring_set_rest_transform(id, i, I3);
|
||||
|
||||
BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,19 +512,29 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
for (LinkNode *link = cloth->springs; link; link = link->next) {
|
||||
ClothSpring *spring = (ClothSpring *)link->link;
|
||||
if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL)
|
||||
hair_ij = &hairdata[spring->ij];
|
||||
hair_kl = &hairdata[spring->kl];
|
||||
BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, hair_ij->radius, hair_kl->radius, winvec);
|
||||
}
|
||||
if (hairdata) {
|
||||
hair_ij = &hairdata[spring->ij];
|
||||
hair_kl = &hairdata[spring->kl];
|
||||
BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, hair_ij->radius, hair_kl->radius, winvec);
|
||||
}
|
||||
else
|
||||
BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, 1.0f, 1.0f, winvec);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ClothHairData *hairdata = clmd->hairdata;
|
||||
|
||||
vert = cloth->verts;
|
||||
for (i = 0; i < cloth->numverts; i++, vert++) {
|
||||
ClothHairData *hair = &hairdata[i];
|
||||
if (vert->solver_index < 0)
|
||||
continue;
|
||||
|
||||
BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
|
||||
if (hairdata) {
|
||||
ClothHairData *hair = &hairdata[i];
|
||||
BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
|
||||
}
|
||||
else
|
||||
BPH_mass_spring_force_vertex_wind(data, i, 1.0f, winvec);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user