PDA

View Full Version : IK-FK switching with auto snap?


e-moo
05-18-2009, 12:04 PM
Hi all,
does anyone know how to achieve IK/FK switching with auto snap?
What i am trying to say is that I want to switch from IK to FK (and vice versa) so that the joints/controlls hold the same position after switching.

Say I animated a characters hand to reach a certain point using IK, and then switch to FK so that I can animate some arc movement with the hand using FK. Now when i am blending from IK to FK, i want the hand to hold its position (rather than blending the hand to the FK controls, i want the FK to reach the position to hold the same pose...). Sorry if i am failing to make my point clear?

skunk184
05-18-2009, 01:05 PM
i am just finishing up a rig with IKFK snapping and lots of other bells and whistles. the way i did it was to hack into the right click menu so i could execute a scripts without running a scriptjob.

I use a 3 joint setup, so for example I have and FK arm, an IK arm and a skin arm which is constrained between the FK and IK

FK to IK is pretty easy ...... just need to query the rotations on the IK arm ..
example:
float $shoulderRot[] = `xform -q -ws -ro "ik_shoulderJoint" ` ;
rotate -ws -a $shoulderRot[0] $shoulderRot[1] $shoulderRot[2] "fk_shoulderJoint" ;

for IK to FK i just used locators aligned to my ik controllers and parentConstain (maintaining offset )them to the fk joints in the bindPose . then you just need to query the pos and rotation of the locators.
example:
float $wristPos[] = `xform -q -ws -rp "fk_wrist_Loc" ` ;
move -ws -a $wristPos[0] $wristPos[1] $wristPos[2] "ik_wrist_CTRL" ;

float $wristRot[] = `xform -q -ws -ro "fk_wrist_Loc" ` ;
rotate -ws -a $wristRot[0] $wristRot[1] $wristRot[2] "ik_wrist_CTRL" ;

I hope that can get you started
cheers

Craig

doffer
05-18-2009, 01:27 PM
This guys has a pretty sweet FK/IK matching tutorial:
http://timoberlander.com/Pages/Tutorials/Tutorials_Page.htm

strarup
05-18-2009, 01:56 PM
hi,


a 3 joint thingie example... shoulder, elbow and wrist...
fk joints called... --> fk_shoulder, fk_elbow and fk_wrist...
ik joints called... --> ik_shoulder, ik_elbow and ik_wrist
and then there is the ikHandle called... --> daIKHandle

just change the names... to the names of your setup... :)

from fk to ik...

proc switchToIK()
{
delete `parentConstraint fk_wrist daIKHandle`;
}
switchToIK;


from ik to fk...

proc switchToFK()
{
delete `orientConstraint ik_shoulder fk_shoulder`;
delete `orientConstraint ik_elbow fk_elbow`;
}
switchToFK;


more generic... switching from fk to ik with parameters...
switchToDaIK("NameOfYourFK_wrist", "NameOfYourIK_HandleOrController");

proc switchToDaIK(string $daFk_wrist, string $daIkController)
{
delete `parentConstraint $daFk_wrist $daIkController`;
}
//switchToDaIK(arg1, arg2);
switchToDaIK("fk_wrist", "daIKHandle");


more generic... switching from ik to fk with parameters...
switchToDaFK("NameOfYourIK_shoulder", "NameOfYourIK_elbow", "NameOfYourFK_shoulder", "NameOFYourFK_elbow");

proc switchToDaFK(string $daIk_shoulder, string $daIk_elbow, string $daFk_shoulder, string $daFk_elbow)
{
delete `orientConstraint $daIk_shoulder $daFk_shoulder`;
delete `orientConstraint $daIk_elbow $daFk_elbow`;
}
//switchToDaFK(arg1, arg2, arg3, arg4);
switchToDaFK("ik_shoulder", "ik_elbow", "fk_shoulder", "fk_elbow");


kind regards

strarup

skunk184
05-18-2009, 02:32 PM
Alex ...

what happens to your ik elbow or knee poleVector contraint when you match from IK to FK ?

