IK rotation limits fixes:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 28 Aug 2005 13:06:41 +0000 (13:06 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 28 Aug 2005 13:06:41 +0000 (13:06 +0000)
- Z-axis rotation limits were not working, was using wrong flag.
- Don't allow min limit to go over max, or vice versa.
- Fix for jacobian getting overwritten with IK clamping.

intern/iksolver/intern/IK_QJacobian.cpp
intern/iksolver/intern/IK_QJacobian.h
source/blender/src/buttons_editing.c

index cfa764454d494e177be39afdd620818718f81aef..3eb79c89e4deb62431d57b936ea7407b405f6bf1 100644 (file)
@@ -72,6 +72,8 @@ void IK_QJacobian::ArmMatrices(int dof, int task_size, int tasks)
        if (task_size >= dof) {
                m_transpose = false;
 
+               m_jacobian_tmp.newsize(task_size, dof);
+
                m_svd_u.newsize(task_size, dof);
                m_svd_v.newsize(dof, dof);
                m_svd_w.newsize(dof);
@@ -87,7 +89,7 @@ void IK_QJacobian::ArmMatrices(int dof, int task_size, int tasks)
                // as the original, and often allows using smaller matrices.
                m_transpose = true;
 
-               m_jacobian_t.newsize(dof, task_size);
+               m_jacobian_tmp.newsize(dof, task_size);
 
                m_svd_u.newsize(task_size, task_size);
                m_svd_v.newsize(dof, task_size);
@@ -106,8 +108,6 @@ void IK_QJacobian::SetBetas(int id, int, const MT_Vector3& v)
        m_beta[id] = v.x();
        m_beta[id+1] = v.y();
        m_beta[id+2] = v.z();
-
-       //printf("#: %f %f %f\n", v.x(), v.y(), v.z());
 }
 
 void IK_QJacobian::SetDerivatives(int id, int dof_id, const MT_Vector3& v)
@@ -115,8 +115,6 @@ void IK_QJacobian::SetDerivatives(int id, int dof_id, const MT_Vector3& v)
        m_jacobian[id][dof_id] = v.x()*m_weight_sqrt[dof_id];
        m_jacobian[id+1][dof_id] = v.y()*m_weight_sqrt[dof_id];
        m_jacobian[id+2][dof_id] = v.z()*m_weight_sqrt[dof_id];
-
-       //printf("%d: %f %f %f\n", dof_id, v.x(), v.y(), v.z());
 }
 
 void IK_QJacobian::Invert()
@@ -124,13 +122,14 @@ void IK_QJacobian::Invert()
        if (m_transpose) {
                // SVD will decompose Jt into V*W*Ut with U,V orthogonal and W diagonal,
                // so J = U*W*Vt and Jinv = V*Winv*Ut
-               TNT::transpose(m_jacobian, m_jacobian_t);
-               TNT::SVD(m_jacobian_t, m_svd_v, m_svd_w, m_svd_u, m_work1, m_work2);
+               TNT::transpose(m_jacobian, m_jacobian_tmp);
+               TNT::SVD(m_jacobian_tmp, m_svd_v, m_svd_w, m_svd_u, m_work1, m_work2);
        }
        else {
                // SVD will decompose J into U*W*Vt with U,V orthogonal and W diagonal,
                // so Jinv = V*Winv*Ut
-               TNT::SVD(m_jacobian, m_svd_u, m_svd_w, m_svd_v, m_work1, m_work2);
+               m_jacobian_tmp = m_jacobian;
+               TNT::SVD(m_jacobian_tmp, m_svd_u, m_svd_w, m_svd_v, m_work1, m_work2);
        }
 
        if (m_sdls)
index a16d7a7a941ad7210f83c1d6fb32ec30e07f4cc7..b80db1d8f53aeef0a5bc534dd83c74dd5c68e1ad 100644 (file)
@@ -79,7 +79,7 @@ private:
        bool m_transpose;
 
        // the jacobian matrix and it's null space projector
-       TMatrix m_jacobian, m_jacobian_t;
+       TMatrix m_jacobian, m_jacobian_tmp;
        TMatrix m_null;
 
        /// the vector of intermediate betas
