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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/collision.c171
1 files changed, 59 insertions, 112 deletions
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index f358355912b..7015e36be1a 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -647,6 +647,31 @@ DO_INLINE void collision_interpolateOnTriangle(float to[3],
VECADDMUL(to, v3, w3);
}
+static void cloth_selfcollision_impulse_vert(const float clamp_sq,
+ const float impulse[3],
+ struct ClothVertex *vert)
+{
+ float impulse_len_sq = len_squared_v3(impulse);
+
+ if ((clamp_sq > 0.0f) && (impulse_len_sq > clamp_sq)) {
+ return;
+ }
+
+ if (fabsf(vert->impulse[0]) < fabsf(impulse[0])) {
+ vert->impulse[0] = impulse[0];
+ }
+
+ if (fabsf(vert->impulse[1]) < fabsf(impulse[1])) {
+ vert->impulse[1] = impulse[1];
+ }
+
+ if (fabsf(vert->impulse[2]) < fabsf(impulse[2])) {
+ vert->impulse[2] = impulse[2];
+ }
+
+ vert->impulse_count++;
+}
+
static int cloth_collision_response_static(ClothModifierData *clmd,
CollisionModifierData *collmd,
Object *collob,
@@ -665,11 +690,12 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
cloth1 = clmd->clothObject;
for (int i = 0; i < collision_count; i++, collpair++) {
- float i1[3], i2[3], i3[3];
-
+ float i1[3], i2[3], i3[3], time_multiplier, d;
zero_v3(i1);
zero_v3(i2);
zero_v3(i3);
+ time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
+ d = clmd->coll_parms->epsilon * 8.0f / 9.0f + epsilon2 * 8.0f / 9.0f - collpair->distance;
/* Only handle static collisions here. */
if (collpair->flag & (COLLISION_IN_FUTURE | COLLISION_INACTIVE)) {
@@ -728,11 +754,10 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
/* If magrelVel < 0 the edges are approaching each other. */
if (magrelVel > 0.0f) {
/* Calculate Impulse magnitude to stop all motion in normal direction. */
- float magtangent = 0, repulse = 0, d = 0;
+ float magtangent = 0, repulse = 0;
double impulse = 0.0;
float vrel_t_pre[3];
float temp[3];
- float time_multiplier;
/* Calculate tangential velocity. */
copy_v3_v3(temp, collpair->normal);
@@ -762,20 +787,11 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
impulse = magrelVel / 1.5f;
VECADDMUL(i1, collpair->normal, w1 * impulse);
- cloth1->verts[collpair->ap1].impulse_count++;
-
VECADDMUL(i2, collpair->normal, w2 * impulse);
- cloth1->verts[collpair->ap2].impulse_count++;
-
if (!is_hair) {
VECADDMUL(i3, collpair->normal, w3 * impulse);
- cloth1->verts[collpair->ap3].impulse_count++;
}
- time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
-
- d = clmd->coll_parms->epsilon * 8.0f / 9.0f + epsilon2 * 8.0f / 9.0f - collpair->distance;
-
if ((magrelVel < 0.1f * d * time_multiplier) && (d > ALMOST_ZERO)) {
repulse = MIN2(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel);
@@ -790,7 +806,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
VECADDMUL(i1, collpair->normal, impulse);
VECADDMUL(i2, collpair->normal, impulse);
-
if (!is_hair) {
VECADDMUL(i3, collpair->normal, impulse);
}
@@ -798,92 +813,33 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
result = 1;
}
- else {
- float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
- float d;
-
- d = clmd->coll_parms->epsilon * 8.0f / 9.0f + epsilon2 * 8.0f / 9.0f - collpair->distance;
-
- if (d > ALMOST_ZERO) {
- /* Stay on the safe side and clamp repulse. */
- float repulse = d / time_multiplier;
- float impulse = repulse / 4.5f;
-
- VECADDMUL(i1, collpair->normal, w1 * impulse);
- VECADDMUL(i2, collpair->normal, w2 * impulse);
+ else if (d > ALMOST_ZERO) {
+ /* Stay on the safe side and clamp repulse. */
+ float repulse = d / time_multiplier;
+ float impulse = repulse / 4.5f;
- if (!is_hair) {
- VECADDMUL(i3, collpair->normal, w3 * impulse);
- }
-
- cloth1->verts[collpair->ap1].impulse_count++;
- cloth1->verts[collpair->ap2].impulse_count++;
-
- if (!is_hair) {
- cloth1->verts[collpair->ap3].impulse_count++;
- }
+ VECADDMUL(i1, collpair->normal, w1 * impulse);
+ VECADDMUL(i2, collpair->normal, w2 * impulse);
- result = 1;
+ if (!is_hair) {
+ VECADDMUL(i3, collpair->normal, w3 * impulse);
}
+
+ result = 1;
}
if (result) {
- float clamp = clmd->coll_parms->clamp * dt;
-
- if ((clamp > 0.0f) &&
- ((len_v3(i1) > clamp) || (len_v3(i2) > clamp) || (len_v3(i3) > clamp))) {
- return 0;
- }
-
- for (int j = 0; j < 3; j++) {
- if (cloth1->verts[collpair->ap1].impulse_count > 0 &&
- fabsf(cloth1->verts[collpair->ap1].impulse[j]) < fabsf(i1[j])) {
- cloth1->verts[collpair->ap1].impulse[j] = i1[j];
- }
-
- if (cloth1->verts[collpair->ap2].impulse_count > 0 &&
- fabsf(cloth1->verts[collpair->ap2].impulse[j]) < fabsf(i2[j])) {
- cloth1->verts[collpair->ap2].impulse[j] = i2[j];
- }
-
- if (!is_hair) {
- if (cloth1->verts[collpair->ap3].impulse_count > 0 &&
- fabsf(cloth1->verts[collpair->ap3].impulse[j]) < fabsf(i3[j])) {
- cloth1->verts[collpair->ap3].impulse[j] = i3[j];
- }
- }
- }
+ float clamp_sq = clmd->coll_parms->clamp * dt;
+ clamp_sq *= clamp_sq;
+ cloth_selfcollision_impulse_vert(clamp_sq, i1, &cloth1->verts[collpair->ap1]);
+ cloth_selfcollision_impulse_vert(clamp_sq, i2, &cloth1->verts[collpair->ap2]);
+ cloth_selfcollision_impulse_vert(clamp_sq, i3, &cloth1->verts[collpair->ap3]);
}
}
return result;
}
-static void cloth_selfcollision_impulse_vert(const float clamp_sq,
- const float impulse[3],
- struct ClothVertex *vert)
-{
- float impulse_len_sq = len_squared_v3(impulse);
-
- if ((clamp_sq > 0.0f) && (impulse_len_sq > clamp_sq)) {
- return;
- }
-
- if (fabsf(vert->impulse[0]) < fabsf(impulse[0])) {
- vert->impulse[0] = impulse[0];
- }
-
- if (fabsf(vert->impulse[1]) < fabsf(impulse[1])) {
- vert->impulse[1] = impulse[1];
- }
-
- if (fabsf(vert->impulse[2]) < fabsf(impulse[2])) {
- vert->impulse[2] = impulse[2];
- }
-
- vert->impulse_count++;
-}
-
static int cloth_selfcollision_response_static(ClothModifierData *clmd,
CollPair *collpair,
uint collision_count,
@@ -900,6 +856,8 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
for (int i = 0; i < collision_count; i++, collpair++) {
float ia[3][3] = {{0.0f}};
float ib[3][3] = {{0.0f}};
+ float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
+ float d = clmd->coll_parms->selfepsilon * 8.0f / 9.0f * 2.0f - collpair->distance;
/* Only handle static collisions here. */
if (collpair->flag & (COLLISION_IN_FUTURE | COLLISION_INACTIVE)) {
@@ -952,10 +910,10 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
/* If magrelVel < 0 the edges are approaching each other. */
if (magrelVel > 0.0f) {
/* Calculate Impulse magnitude to stop all motion in normal direction. */
- float magtangent = 0, repulse = 0, d = 0;
+ float magtangent = 0, repulse = 0;
double impulse = 0.0;
float vrel_t_pre[3];
- float temp[3], time_multiplier;
+ float temp[3];
/* Calculate tangential velocity. */
copy_v3_v3(temp, collpair->normal);
@@ -993,10 +951,6 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
VECADDMUL(ib[1], collpair->normal, -u2 * impulse);
VECADDMUL(ib[2], collpair->normal, -u3 * impulse);
- time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
-
- d = clmd->coll_parms->selfepsilon * 8.0f / 9.0f * 2.0f - collpair->distance;
-
if ((magrelVel < 0.1f * d * time_multiplier) && (d > ALMOST_ZERO)) {
repulse = MIN2(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel);
@@ -1019,27 +973,20 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
result = 1;
}
- else {
- float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
- float d;
-
- d = clmd->coll_parms->selfepsilon * 8.0f / 9.0f * 2.0f - collpair->distance;
+ else if (d > ALMOST_ZERO) {
+ /* Stay on the safe side and clamp repulse. */
+ float repulse = d * 1.0f / time_multiplier;
+ float impulse = repulse / 9.0f;
- if (d > ALMOST_ZERO) {
- /* Stay on the safe side and clamp repulse. */
- float repulse = d * 1.0f / time_multiplier;
- float impulse = repulse / 9.0f;
-
- VECADDMUL(ia[0], collpair->normal, w1 * impulse);
- VECADDMUL(ia[1], collpair->normal, w2 * impulse);
- VECADDMUL(ia[2], collpair->normal, w3 * impulse);
+ VECADDMUL(ia[0], collpair->normal, w1 * impulse);
+ VECADDMUL(ia[1], collpair->normal, w2 * impulse);
+ VECADDMUL(ia[2], collpair->normal, w3 * impulse);
- VECADDMUL(ib[0], collpair->normal, -u1 * impulse);
- VECADDMUL(ib[1], collpair->normal, -u2 * impulse);
- VECADDMUL(ib[2], collpair->normal, -u3 * impulse);
+ VECADDMUL(ib[0], collpair->normal, -u1 * impulse);
+ VECADDMUL(ib[1], collpair->normal, -u2 * impulse);
+ VECADDMUL(ib[2], collpair->normal, -u3 * impulse);
- result = 1;
- }
+ result = 1;
}
if (result) {