Im not doubting your skills as your scripting skills are way better than mine but wont your elbow constraint ctrl object just stay in its old position?

it doesnt work on my rig but that maybe because i have a floating/broken hierarchy so i could implement seemless space switching.

anyway just curious

cheers

Craig

strarup
05-18-2009, 11:41 PM
Hi Craig,


what happens to your ik elbow or knee poleVector contraint when you match from IK to FK ?


eh... should be the same as if you moved the IK handle manually to the position of the wrist except for the rotation of the wrist...
you can also use pointConstraint instead of parentConstraint... which will say nothing at the moment happens to it... :D
what happens depends on how you have setup the polevector... but if you move the IK_handle manually to the position of the fk_wrist...
or you move it by using pointConstraint or parentConstraint it will be the same... (except parentConstraint also rotates)
I just did this code quick with 2 joint chains with 3 joint in either of them... and with no polevector thingie...
so didn't test for that...
but for an example to get that to work... see a bit further down...

Im not doubting your skills as your scripting skills are way better than mine but wont your elbow constraint ctrl object just stay in its old position?



eh... jup... but didn't take that into consideration... when I just quick made it and tested it on a simple quick 2 times 3 bones setup... :)
will try use packageMan (http://www.rigging101.com/free/rigs/pm.zip) from Javier Solsona (a.k.a. Goosh) site rigging101 (http://www.rigging101.com/freestuff.htm) as an example...


and using packageman's right arm... to show an example of the script and adobt/modify it to work with the rig... also with getting the polevector/IK elbow controller to follow along...
if you download packageMan and do the following stuff... then you can try to see how the bit's of the scripts work... and maybe where you need to change some stuff to make it work on your rig... :)


//turn on packageman's IKFK Switch concroller
setAttr "PM_Controllers.IKFKSwitch" 1;
//turn on packageman's rightarm controller's...
setAttr "PM_Controllers.ArmR" 1;

in this case for the script in the former post... this are the values for packageman...
fk_shoulder = FKShoulderCtrl_R //joint name = CFKjShoulder_R
fk_elbow = FKElbowCtrl_R //joint name = CFKjElbow_R
fk_wrist = FKWristCtrl_R //joint name = CFKjWrist_R

ik_shoulder = IKjShoulder_R
ik_elbow = IKjElbow_R
ik_wrist = IKjWrist_R
ik_Handle = IKWristCtrl_R

//ik on
setAttr "switchWristCtrl_R.FK_IK" 10;
//fk on
setAttr "switchWristCtrl_R.FK_IK" 0;

example 1 switching from IK to FK....

//first turn on IK
setAttr "switchWristCtrl_R.FK_IK" 10;
//move and rotate ik handle...
setAttr "IKWristCtrl_R.tx" 4.801;
setAttr "IKWristCtrl_R.ty" 4.995;
setAttr "IKWristCtrl_R.tz" 2.532;
setAttr "IKWristCtrl_R.rx" -61.078;
setAttr "IKWristCtrl_R.ry" 11.27;
setAttr "IKWristCtrl_R.rz" 77.952 ;

//turn back on fk... and use the script...
setAttr "switchWristCtrl_R.FK_IK" 0;


//added the wrist aswell...
proc switchToDaFK(string $daIk_shoulder, string $daIk_elbow, string $daIk_wrist, string $daFk_shoulder, string $daFk_elbow, string $daFk_wrist)
{
delete `orientConstraint $daIk_shoulder $daFk_shoulder`;
delete `orientConstraint $daIk_elbow $daFk_elbow`;
delete `orientConstraint $daIk_wrist $daFk_wrist`;
}
//switchToDaFK(arg1, arg2, arg3, arg4, arg5, arg 6);
switchToDaFK("IKjShoulder_R", "IKjElbow_R", "IKjWrist_R", "CFKjShoulder_R", "CFKjElbow_R", "CFKjWrist_R");


unfortunately the controller's doesn't follow... but all the FK joint's are at the position matching the IK positions...
to get it to work with the fk controllers on Packageman... we need to skip x and y on the elbow...

proc switchToDaFK(string $daIk_shoulder, string $daIk_elbow, string $daIk_wrist, string $daFk_shoulder, string $daFk_elbow, string $daFk_wrist)
{
delete `orientConstraint $daIk_shoulder $daFk_shoulder`;
delete `orientConstraint -sk x -sk y $daIk_elbow $daFk_elbow`;
delete `orientConstraint $daIk_wrist $daFk_wrist`;
}
//switchToDaFK(arg1, arg2, arg3, arg4, arg5, arg6);
switchToDaFK("IKjShoulder_R", "IKjElbow_R", "IKjWrist_R", "FKShoulderCtrl_R", "FKElbowCtrl_R", "FKWristCtrl_R");

since the fk elbow controller only have a rotateZ attribute "activated"/availible...

//--- end of the fk matching/switching stuff...


set back to zero to prepare for the IK matching/switching thingie....
setAttr "switchWristCtrl_R.FK_IK" 10;
setAttr "IKWristCtrl_R.translateX" 0;
setAttr "IKWristCtrl_R.translateY" 0;
setAttr "IKWristCtrl_R.translateZ" 0;
setAttr "IKWristCtrl_R.rotateX" 0;
setAttr "IKWristCtrl_R.rotateY" 0;
setAttr "IKWristCtrl_R.rotateZ" 0;

setAttr "switchWristCtrl_R.FK_IK" 0;
setAttr "FKWristCtrl_R.rotateX" 0;
setAttr "FKShoulderCtrl_R.rotateX" 0;
setAttr "FKWristCtrl_R.rotateY" 0;
setAttr "FKShoulderCtrl_R.rotateY" 0;
setAttr "FKWristCtrl_R.rotateZ" 0;
setAttr "FKShoulderCtrl_R.rotateZ" 0;
setAttr "FKElbowCtrl_R.rotateZ" 0;


start... example 2 switching from FK to IK....
//rotate fk a bit...
setAttr "FKShoulderCtrl_R.rx" -16.672 ;
setAttr "FKShoulderCtrl_R.ry" -0.688 ;
setAttr "FKShoulderCtrl_R.rz" 33.147 ;
setAttr "FKElbowCtrl_R.rz" 46.287;
setAttr "FKWristCtrl_R.rx" -42;


//turn back on ik... and use the script...
setAttr "switchWristCtrl_R.FK_IK" 10;


proc switchToDaIK(string $daFk_wrist, string $daIkController)
{
delete `parentConstraint $daFk_wrist $daIkController`;
}
//switchToDaIK(arg1, arg2);
switchToDaIK("FKWristCtrl_R", "IKWristCtrl_R");


there is a slightly difference in the position of the fk_elbow and the ik_elbow...
but that difference would have been there if you had moved the ik manually aswell...
again... depends on how you have setup the polevector... and other stuff of the rig...
this was just an example how to do it without that much code... and the polevector wasn't considered there...

to get it to work with packageman's Ik_elbow/polevector... need to change a bit...
will use a bit from the example doffer posted a link to... by using a locator...

and setting up an locator at the IkElbow control of the rightarm of packageman...
and parentConstraint that to the fk_elbow...
calling the locator... daFKPoleLoc_R...

proc setupFkPoleVecThingieBob(string $daLoc, string $daFkElbow, string $daIkElbowControl)
{
string $daFkPoleLoc[] = `spaceLocator -n $daLoc`;
delete `parentConstraint $daIkElbowControl $daFkPoleLoc[0]`;
parentConstraint -mo CFKjElbow_R $daFkPoleLoc[0];
setAttr ($daFkPoleLoc[0]+".template") 1;
//setAttr ($daFkPoleLoc[0]+".visibilty") 0;
}
setupFkPoleVecThingieBob("daFKPoleLoc_R","CFKjElbow_R", "IKElbowCtrl_R");


and then add 2 more values to the switchToDaIK procedure... the Fk elbow/pole thingie locator... and the ik elbow/polevector control...

proc switchToDaIK(string $daFk_wrist, string $daIkController, string $daFkPoleLoc, string $daIkElbowControl)
{
delete `parentConstraint $daFk_wrist $daIkController`;
delete `pointConstraint $daFkPoleLoc $daIkElbowControl`;
}
//switchToDaIK(arg1, arg2, arg3 arg4);
switchToDaIK("FKWristCtrl_R", "IKWristCtrl_R", "daFKPoleLoc_R", "IKElbowCtrl_R");

and now the IK match that with the FK also with the IK elbow... :-)

