[Bf-blender-cvs] [1d57779c20a] fracture_modifier: using quaternions and correction of quaternion sign flips for convert to keyframes now
Martin Felke
noreply at git.blender.org
Tue Aug 8 01:26:35 CEST 2017
Commit: 1d57779c20a59ba85394993ee759a1ee4cb0b401
Author: Martin Felke
Date: Tue Aug 8 01:26:25 2017 +0200
Branches: fracture_modifier
https://developer.blender.org/rB1d57779c20a59ba85394993ee759a1ee4cb0b401
using quaternions and correction of quaternion sign flips for convert to keyframes now
===================================================================
M source/blender/editors/object/object_modifier.c
===================================================================
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 0fbc37b0ac0..9fc814e6472 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -3102,6 +3102,29 @@ MINLINE void div_v3_v3(float r[3], const float a[3], const float b[3])
r[2] = a[2];
}
+MINLINE void div_v4_v4(float r[4], const float a[4], const float b[4])
+{
+ if (b[0] != 0)
+ r[0] = a[0] / b[0];
+ else
+ r[0] = a[0];
+
+ if (b[1] != 0)
+ r[1] = a[1] / b[1];
+ else
+ r[1] = a[1];
+
+ if (b[2] != 0)
+ r[2] = a[2] / b[2];
+ else
+ r[2] = a[2];
+
+ if (b[3] != 0)
+ r[3] = a[3] / b[3];
+ else
+ r[3] = a[3];
+}
+
MINLINE void compare_v3_fl(bool r[3], const float a[3], const float b)
{
r[0] = fabsf(1.0f - a[0]) > b;
@@ -3109,6 +3132,14 @@ MINLINE void compare_v3_fl(bool r[3], const float a[3], const float b)
r[2] = fabsf(1.0f - a[2]) > b;
}
+MINLINE void compare_v4_fl(bool r[4], const float a[4], const float b)
+{
+ r[0] = fabsf(1.0f - a[0]) > b;
+ r[1] = fabsf(1.0f - a[1]) > b;
+ r[2] = fabsf(1.0f - a[2]) > b;
+ r[3] = fabsf(1.0f - a[3]) > b;
+}
+
static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi, Group* gr, Object* ob, Scene* scene,
int start, int end, int count, Object* parent, bool is_baked,
PTCacheID* pid, PointCache *cache, float obloc[3], float diff[3], int *j, Base **base,
@@ -3120,8 +3151,8 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
float cent[3];
float prevloc[3] = {0, 0, 0};
float prevploc[3] = {0, 0, 0};
- float prevrot[3] = {0, 0, 0};
- float prevprot[3] = {0, 0, 0};
+ float prevrot[4] = {0, 0, 0, 0};
+ float prevprot[4] = {0, 0, 0, 0};
bool adaptive = threshold > 0;
char *name = BLI_strdupcat(ob->id.name + 2, "_key");
@@ -3136,6 +3167,9 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
ob_new = BKE_object_add(G.main, scene, OB_MESH, name);
*base = scene->basact;
+ //this and keyframing quats hopefully solves the sudden rotation / gimbal lock (?) issue
+ ob_new->rotmode = ROT_MODE_QUAT;
+
//MEM_freeN((void*)name);
ED_object_parent_set(NULL, G.main, scene, ob_new, parent, PAR_OBJECT, false, false, NULL);
@@ -3187,7 +3221,7 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
bool dostep = adaptive ? (((i + start) % step == 0) || i == start || i == end) : true;
float size[3] = {1, 1, 1};
bool locset[3] = {true, true, true};
- bool rotset[3] = {true, true, true};
+ bool rotset[4] = {true, true, true, true};
if (dostep) {
//if adaptive and step is on same frame, prefer adaptive vector handle
@@ -3209,6 +3243,7 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
rotset[0] = false;
rotset[1] = false;
rotset[2] = false;
+ rotset[3] = false;
}
copy_v3_v3(size, ob->size);
@@ -3239,9 +3274,22 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
rot[2] = mi->rots[x*4+2];
rot[3] = mi->rots[x*4+3];
+ if (i >= start + 1)
+ {
+ //taken from rigidbody.py
+ // make quaternion compatible with the previous one
+ //if q1.dot(q2) < 0.0:
+ // obj.rotation_quaternion = -q2
+ //else:
+ // obj.rotation_quaternion = q2
+ if (dot_qtqt(prevrot, rot) < 0.0) {
+ negate_v4(rot);
+ }
+ }
+
if (adaptive)
{
- float diffloc[3], diffploc[3], diffrot[3], diffprot[3], difflq[3], diffrq[3];
+ float diffloc[3], diffploc[3], diffrot[4], diffprot[4], difflq[3], diffrq[4];
if (i >= start + 2)
{
sub_v3_v3v3(diffploc, prevploc, prevloc);
@@ -3249,20 +3297,20 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
div_v3_v3(difflq, diffploc, diffloc);
compare_v3_fl(locset, difflq, threshold);
- sub_v3_v3v3(diffprot, prevprot, prevrot);
- sub_v3_v3v3(diffrot, prevrot, rot);
- div_v3_v3(diffrq, diffprot, diffrot);
- compare_v3_fl(rotset, diffrq, threshold);
+ sub_v4_v4v4(diffprot, prevprot, prevrot);
+ sub_v4_v4v4(diffrot, prevrot, rot);
+ div_v4_v4(diffrq, diffprot, diffrot);
+ compare_v4_fl(rotset, diffrq, threshold);
}
if (i >= start + 1)
{
copy_v3_v3(prevploc, prevloc);
- copy_v3_v3(prevprot, prevrot);
+ copy_v4_v4(prevprot, prevrot);
}
copy_v3_v3(prevloc, loc);
- copy_v3_v3(prevrot, rot);
+ copy_v4_v4(prevrot, rot);
}
if (dostep)
@@ -3274,6 +3322,7 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
rotset[0] = true;
rotset[1] = true;
rotset[2] = true;
+ rotset[3] = true;
}
}
}
@@ -3294,7 +3343,7 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
loc_quat_size_to_mat4(mat, loc, rot, size);
- if (locset[0] || locset[1] || locset[2] || rotset[0] || rotset[1] || rotset[2]) {
+ if (locset[0] || locset[1] || locset[2] || rotset[0] || rotset[1] || rotset[2] || rotset[3]) {
BKE_scene_frame_set(scene, (double)i);
}
@@ -3302,6 +3351,7 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
copy_v3_v3(ob_new->loc, loc);
copy_qt_qt(ob_new->quat, rot);
+
quat_to_compatible_eul(ob_new->rot, ob_new->rot, rot);
copy_v3_v3(ob_new->size, size);
}
@@ -3316,13 +3366,16 @@ static Object* do_convert_meshIsland(FractureModifierData* fmd, MeshIsland *mi,
insert_keyframe(NULL, (ID*)ob_new, NULL, "Location", "location", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
if (rotset[0])
- insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
+ insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_quaternion", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
if (rotset[1])
- insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
+ insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_quaternion", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
if (rotset[2])
- insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_euler", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+ insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_quaternion", 2, i, BEZT_KEYTYPE_KEYFRAME, flag);
+
+ if (rotset[3])
+ insert_keyframe(NULL, (ID*)ob_new, NULL, "Rotation", "rotation_quaternion", 3, i, BEZT_KEYTYPE_KEYFRAME, flag);
//insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 0, i, BEZT_KEYTYPE_KEYFRAME, flag);
//insert_keyframe(NULL, (ID*)ob_new, NULL, "Scale", "scale", 1, i, BEZT_KEYTYPE_KEYFRAME, flag);
More information about the Bf-blender-cvs
mailing list