Notifications
Clear all

[Closed] FK to IK…calculating the IK twist?

IK to FK…calculating the IK twist?
Hey guys, thought I’d try posting this where all the math geniuses hang out. I’m still on the new side of figuring all this character setup stuff out…but I think I’m pretty close to being on my way. I just wanted to run this by people and see if there’s a better/more efficient way to go about it.

 Snapping FK to IK bones seems rather straightforward an easy. No problems there.
 
 My problem occurs in the other direction, so when snapping back from FK bones to IK bones I wasn't sure if there  was an easy (Maxscript) way to figure out the IK twist value if you're  not using Pole Vectors (IK Solver Plane Targets) to control the twisting  of a leg in an animation.  This is the setup I'm currently thinking  about using...
 
 I created an IK chain an used the twist to rotate it 45 degrees.
 Point01 has a lookat (aim) constraint with Bone01 as the upnode.
 Point02 has a lookat (aim) constraint with Bone03 as the upnode.
[img] http://www.themichaelsmith.com/TwistCalculation.jpg [/img]
 
 As you can see Point02 has the same x rotation value as the twist.
 
 A couple issues I have with this method....
 I'm curious if there's any way to calculate the twist value without  the addition of the two lookat (aim) constrained nodes by some cool  vector math (magic) solution based on the bone positions or something.   Basically I looking for a "cleaner" way so I don't have more point  helpers than I need lying around.
 
 I can't seem to get the gimbal coordsys x rotation value of the lookat  (aim) constrained rotation of the Point02 node.  It shows up in "Rotate  Transform Type-In" window but I can't find it via MaxScript.  I can add  yet another point helper parented to Point01 with a regular Euler  controller and align it to Point02 to get the x rotation value....but it  seems like I shouldn't have to do that.
 
 Any suggestions?
3 Replies

Doh, I’m sorry guys, I got the title of this post exactly backwards. I don’t have a problem matching FK to IK, that’s easy. It’s when I have to go the other way that I have issues. (IK to FK). Sorry about that.

 elT

You can link a helper to the first bone of the FK chain that represents what would be a swivel angle target on the IK chain. Then, if you have the swivel angle target on the IK chain, you can simply position it at that helper linked to the FK chain.

You could also calculate the angle between the FK and IK knee since both hips should be in the same place.

You can also gradually increase or deacrease the swivel angle while testing the distance between the knees and keep doing it until it matches.

Or simply, you can go here and see how Paul does his FK/IK:
http://paulneale.com/tutorials/IKFKarm/IKFKarmSetup.html

Or use this: http://joleanes.com/scripts_plugins/IKFKSolver.php
An awesome free FK/IK solver plug in by Felix Joleanes that has everything you need when it comes to arms and legs.

Cheers.

K…I figured this out a while ago and haven’t gotten around to posting it till now. I still think there’s GOT to be cleaner way to figure out if your twist value is positive of negative depending on where the end bone is relevant to the start bone. So let me know if you have suggestions.

  All you have to do to get this script to work is create a 4 bone chain like I had in the picture.  Then make a copy of it....so you have two bone chains (8 bones all together), like an FK/IK bone blend setup.  Create an IK chain between Bone02 and Bone 04.  That'll be the IK bone chain.  The script uses the default name of the bones and IK chain.
 
 Rotate the FK bones around, then uses this script to align the IK chain bones to the FK bones....  (Make sure you only rotate Bone03 on the one axis) 

   /*
   from CGTalks sticky thread:
   Geometrical calculations : points, lines, planes : intersections, distances, angles
   
    http://forums.cgsociety.org/showthread.php?f=98&t=295257 
   
   Point-Line Distance : the distance between the line AB and the point C:
   fn pointLineDist2 pA pB pC = (
   	local vAB=pB-pA
   	local vAC=pC-pA
   	(length (cross vAB vAC))/(length vAB)
   	)
   	
   and
   
   Point-Line Projection : find the point on the line AB which is the projection of the point C:
   fn pointLineProj pA pB pC = (
   	local vAB=pB-pA
   	local vAC=pC-pA
   	local d=dot (normalize vAB) (normalize vAC)
   	(pA+(vAB*(d*(length vAC/length vAB))))
   	)	
   */
   
   fn pointLineDist2 IKStart IKEnd IKBend =
   (
   	local vAB=IKStart-IKEnd
   	local vAC=IKBend-IKEnd
   	(length (cross vAB vAC))/(length vAB)
   
   )
   
   fn pointLineProj IKStart IKEnd IKBend = 
   (
   	local vAB=IKEnd-IKStart
   	local vAC=IKBend-IKStart
   	local d=dot (normalize vAB) (normalize vAC)
   	(IKStart+(vAB*(d*(length vAC/length vAB))))
   )
   
   --match the IK Goal position with the FK end bone and set the IK Twist to 0
   $'IK Chain01'.pos = $Bone08.pos
   $'IK Chain01'.transform.controller.swivelAngle = 0
   
   --You now have a triangle between the two different knee positions and a point on the line that runs through
   --the start and end bones of both the bone systems. You can define the lengths of all three sides of that
   --triangle with the pointLineDist2 function.  ( I think the lengths of both the IK and FK bend bones will 
   --always be equal) 
   
   --Define the triangle side lengths of all three sides using the function
   IKDist = pointLineDist2  $Bone02.pos $Bone04.pos $Bone03.pos
   FKDist = pointLineDist2 $Bone06.pos $Bone08.pos  $Bone07.pos
   --Define the length of the side opposite the angle I need for the twist
   --i.e. the distance between the two bend bones
   B2BDist = distance $Bone07.pos $Bone03.pos
   
   --Know that I know the lengths of all three sides I can use the "Cosine Rule" to calculate the twist angle
   TwistValue = acos(-(B2BDist^2 - FKDist^2 - IKDist^2)/(2*FKDist*IKDist))
   
   --But the twist value from this method is always positive.  Depending on which quadrant the end of the chain is
   --relevant to the start bone of the chain.  Sometimes the twist will be a negative value.
   --I used the following vector math to figure this out....If there's a "cleaner" way to do it let me know.
   
   PointA = pointLineProj $Bone02.pos $Bone04.pos $Bone03.pos
   theVector1 = $Bone03.pos - PointA
   theVector2 =PointA - $Bone07.pos
   PosOrNeg = cross theVector1 theVector2
   
   PosOrNeg2 = $Bone06.pos - $Bone08.pos
   j = PosOrNeg[3]*PosOrNeg2[3]
   
   
   if j >0 then $'IK Chain01'.transform.controller.swivelAngle = TwistValue
   if j < 0 then $'IK Chain01'.transform.controller.swivelAngle = -TwistValue
   
   
    

VIOLA…no extra point helpers or anything needed…just a FK and an IK bone chain and the twist angle is calculated for the IK bone chain so that it matches the FK pose.

Special thanks to the stick thread I found here on CGTalk
http://forums.cgsociety.org/showthread.php?f=98&t=295257
It’s been a loooooooong time since I’ve used the Trigonometry part of my brain.