however this work for the packageman setup/rig... might be different for other rig's... but see the script bits as some ingredients for cooking a meal... it might need a bit salt & pepper here or there... but some of the ingredient for the meal is there... :D

e.g. had to change a bit in the switchToFk on the elbow when using the fk controllers... and skip x and y in the orientConstraint because the controller only rotates in Z...
and will spit out error's when trying to orientConstraint to x and y on the FK_elbow controller...

and let's say you e.g. have a polevector where the setup calculates the placement based on how the Ik handle moves... or moves together with the ik handle... then the above example wouldn't work but the first would... it all depends on how stuff is setup...

I don't know how your setup or hierarchy is build up... but hope some of this has been helpful anyway...
maybe you have to also skip some of the axes... to make it work on your rig... :)

kind regards

Alex

skunk184
05-19-2009, 02:57 AM
Hi Alex,

Thanks for the post which is a great post for all im sure. I should of been clearer with my post .I already have IKFK snapping working on my rig but was wondering if id gone about it the wrong way as my snapping script ended up at with more than 600 lines (laughs at myself) and you did it with just a couple lines. The majority of my script is getting objects from my scene to be useable in my scripts (im sure there must be a much more economic way to do it though)and there are only a few lines that actually do the snap .


this is small example of my very long winded object catching ,sorry its not in a little code window but I dont how to do one of them.
{
string $RfkShoulderJ,$LfkShoulderJ ,$RfkCtrlShoulder ,$LfkCtrlShoulder ;

string $joints[] = `ls -typ "joint"`;
for ($i = 0; $i < size($joints); $i++)
{
if (`match "fk_j_R_shoulder" $joints[$i]` == "fk_j_R_shoulder" )
{
$RfkShoulderJ = $joints[$i];
}
else if (`match "fk_j_L_shoulder" $joints[$i]` == "fk_j_L_shoulder" )
{
$LfkShoulderJ = $joints[$i];
}
}

string $CTRLcurves[];
string $curveShapes[] = `ls -type "nurbsCurve"`;
for ($i=0; $i<size($curveShapes);$i++)
{
string $hold[] = `listRelatives -parent $curveShapes[$i]`;
$CTRLcurves[$i] = $hold[0];
}
for ($i=0; $i<size($CTRLcurves);$i++)
{
if (`match "fk_R_shoulder" $CTRLcurves[$i]` == "fk_R_shoulder" )
{
$RfkCtrlShoulder = $CTRLcurves[$i];
}
else if (`match "fk_L_shoulder" $CTRLcurves[$i]` == "fk_L_shoulder" )
{
$LfkCtrlShoulder = $CTRLcurves[$i];
}
}
}
The above goes on for lines and lines going through just about every joint and curve in my rig but i could nt figure out a different way to do it.
The reason I got into this in the first place was I wanted to change jobs.So I left the studio i was at for 4 years a couple of months ago and thought id do a quick script for a perfect(?)biped body and facial rig,so i could show some of my techy skills on my new reel(I script so I dont forget how i did things, and its re-useable,and I really enjoy it),but it all turned into a bit of a nightmare mainly because i needed to get corresponding fk ik skin joints and ik fk control objects and a large chunk was figuring out space switching. I had seen and used hamish mckenzies great zooCST scripts but i found zooCST was really difficult for me to pull apart so I had to do it myself .Its actually all turned out fine (just need to add ribbons for secondary controls on top of the skin cluster and its done) although the object catching is still bugging me a little.

