# CCD IK is Jerky and sometimes spazzy

 08 August 2012 #1 bearsomg New Member portfolio Justin Prefer not to disclose, USA   Join Date: Aug 2012 Posts: 3 CCD IK is Jerky and sometimes spazzy Hello. I am writing an IK solver for a 3D rendering engine that I am designing. My solver works correctly for the most part, but sometimes it will make the animation look jerky or completely spazz out (this usually happens when the joints have to bend over each other more). This is my solver function: ``````D3DXMATRIX effTrans, destTrans, curBoneTrans; D3DXVECTOR3 effPos, destPos, curBonePos; D3DXVECTOR3 curBoneToEff, curBoneToDest; D3DXVECTOR3 cross, refAxis; D3DXVECTOR4 boneToEff, boneToDest; D3DXQUATERNION rot, origEffRot, tmpRotQ; D3DXMATRIX tmpRot, curBoneTransInv; destTrans = _destBone->getCombinedTrans(); destPos = D3DXVECTOR3(destTrans(3,0), destTrans(3,1), destTrans(3,2)); origEffRot = _effBone->getRot(); double dot, angle, distance2; float x; for (int i=0;i<_numBone;i++) { _boneList[i]->UpdateIK() } _effBone->UpdateIK(); for (int i=0;i<_iteration;i++) { for (int b=0;b<_numBone;b++) { //get end effector position effTrans = _effBone->getCombinedTrans(); effPos = D3DXVECTOR3(effTrans(3,0), effTrans(3,1), effTrans(3,2)); //get current bone position curBoneTrans = _boneList[b]->getCombinedTrans(); curBonePos = D3DXVECTOR3(curBoneTrans(3,0), curBoneTrans(3,1), curBoneTrans(3,2)); //create inverse of bone position D3DXMatrixInverse(&curBoneTransInv, NULL, &curBoneTrans); //create point-to-point vector from bone inverse matrix D3DXVec3Transform(&boneToEff, &effPos, &curBoneTransInv); D3DXVec3Transform(&boneToDest, &destPos, &curBoneTransInv); //transfer the vectors over curBoneToEff = (D3DXVECTOR3)boneToEff; curBoneToDest = (D3DXVECTOR3)boneToDest; //get distance between direction vectors distance2 = D3DXVec3Length(&(curBoneToDest-curBoneToEff)); distance2 *= distance2; if (distance2 < IK_MIN_DIST) { //stop if end effector is close enough i = _iteration; break; } D3DXVec3Normalize(&curBoneToEff, &curBoneToEff); D3DXVec3Normalize(&curBoneToDest, &curBoneToDest); //get dot product and angle between the 2 vectors dot = D3DXVec3Dot(&curBoneToDest, &curBoneToEff); if (dot > 1.0f) { continue; } angle = acos(dot); if (fabs(angle) < IK_MIN_ANGLE) { continue; } if (angle < -_angleConstraint) { angle = -_angleConstraint; } else if (angle > _angleConstraint) { angle = _angleConstraint; } //get the cross product (rotation axis) D3DXVec3Cross(&cross, &curBoneToEff, &curBoneToDest); //get length of axis distance2 = D3DXVec3Length(&cross); distance2 *= distance2; if (distance2 < IK_MIN_AXIS && i > 0) { //axis is too small (direction dest to target is too close) skip to next bone continue; } D3DXVec3Normalize(&cross, &cross); //build rotation from axis and angle D3DXQuaternionRotationAxis(&rot, &cross, (float)angle); //check is current bone is limited to x if (_boneList[b]->getIsLimitX()) { quatToEuler(rot, NULL, NULL, &x); if (x < -PI) { x = -PI; } if (-IK_MIN_ROT_SUM < x) { x = -IK_MIN_ROT_SUM; } D3DXMatrixRotationX(&tmpRot, x); D3DXQuaternionRotationMatrix(&rot, &tmpRot); } D3DXQuaternionNormalize(&rot, &rot); //apply rotation to bone //combine with previous rotation for multiple iterations tmpRotQ = _boneList[b]->getRot(); tmpRotQ *= rot; D3DXQuaternionNormalize(&rot, &rot); _boneList[b]->setRot(tmpRotQ); for (int j=b;j>=0;j--) { _boneList[j]->UpdateFromIK(); } _effBone->UpdateFromIK(); } } _effBone->setRot(origEffRot); _effBone->UpdateFromIK();`````` The UpdateIK() function uses this algorithm to update the bone's combined transform: ``````D3DXMatrixRotationQuaternion(&combTrans, &combRot); combTrans(3,0) = translate(3,0) + offset.x; combTrans(3,1) = translate(3,1) + offset.y; combTrans(3,2) = translate(3,2) + offset.z; if (_parent) combTrans *= _parent->getCombinedTrans();`````` Here is a video example of how the IK will be jerky or spazz out. Look at the left leg. The video is the model's bone structure. http://youtu.be/w56-Kv0akNo share quote
 09 September 2012 #2 ThE_JacO Cultist   portfolio CGConnect Member Raffaele Fragapane Performance Technology Supervisor Animal Logic Sydney, Australia   Join Date: Jul 2002 Posts: 10,955 Honestly, I haven't read the code. But looking at the video, and assuming you're using the pretty standard law of cosine 3 point IK for 2 joints chains, it simply looks like you have a preferred plane implementation with no directionality. Given two points, two lengths and a plane for them live on, there's always two solutions to law of cos or practically any other stateless (no temporal dimension) IK solver. The knee might go one way or the other basically. Make sure a direction is available for the IK to solve the knee consistently, and that direction doesn't become ambiguous (never aligned to the solver's plane). __________________ Come, Join the Cult http://www.cultofrig.com - Rigging from First Principles share quote
 09 September 2012 #3 CGTalk Moderation Expert   Join Date: Sep 2003 Posts: 1,066,473 Thread automatically closed This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum. __________________ CGTalk Policy/Legalities Note that as CGTalk Members, you agree to the terms and conditions of using this website. share quote

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts vB code is On Smilies are On [IMG] code is On HTML code is Off CGSociety Society of Digital Artists www.cgsociety.org Powered by vBulletinCopyright ©2000 - 2006, Jelsoft Enterprises Ltd.
Forum Jump
 Please select one User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home -------------------- Gallery     Latest Entries     Featured Videos     Featured 3D     Featured 2D     CG Awards     Expose12 Call For Entries (closed) Main     News         Press Releases and Media     General Discussion         Legacy Threads     Off Topic     Recruitment     Education Software     Autodesk Maya         Maya Dynamics         Maya Rendering         Maya Character Setup         Maya Programming     Autodesk Miscellaneous         Autodesk MotionBuilder         Autodesk Mudbox         Autodesk Softimage             XSI: Programming             ICE: Interactive Creative Environment     Autodesk 3ds max         3dsMax SDK and MaxScript         3dsMax Tutorials & Tips         3dsMax Resources         Plugins & Add-ons         Particle Flow     Maxon Cinema 4D         Cinema 4D Resources     The Foundry Modo         The Foundry Time Travel Challenge     Pixologic ZBrush     Photoshop / Painter     Side Effects Houdini     Blender     Lightwave 3D         LW Resources         LW Tutorials     Allegorithmic Substance         Substance Painter         Substance Designer     E-on Software Vue     Compositing Software         The Foundry Nuke         Adobe After Effects         Autodesk Effects and Compositing         Eyeon Software Digital Fusion Challenges     Modeling Challenge         Member Model Collection     Digital Matte Painting Challenge         DMP Mini Challenge Collection     Sketch Challenge         Member SKETCH Collection     FXWARS Challenge         Member FXGallery     Lighting Challenges WIP     Professional Feedback     WIP/Critique: 3D     WIP/Critique: 2D         Speedpaints & Sketchbooks     WIP/Critique: Animation     Collaborative Projects Techniques     Art Techniques and Theories     Digital Matte Painting         Digital Matte Painting Mini-Challenge     Modeling     Texturing and Surfacing     Character Rigging     Animation     Lighting and Shaders     Compositing and Editing     Anatomy and Figurative Art         SPOTLIGHT: Best of the Artistic Anatomy and Figurative Art Forum         Tutorials and Workshops         Personal Anatomy & Sketchbook Threads         References, Resources, and Supplies Technical     Virtual Reality     Game Engine     Graphics Programming     Technical and Hardware
Miscellaneous

All times are GMT. The time now is 01:04 AM.