index 0ffe38adf9c69f5675eea7cf4f016a640ed007c3..9b9b4f82e52b26d09e706293b75ff740062e4473 100644 (file)
@@ -2342,8 +2342,8 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
                                uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff X:", bx-10, by-80, 114, 19, &pchan->stiffness[0], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for X axis");
                                uiDefButBitS(block, TOG, BONE_IK_XLIMIT, B_ARM_RECALCDATA, "Limit X", bx-10,by-100,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over X axis");
                                if ((pchan->ikflag & BONE_IK_XLIMIT)) {
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min X:", bx-10, by-120, 114, 19, &pchan->limitmin[0], -180.0f, 180.0f, 10.0f, 0.0f, "Minimum X limit");
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max X:", bx-10, by-140, 114, 19, &pchan->limitmax[0], -180.0f, 180.0f, 10.0f, 0.0f, "Maximum X limit");
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min X:", bx-10, by-120, 114, 19, &pchan->limitmin[0], -180.0f, pchan->limitmax[0], 10.0f, 0.0f, "Minimum X limit");
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max X:", bx-10, by-140, 114, 19, &pchan->limitmax[0], pchan->limitmin[0], 180.0f, 10.0f, 0.0f, "Maximum X limit");
                                        zerolimit = 0;
                                }
                                zerodof = 0;
@@ -2356,8 +2356,8 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
                                uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Y:", bx+104, by-80, 114, 19, &pchan->stiffness[1], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Y axis");
                                uiDefButBitS(block, TOG, BONE_IK_YLIMIT, B_ARM_RECALCDATA, "Limit Y", bx+104,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Y axis");
                                if ((pchan->ikflag & BONE_IK_YLIMIT)) {
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Y:", bx+104, by-120, 113, 19, &pchan->limitmin[1], -180.0f, 180.0f, 10.0f, 0.0f, "Minimum Y limit");
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Y:", bx+104, by-140, 113, 19, &pchan->limitmax[1], -180.0f, 180.0f, 10.0f, 0.0f, "Maximum Y limit");
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Y:", bx+104, by-120, 113, 19, &pchan->limitmin[1], -180.0f, pchan->limitmax[1], 10.0f, 0.0f, "Minimum Y limit");
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Y:", bx+104, by-140, 113, 19, &pchan->limitmax[1], pchan->limitmax[1], 180.0f, 10.0f, 0.0f, "Maximum Y limit");
                                        zerolimit = 0;
                                }
                                zerodof = 0;
@@ -2368,10 +2368,10 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
                        uiDefButBitS(block, TOG, BONE_IK_NO_ZDOF, B_ARM_RECALCDATA, "Lock Z Rot", bx+217,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Z DoF for IK");
                        if ((pchan->ikflag & BONE_IK_NO_ZDOF)==0) {
                                uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Z:", bx+217, by-80, 114, 19, &pchan->stiffness[2], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Z axis");
-                               uiDefButBitS(block, TOG, BONE_IK_ZLIMIT, B_ARM_RECALCDATA, "Limit Z", bx+217,by-100,113,19, &pchan->flag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Z axis");
-                               if ((pchan->flag & BONE_IK_ZLIMIT)) {
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Z:", bx+217, by-120, 113, 19, &pchan->limitmin[2], -180.0f, 180.0f, 10.0f, 0.0f, "Minimum Z limit");
-                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Z:", bx+217, by-140, 113, 19, &pchan->limitmax[2], -180.0f, 180.0f, 10.0f, 0.0f, "Maximum Z limit");
+                               uiDefButBitS(block, TOG, BONE_IK_ZLIMIT, B_ARM_RECALCDATA, "Limit Z", bx+217,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Z axis");
+                               if ((pchan->ikflag & BONE_IK_ZLIMIT)) {
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Z:", bx+217, by-120, 113, 19, &pchan->limitmin[2], -180.0f, pchan->limitmax[2], 10.0f, 0.0f, "Minimum Z limit");
+                                       uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Z:", bx+217, by-140, 113, 19, &pchan->limitmax[2], pchan->limitmin[2], 180.0f, 10.0f, 0.0f, "Maximum Z limit");
                                        zerolimit = 0;
                                }
                                zerodof = 0;