anyway thanks again for taking the time out!

Craig

e-moo
05-19-2009, 06:17 AM
thanks a LOT ppl for the replies.
I haven't read all of them yet, just posting to thank you guys for the support! :)

@Craig:
FK to IK is pretty easy ...... just need to query the rotations on the IK arm ..
example:
float $shoulderRot[] = `xform -q -ws -ro "ik_shoulderJoint" ` ;
rotate -ws -a $shoulderRot[0] $shoulderRot[1] $shoulderRot[2] "fk_shoulderJoint" ;

for IK to FK i just used locators aligned to my ik controllers and parentConstain (maintaining offset )them to the fk joints in the bindPose . then you just need to query the pos and rotation of the locators.
example:
float $wristPos[] = `xform -q -ws -rp "fk_wrist_Loc" ` ;
move -ws -a $wristPos[0] $wristPos[1] $wristPos[2] "ik_wrist_CTRL" ;

float $wristRot[] = `xform -q -ws -ro "fk_wrist_Loc" ` ;
rotate -ws -a $wristRot[0] $wristRot[1] $wristRot[2] "ik_wrist_CTRL" ;

you probably meant from IK to FK in the first line?
another thing, i managed to switch from IK to FK with no probs, but when switching from FK to IK, just placing the IK controller to the end of the FK chain does not seem to work. I have to manage the pole vector to match them exactly...
by the way, if i set pole vector to 0,0,0 and use 'twist' to manage the ik roll, is it possible to set the 'twist' value so that the IK chain match the FK chain?

