PDA

View Full Version : Joint Snapping Mel


Khaos
04-23-2003, 06:55 PM
I have a FK/IK switch for my arms and legs. When I blend between the two I get a poping movement of the joints. I read things on the web about setting up a MEL script that would snap the FK joints to the position of the IK joints when the switch is enabled.

How would this be setup? I'm just starting to learn MEL so I figure that this would be a good way to get started. Any help would be greatly appriciated.

Oh! If anyone has a better alternative, feel free to soud off! :D

mental
04-23-2003, 08:04 PM
IK/FK switching between only 2 skeletons will give you that popping. the way most people get around it is be using a 3 joint system: IK, FK and control/real arm.

here's a useful tutorial by one of the cgtalk forum folk:

http://www.vfs.com/~m07goosh/Tutorials/ikfkswitching/ikfkswitching.htm

it's quick and easy to setup and would probably be a better solution to your problem than a mel script.

larryvm
04-24-2003, 11:52 AM
this is a mel script i wrote for a friend for the same fk-ik with 3 skeletons, is only for ideas,

it made a locator for a new coord system and find the angle to aply for the twist, it work well, but is for the setup of my friend,you must change some things to work in your own skeleton, at this time i canīt made a traduction to english, sorry

// fvik_fk FernandoVizoso
// Larryvm@hotmail.com
// para erik

global proc fvik_fk(string $lado)
{
//colocamos la muņeca, esto esta copiado directamente de tu mail
float $pos[] = `xform -q -ws -t jfk_muneca_izda`;
float $rot[] = `xform -q -ws -a -ro jfk_muneca_izda`;
move -rpr $pos[0] $pos[1] $pos[2] guante_izda;
xform -ws -a -ro $rot[0] $rot[1] $rot[2] guante_izda;

//definimos 4 puntos, el codo y el hombro en fk e ik
float $punto[];
float $punto1[];
float $punto2[];
float $punto3[];
float $matriz[];

// cogemos su posicion
$punto=`xform -q -ws -t ("jik_codo_"+$lado)`;
$punto1=`xform -q -ws -t ("jfk_codo_"+$lado)`;
$punto2=`xform -q -ws -t ("jik_hombro_"+$lado)`;
$punto3=`xform -q -ws -t ("jfk_hombro_"+$lado)`;

//creamos el locator que nos creara un nuevo sistema de coordenadas
$base=`spaceLocator -p 0 0 0` ;



//lo muevo al mismo sitio que el hombro_ik (daria lo mismo al fk, estan en el mismo punto
move -a $punto2[0] $punto2[1] $punto2[2] $base;
// hago un constraint de modo que el eje y este apuntando a la muņeca y el z orientado paralelo al codo

$const=`aimConstraint -weight 1 -aimVector 0 1 0 -upVector 0 0 1 -worldUpType "object" -worldUpObject ("jik_codo_"+$lado) ("guante_"+$lado) $base`;

//calculo las posiciones relativas del codo respecto al hombro
$punto[0]-=$punto2[0];
$punto[1]-=$punto2[1];
$punto[2]-=$punto2[2];
$punto1[0]-=$punto3[0];
$punto1[1]-=$punto3[1];
$punto1[2]-=$punto3[2];

//guardo la matriz de transformacion inversa de el locator

$matriz=`getAttr ($base[0]+".im")`;

//para depurar
print "hecho";

//calculo las coordenadas de los punto (codo ik y fk) en relacion al locator
//esto se hace multiplicando el punto por la matriz de transformacion inversa

float $resultado2[];
$resultado2=pointMatrixMult ($punto, $matriz);

float $resultado3[];
$resultado3=pointMatrixMult ($punto1, $matriz);

vector $v1;
vector $v2;

//creo los vectores poniendole a 0 la componente y, es lo mismo que proyectarlos a un plano perpendicular a la linea del hombro a la muņeca
$v1=<<$resultado2[0],0,$resultado2[2]>>;
$v2=<<$resultado3[0],0,$resultado3[2]>>;

// calculo el angulo
$angulo=rad_to_deg(`angle $v1 $v2`);
//para depurar
print $angulo;

//guardo el twist del ik
$twist=`getAttr ("guante_"+$lado+".twist")`;

//calculo el twist nuevo tomandolo como positivo
$twist2=$twist-$angulo;

setAttr ("guante_"+$lado+".twist") $twist2;
float $test1[];
float $test2[];


//testeo si era el angulo correcto
$test1=`getAttr ("jfk_hombro_"+$lado+".rotate")`;
$test2=`getAttr ("jik_hombro_"+$lado+".rotate")`;
int $test1ent[];
int $test2ent[];
$test1ent[0]=$test1[0]*100;
$test1ent[1]=$test1[1]*100;
$test1ent[2]=$test1[2]*100;
$test2ent[0]=$test2[0]*100;
$test2ent[1]=$test2[1]*100;
$test2ent[2]=$test2[2]*100;

if (($test1ent[0]==$test2ent[0])&&($test1ent[1]==$test2ent[1])&&($test1ent[2]==$test2ent[2]))
{
//si lo es va cojonudo
print "\n angulo positivo";
}
else
{
/si no lo es lo tomo como negativo
$twist2=$twist+$angulo;
setAttr ("guante_"+$lado+".twist") $twist2;
print "\n angulo negativo";
}
//borro el locator y el constraint
delete $const;
delete $base;

}

CGTalk Moderation
01-14-2006, 11:00 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.