[Bf-blender-cvs] [9c1016b74e1] fracture_modifier: fix for rotation calculation in anim bind
Martin Felke
noreply at git.blender.org
Mon Jun 17 11:38:14 CEST 2019
Commit: 9c1016b74e15cb038f91b4f8aad56cf9c30397fe
Author: Martin Felke
Date: Mon Jun 17 10:45:38 2019 +0200
Branches: fracture_modifier
https://developer.blender.org/rB9c1016b74e15cb038f91b4f8aad56cf9c30397fe
fix for rotation calculation in anim bind
===================================================================
M source/blender/blenkernel/intern/fracture.c
===================================================================
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index a7bae68ca67..4b458cfd405 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -3953,6 +3953,35 @@ void activate(MeshIsland *mi, AnimBind *bind)
}
}
}
+static float verts_to_quat(float quat[4], float v1[3], float v2[3], float v3[3], bool fallback)
+{
+ float l1, l2, l3, lmax, thresh, co1[3], co2[3], co3[3];
+
+ //hypotenuse... find it
+ l1 = len_v3v3(v1, v2);
+ l2 = len_v3v3(v2, v3);
+ l3 = len_v3v3(v1, v3);
+ lmax = MAX3(l1, l2, l3);
+ thresh = 2 * area_tri_v3(v1, v2, v3) / (lmax * lmax);
+
+ copy_v3_v3(co1, v1);
+ copy_v3_v3(co2, v2);
+ copy_v3_v3(co3, v3);
+
+ if ((thresh < 0.1f) && fallback)
+ {
+ float cor[3][3] = {{0.1f, 0.0f, 0.0f}, {0.0f, -0.15f, 0.0f}, {0.0f, 0.0f, 0.2f}} ;
+ //printf("Degenerate %f triangle, correcting %d %d %d in %d\n", thresh, v1, v2, v3, mi->id);
+ add_v3_v3(co1, cor[0]);
+ add_v3_v3(co2, cor[1]);
+ add_v3_v3(co3, cor[2]);
+ }
+
+ tri_to_quat(quat, co1, co2, co3);
+
+ return thresh;
+}
+
void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bind)
{
@@ -3974,7 +4003,7 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
if (fmd->anim_mesh_ob == ob)
return;
- dm = eval_mod_stack_simple(fmd->anim_mesh_ob);
+ dm = fmd->anim_mesh_ob->derivedFinal; //eval_mod_stack_simple(fmd->anim_mesh_ob);
if (!dm)
return;
@@ -4015,6 +4044,7 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
fmd->anim_bind[i].v = -1;
fmd->anim_bind[i].v1 = -1;
fmd->anim_bind[i].v2 = -1;
+ fmd->anim_bind[i].poly = -1;
zero_v3(fmd->anim_bind[i].offset);
zero_v3(fmd->anim_bind[i].no);
unit_qt(fmd->anim_bind[i].quat);
@@ -4066,6 +4096,7 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
if (do_bind)
{
i = 0;
+ float limit = 0.0001f;
for (mi = fmd->meshIslands.first; mi; mi = mi->next, i++)
{
KDTreeNearest n;
@@ -4081,7 +4112,7 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
if (totpoly > 0)
{
int v1, v2, v3;
- float limit = 0.0001f;
+
MPoly *mp = mpoly + n.index;
MLoop *ml = mloop + mp->loopstart;
BKE_mesh_calc_poly_normal(mp, ml, mvert, f_no);
@@ -4113,9 +4144,40 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
mi->rigidbody->flag |= RBO_FLAG_KINEMATIC_BOUND;
}
else {
- fmd->anim_bind[i].v = n.index;
- fmd->anim_bind[i].v1 = -1;
- fmd->anim_bind[i].v2 = -1;
+ int k = 0;
+ bool found = false;
+ KDTreeNearest n2[12];
+ BLI_kdtree_find_nearest_n(tree, co, &n2, 12);
+ fmd->anim_bind[i].v = n2[0].index;
+ fmd->anim_bind[i].v1 = n2[1].index;
+
+ for (k = 0; k < 10; k++)
+ {
+ float rot[4], thresh;
+ fmd->anim_bind[i].v2 = n2[k+2].index;
+ thresh = verts_to_quat(rot, mvert[fmd->anim_bind[i].v].co,
+ mvert[fmd->anim_bind[i].v1].co,
+ mvert[fmd->anim_bind[i].v2].co, false);
+ if (thresh > 0.1)
+ {
+ copy_qt_qt(fmd->anim_bind[i].quat, rot);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ //fallback if no suitable vert was found
+ float rot[4];
+ printf("BIND Fallback.../n");
+ fmd->anim_bind[i].v2 = n2[2].index;
+ verts_to_quat(rot, mvert[fmd->anim_bind[i].v].co,
+ mvert[fmd->anim_bind[i].v1].co,
+ mvert[fmd->anim_bind[i].v2].co, true);
+ copy_qt_qt(fmd->anim_bind[i].quat, rot);
+ }
+
mi->rigidbody->flag |= RBO_FLAG_KINEMATIC_BOUND;
}
@@ -4126,16 +4188,12 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
copy_v3_v3(fmd->anim_bind[i].offset, diff);
- if ((fmd->anim_bind[i].v1 == -1 || fmd->anim_bind[i].v2 == -1)) {
- //fallback if not enough verts around
- normal_short_to_float_v3(fmd->anim_bind[i].no, mvert[n.index].no);
- normalize_v3(fmd->anim_bind[i].no);
- }
- else if (totpoly > 0) {
+ if (totpoly > 0)
+ {
tri_to_quat_ex(fmd->anim_bind[i].quat,
- mvert[fmd->anim_bind[i].v].co,
- mvert[fmd->anim_bind[i].v1].co,
- mvert[fmd->anim_bind[i].v2].co, f_no);
+ mvert[fmd->anim_bind[i].v].co,
+ mvert[fmd->anim_bind[i].v1].co,
+ mvert[fmd->anim_bind[i].v2].co, f_no);
copy_v3_v3(fmd->anim_bind[i].no, f_no);
}
}
@@ -4168,7 +4226,8 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
}
//only let kinematic rbs do this, active ones are being taken care of by bullet
- if (mi && mi->rigidbody && (mi->rigidbody->flag & RBO_FLAG_KINEMATIC))
+ if (mi && mi->rigidbody && (mi->rigidbody->flag & RBO_FLAG_KINEMATIC) &&
+ (mi->rigidbody->flag & RBO_FLAG_KINEMATIC_BOUND))
{
//the 4 rot layers *should* be aligned, caller needs to ensure !
bool quats = quatX && quatY && quatZ && quatW;
@@ -4190,9 +4249,9 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
copy_v3_v3(co, mvert[v].co);
copy_v3_v3(off, fmd->anim_bind[i].offset);
- if (fmd->anim_mesh_rot)
+ //if (fmd->anim_mesh_rot)
{
- if (quats)
+ if (quats && fmd->anim_mesh_rot)
{
quat[0] = quatX[v];
quat[1] = quatY[v];
@@ -4201,14 +4260,20 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
}
else
{
- copy_v3_v3(vec, fmd->anim_bind[i].no);
- if (fmd->anim_bind[i].v1 == -1 || fmd->anim_bind[i].v2 == -1) {
- //fallback if not enough verts around;
- normal_short_to_float_v3(no, mvert[v].no);
- normalize_v3(no);
- rotation_between_vecs_to_quat(quat, vec, no);
+ //copy_v3_v3(vec, fmd->anim_bind[i].no);
+ //if (fmd->anim_bind[i].v1 == -1 || fmd->anim_bind[i].v2 == -1) {
+ if (fmd->anim_bind[i].poly == -1)
+ {
+ float rot[4], iquat[4];
+ verts_to_quat(rot, mvert[fmd->anim_bind[i].v].co,
+ mvert[fmd->anim_bind[i].v1].co,
+ mvert[fmd->anim_bind[i].v2].co, true);
+
+ invert_qt_qt(iquat, fmd->anim_bind[i].quat);
+ mul_qt_qtqt(quat, rot, iquat);
}
- else {
+ else
+ {
float rot[4], iquat[4], fno[3];
MPoly *mp = mpoly + fmd->anim_bind[i].poly;
MLoop *ml = mloop + mp->loopstart;
@@ -4232,14 +4297,19 @@ void BKE_read_animated_loc_rot(FractureModifierData *fmd, Object *ob, bool do_bi
copy_v3_v3(mi->rigidbody->pos, co);
- if (fmd->anim_mesh_rot)
{
- if (quats) {
+ if (quats && fmd->anim_mesh_rot) {
//if rotations are changed, re-bind the object to fix
mul_qt_qtqt(quat, ob_quat, quat);
}
mul_qt_qtqt(quat, anim_quat, quat);
+
+ //attempt to avoid sudden flipping of shards
+ if (dot_qtqt(mi->rigidbody->orn, quat) < 0.0) {
+ negate_v4(quat);
+ }
+
copy_qt_qt(mi->rigidbody->orn, quat);
}
More information about the Bf-blender-cvs
mailing list