again, thanks to all for the inputs... :)

skunk184
05-19-2009, 07:10 AM
Hi Imranul ,

EDIT - the first line is right i think looking at it again ... you are querying the IK shoulder joint rotation and then rotating the FK shoulder. It may be easier to use the orientConstraint as is pointed out but it looks right to me (but I did nt sleep last night so its all this IKFKIKFK is confusing me at the moment)

my advice would be to read Alex's(strarup) last post... He is one of the MEL masters here on cgtalk! Im hoping he'll read my previous post here cause id really like to clean up my script :P

not sure why its not working as there are so many ways to set up a rig and to quote Alex "one mistake can ruin it all",but i did have a few problems orienting (position was fine )my IK wrist to my FK wrist and vice versa but all i did was:
delete`orientConstraint -o 0 -2.673 -90 "wrist_joint" "ik_wristCrtl"`; // which was the offset difference on my rig.(obviously youll need to find your own values if the orientation is the problem).

I guess you should be able to do it using the twist attr but inever thought about how as ive always used pvConstraint. I would think its easier to use a pvConstraint,but im not sure.

cheers

Craig.

e-moo
05-19-2009, 11:32 AM
I did a small test with the following code, and it seems to work well :)

//IK to FK snap (FK controls snap to IK controls):
$ShoulderRot = `xform -q -ro -ws IK_Shoulder_joint`;
rotate -ws -a $ShoulderRot[0] $ShoulderRot[1] $ShoulderRot[2] "FK_Shoulder_ctrl" ;

$ElbowRot = `xform -q -ro -ws IK_Elbow_joint`;
rotate -ws -a $ElbowRot[0] $ElbowRot[1] $ElbowRot[2] "FK_Elbow_ctrl" ;
setAttr "Arm_control.IKFK_Blend" 1;

//FK to IK snap (IK controls snap to FK controls):
$Wrist_pos = `xform -q -t -ws FK_Wrist_joint`;
move -ws $Wrist_pos[0] $Wrist_pos[1] $Wrist_pos[2] "IK_Wrist_ctrl";

$PV_pos = `xform -q -t -ws Elbow_Aim_locator_follower`;
move -ws $PV_pos[0] $PV_pos[1] $PV_pos[2] "Elbow_Aim_locator";

i was having issues previously cause the control shapes had problems with orientation :)

skunk184
05-19-2009, 01:23 PM
splendid ... glad you got it working !

Craig

strarup
05-19-2009, 11:57 PM
Hi Craig,


will try and take a look at it... have been a bit busy today... and going to get my kids tomorrow for a couple of days... so not so sure how much time I will get the next couple of days before sunday when I have to bring them back to their mom...

might have some time in the evenings when they have been put to bed... but I dare not promise anything... since it's difficult to predict how a day goes before it's over...

if you e.g. want me to take a look at the whole script you can e.g. send it to my gmail... my main mail doesn't have that much storage left... :D
my gmail is strarup@gmail.com (http://forums.cgsociety.org/strarup@gmail.com) (only downside with my gmail is I often forget to check it)
main mail is 3d@strarup.net (http://forums.cgsociety.org/3d@strarup.net)
but will keep an eye on the gmail if you send anything...
e.g. the script and one of the rigs you have made that should work with the script... if posible...

a bit tired right now so will not comment that much... should allready be in my bed... got to get up early and catch a train in the morning... weee 5 hours travelling... and then 5 hours travelling back again... :D

eh... to get/make code "windows" here on cgtalk... just write code YourCodeExampleStuff /code
code and /code need a to be within a [] so code at the start... then your code stuff... and at the end /code or just highlight it and press the "wrap code tags" button which also make it... I ussually just write my post in a texteditor before posting...
btw. hamish mckenzie is cool... he's the one that learned me the trick of the "delete `parentConstraint $daObj1 $daObj2`;" a couple of years ago... :)

but will take a look at your code if you send it... and also post a better comment/post when I'm not so tired and have had better time to read your post... my brain is off duty at the moment... :)

kind regards

Alex

skunk184
05-20-2009, 05:55 AM
mornin' Alex,

Just sent you an email and like i said in it ,please dont worry about my me and my messy scripts. If you are busy ,not busy or whatever please dont feel obliged to take a look at them!Just enjoy the time with your kids mate!;)

"delete `parentConstraint $daObj1 $daObj2`;"

... great trick. Kiaran Ritchie taught me that one.In fact if it was nt for Kiaran and his Art of Rigging series I dont think i would have ever thought MEL was possible for me to learn!Thanks Kiaran. There will be code windows all over the place from now on,cheers for that.

Lucky you. Your brain is only off for the moment.Mine was "setAttr ($craig + ".brainUsage") 0"; for 28 years until I got into cg (9-10 years ago). Getting my brain wheels turning again was a challenge in itself and keeping them rotating is constant battle ...aarrrgghhh :argh: gimble lock.

A prime example of this is i sent the email to 3d@strarup.net and not your gmail like you asked, derrrrrrgh. It sounds like your "nose knows"( it made me chuckle! I really hope you what im referring to here or it just looks stupid),knows more than my brain.

always a pleasure to read your always 'packed with info' posts and again please dont worry if you dont find the time to look at my stuff.
have great day mate !

Craig

Mishiza
06-26-2009, 12:47 AM
Hey Guys!

Was reading this thread and in my quest for solving the problem of snapping the controllers. I was a bit stumped that everyone uses the pole vector function to snapp the controller into place (IK to FK). :lightbulb

Since my rigg is using both the pole vector and the twist value i wanted to add some thoughts to your solution. :twisted:

What if you can't use the pole vector and only the Twist on the IK handle? Now just to run this argument home, i know i can use the pole vector and that is the easy solution. But what if the animator (including me) wanted to use the twist?

e-moo
06-26-2009, 08:42 AM
Mishiza: (http://forums.cgsociety.org/member.php?u=317005)Thanks (http://forums.cgsociety.org/member.php?u=317005) for putting it up. I'd like to know this as well as i dont like to anbimate with pole vectors either.
(http://forums.cgsociety.org/member.php?u=317005)

Leffler
06-26-2009, 12:10 PM
Hi, just wanted to add something Ive discovered

When snapping and using constrains that then gets deleted, that is NOT going to work very well when you start adding keyframes to the channels. Then the constrain will be part of a pairblend-node with the value of 0 as standard, so when deleted it will not have done anything.

// Otto

Mishiza
06-26-2009, 07:51 PM
Hi, just wanted to add something Ive discovered

When snapping and using constrains that then gets deleted, that is NOT going to work very well when you start adding keyframes to the channels. Then the constrain will be part of a pairblend-node with the value of 0 as standard, so when deleted it will not have done anything.

// Otto

Yes I agree with this, deleting constraints will cause havoc later on. Why not have have a dummy object or grup that has the same worldspace as the controller you are trying to relocate and then just copy the translation& rotation attributes? Much safer.

Anyways, I've done a small test and i succeeded in making a snap IK>FK without using polevectors. :bounce: Using a point constraint, and three aimconstraints you can easily make a object which rotation Z values you can copy paste onto the twist value of the IK handle.

If anyone has any interest in how i did it i can post my script later on!

Leffler
06-26-2009, 08:35 PM
Of course, post it up dude!

(Funny, five minutes ago I visited the crytek website)

Mishiza
06-27-2009, 01:56 PM
So before you read this. this not a stand alone code, you need to for example also snap the IK controller where the FK controller is. Do not try to create and delete constraints all the time though, it just adds up in memory and sooner or later it will break down. anyways we are only covering the point where we have the shoulder and hand aligned where they should be and only have the twistvalue left to manipulate. With that said lets go to our code.


so lets start by defining our joint names and controllers name.
these names are just temporary. s for shoulder, e for elbow, h for hand.

string $IK_E_joint_name = "ikjoint2";
string $IK_s_joint_name = "ikjoint5";
string $IK_h_joint_name = "ikjoint3";
string $FK_E_ctrl_name = "FKjoint2";

once we done that we go on to creating our objects. These needn't be actual objects, you can basically do the same thing with null groups, but using lets say a cone gives you an idea of the workings since it is visible that its pointing.

\\Some easier names for the strings

string $aimref = ("aim_at_" + $FK_E_ctrl_name);
string $aimobject = ("aim_at_" + $IK_E_joint_name);
string $groupmaster = ($IK_E_joint_name + "_rotGroup")

\\ creates the objects and parents them into eachother
spaceLocator -p 0 0 0 -n $groupmaster;
polyCone -n $aimobject;
polyCone -n $aimref;
parent $aimref $aimobject;
parent $aimref $groupmaster;

now that thats done we can start with the constraints for the groupmaster

\\constraints the groupmaster between the shoulder and hand joint of the IK
pointConstraint -w 1.0 $IK_s_joint_name $IK_h_joint_name $groupmaster;

\\creates an aim constraint so the groupmaster is stable
select -r ($IK_s_joint_name);
select -add ($IK_E_joint_name + "_rotGroup");
aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 0 1 -upVector 0 1 0 -worldUpType "scene";

Now the reason we need a aimconstraint is that we know that the groupmaster is always pointing in the right direction. if not, we are going to get some weird offset rotation values.

next we do the same thing with the cones but we give them targets that are the elbows.

\\starts to constrain the cones so that they aim at he FK and IK joints.
select -r $IK_E_joint_name;
select -add $aimobject;
aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 1 0 -upVector 0 1 0 -worldUpType "scene";
select -r $FK_E_ctrl_name;
select -add $aimref;
aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 1 0 -upVector 0 1 0 -worldUpType "scene";



So now we are basically done with the main code all we need is to set this to work with our $aimobject's rotationZ value. How ever this is not exact so we can't just copypaste this into our IK.twist. But what we can do is make a code and define a margin of error, say 0.001 and use that to evaluate the rotation.

float $angle;
global proc setRotationTwist()
{
while ( (`getAttr aim_at_ikjoint2.rotateZ`) > 0.001 )
{
$angle = (`getAttr aim_at_ikjoint2.rotateZ`) + (`getAttr ikHandle1.twist`);
setAttr ikHandle1.twist $angle;
}
};

now we have a rotation on the twist that is near perfect the one that is the FK. Sorry for the sloppy code! hope this has helped you guys ^^

CGTalk Moderation
06-27-2009, 01:56 PM
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.