RIGGING

quarta parte - le braccia






In questa quarta parte ci occuperemo delle braccia, quindi andiamo subito ad iniziare.

Questo è il braccio del nostro scheletro base, dobbiamo replicarlo(2 volte)tenendo solo i joints segnati, che sono, spalla, gomito, avambraccio e polso:

Image 65

chiameremo una catena: j_L_Shoulder_Ik,  j_L_Elbow_Ik, j_L_ForeArm_Ik, j_L_Wrist_Ik, e l'altra

j_L_Shoulder_Fk,  j_L_Elbow_Fk, j_L_ForeArm_Fk, j_L_Wrist_Fk.

Imparentiamo le due shoulder a j_sk_L_Scapula e facciamo il mirror, poi prendiamo i due Elbow_Ik, e settiamogli il preferred angle come abbiamo fatto per le gambe, solo che stavolta la rotazione sarà sull'asse y, in avanti, come un vero gomito.

Image 66

Creiamo quindi la nostra IK handle dalla spalla al FOREARM..attenzione al messaggio che Maya darà, qui segnato da un cerchio rosso:

Image 67

Leggiamo bene il numero dell' effector appena creato(nel mio caso 17), e nella Command Line digitiamo select effector17 e premiamo invio.

Image 68

selezioniamo il move tool e premiamo il tasto insert, poi snappiamo l'effector al polso

Image 69

Usciamo dal move tool e rinominiamo l'handle ik_L_Arm.

Creiamo un semplice controllo, nel mio caso un cubo formato da una curva e snappiamolo all'ik(ctrl_L_Arm_Ik, delete history, center pivot e freeze transformations), poi point constraint(controllo-ik) e orient constraint (j_sk_L_Wrist-controllo).

Image 70

Creiamo un controllo per il pole vector, snappato al gomito, poi portato indietro lungo l'asse z(ctrl_L_Arm_Pv, delete history, center pivot e freeze transformations) e pole vector constraint (controllo-ik), poi possiamo nascondere l'ik.

Image 71

Ora pensiamo alla catena FK, creiamo un locator e snappiamolo a ctrl_L_Arm_Pv (loc_L_Arm_Fk_Pv, delete history, center pivot e freeze transformations), poi parent constraint j_L_Shoulder_Fk-locator.

Image 72

Perchè questo? Facciamo un po' di teoria sull'IK.

Costruiamoci un semplice braccio dalla vista frontale composto da: Root, spalla, gomito, polso e qualche dito.

Image 73

Settiamo il preferred angle e creiamo un ikRPsolver, dalla spalla al polso.

Image 74

creiamo un locator come pole vector, piazziamolo e settiamo un pole vector constraint(locator-ik)

Image 75

Ora creiamo un piano poligonale, settiamo le suddivisioni a 1,1...poi snappiamo il suo pivot point ad un edge

Image 76

poi snappiamo il piano al gomito e scaliamolo

Image 77

ora selezioniamo il gomito, poi il piano e parent constraint

Image 78

come vediamo, il piano passa per il gomito, il polso e il locator...siccome per tre punti passa uno ed un solo piano, questo è l'unico possibile.

Muoviamo un po' l'IK

Image 79

Comunque muoviamo l'IK, il piano passa sempre per quei 3 punti...confermiamolo muovendo anche il locator...

Image 80

Visto? Non dico bugie, e neanche il solver :) , ed è una consolazione, perchè così possiamo lavorarci su.

Quando abbiamo un sistema IK/FK, il problema non è tanto il passaggio dall' IK all' FK, quello è semplice, il difficile è l'inverso...perchè?

Riprendiamo la nostra semplice catena IK, rinominiamo appropriatamente e stavolta azzeriamo i controlli Ctrl_IK e loc_IK_Pv facendo un freeze transformations, mettiamo il tutto (esclusa la Root in un livello chiamato L_IK).

Image 81

Ora ricreiamo la stessa catena con altri nomi e mettiamo il tutto (esclusa la Root in un livello chiamato L_FK).

Image 82

Visualizziamo tutti i livelli e spostiamo il nostro braccio IK(volendo anche il pole vector)

Image 83

prendiamo nota delle rotazioni di spalla_IK

Image 84

e copiamole in spalla_Fk

Image 85

poi prendiamo nota delle rotazioni di gomito_IK

Image 86

e copiamole in gomito_Fk

Image 87

Ed ecco eseguito uno snapping IK-FK...facile da farsi anche con un semplice script.

Ora muoviamo un po' la spalla_FK

Image 88

Non possiamo copiare le rotazioni al contrario di come abbiamo fatto prima...dovremmo disabilitare l'IK, copiare le rotazioni e riabilitare l'IK...ma una volta fatto, entrerebbe in azione il nostro Pole Vector...e addio...

Image 89

Come facciamo a stabilire dove si dovrà trovare il nostro pole vector? E a stabilirlo matematicamente, facilmente, e senza impazzire?

Rimettiamo tutto a posto(azzeriamo le traslazioni di ctrl_IK e loc_IK_Pv, e le rotazioni di spalla_FK e gomito_FK)...

Creiamo un nuovo locator e chiamiamolo loc_FK_Pv...snappandolo a loc_IK_Pv, poi imparentiamolo a spalla_FK.

Image 90

Ora muoviamo liberamente spalla_FK e gomito_FK...

Image 91

Selezioniamo ctrl_IK e snappiamolo a polso_FK

Image 92

poi selezioniamo loc_IK_Pv e snappiamolo a loc_FK_Pv

Image 93

Facile e ben calcolabile...no?

Questa è l'idea che ci guiderà nella nostra costruzione del braccio IK/FK, migliorandola un po' e rendendola eseguibile con un semplicissimo script.

Le nostre due catene erano pronte, ora dobbiamo trovare il modo di fargli controllare la nostra catena base...Innanzi tutto aggiungiamo al nostro 'controllo raggruppatore' (ctrl_L_Arm) due attributi di tipo integer con minimo = 0 e massimo = 1 di nome ikIndex e fkIndex.

Creiamo un reverse node(rev_IkFkIndex) e colleghiamo ctrl_L_Arm.ikIndex con rev_IkFkIndex.InputX, poi riprendiamoli in ordine inverso e colleghiamo rev_IkFkIndex.OutputX con ctrl_L_Arm.fkIndex.

In questa maniera basterà settare solamente ikIndex e automaticamente fkIndex prenderà il valore opposto(1-0 o 0-1), questi indici diranno quale sistema è attualmente in uso.

In genere si utilizzano degli orient constraint per stabilire quale joint di quale catena comanda la base, io qui invece ho utilizzato un sistema diverso, tanto per provare...ed è il seguente:

IK attivo: spalla_base = spalla_ik

FK attivo: spalla_base = spalla_fk

sarebbe come dire:

IK attivo: spalla_base = spalla_ik + (spalla_fk * 0);

FK attivo: spalla_base = spalla_fk + (spalla_ik * 0);

e quindi:

spalla_base = (spalla_ik * ikIndex) + (spalla_fk * fkIndex);

chiaro?

la rotazione della spalla base è comandata dalla rotazione del controllo ctrl_L_Arm, dove abbiamo imposto tutti i nostri calcoli in precedenza per fare in modo che le varie ossa del braccio ruotino secondo l'asse...ricordate?Y e Z ok, ruota la spalla, X invece spalla ferma e ruota il nostro joint in + tra spalla e gomito.

Quindi creiamo un md_L_Arm_Ik(un multiply divide node) dove moltiplicheremo le rotazioni di j_L_Shoulder_Ik con l' ikIndex,

poi un md_L_Arm_Fk(un multiply divide node) dove moltiplicheremo le rotazioni di j_L_Shoulder_Fk con l' fkIndex.

A questo punto creiamo un pma_L_Arm_IkFk(plus minus average node)dove sommeremo gli output dei due md_... e manderemo il risultato direttamente a ctrl_L_Arm.Rotate.

Per selezionare meglio j_L_Shoulder_Fk, ho utilizzato un metodo che ho scoperto da poco, cioè ho assegnato una shape di una curva al joint, in maniera che, anche se metterò la visibilità dei joints a 0 per non disturbarmi mentre animo, la curva resterà ugualmente visualizzata e selezionabile.

Questo non vuol dire creare una curva e farle controllare il joint...ma fare in modo che la curva DIVENTI il joint, per fare questo bisogna utilizzare un piccolo script:

parent -add -shape NOMEDELLASHAPE NOMEDELJOINT;

ad esempio parent -add -shape nurbsCircleShape1 joint4;

migliorato, selezioniamo la shape, il joint e:

string $allObjects[];

$allObjects = `ls -sl`;

parent -add -shape $allObjects[0] $allObjects[1];

Quindi ho creato il mio solito cubetto fatto da una curva, rinomino, delete history, tasto freccia in basso(per selezionare la shape), shift select j_L_Shoulder_Fk e via allo script.

Ora dovremo solo modellare un po' gli edit point della curva che si è piazzata sul joint intorno al braccio, e poi potremo eliminare la curva inizialmente creata.

Da ora in poi, selezionando la curva avremo selezionato il joint.

In più ho aggiunto un float come attributo a j_L_Shoulder_Fk di nome Elbow da cui controllo la rotazione Y del gomito base, in questa maniera non dovrò selezionare il joint del gomito per muoverlo.

Qualche piccola aggiunta/chiarimento...

Ricordate che all'inizio di questa parte, quando vi ho fatto aggiungere loc_L_Arm_Fk_Pv ve l'ho fatto legare alla spalla con un parent constraint e invece nell'esempio che vi ho fatto dell' IK/FK ve l'ho fatto semplicemente imparentare?

Bene, con un semplice parent il locator sì, si muove, ma i suoi valori di rotazione rimangono sempre 0,0,0 perchè sono relativi al padre, con il parent constraint invece, i suoi valori cambiano, e a noi serve sapere questi valori...

Infatti metteremo un attributo di tipo vector su ctrl_L_Arm_Pv di nome fkpos e ci farò finire con il connection editor i valori di traslate di loc_L_Arm_Fk_Pv.

Inoltre metterò lo stesso tipo di attributo su ctrl_L_Arm_Ik, e ci farò finire i valori di translate di un locator(loc_L_Wrist_Fk) che sarà snappato, freeze transformations e point constraint a j_L_Wrist_Fk, così da sapere dove è il polso fk.

Uno stesso tipo di attributo ma di nome ikrot sarà attribuito a j_L_Shoulder_Fk, e ci finiranno i valori di rotazione di j_L_Shoulder_Ik,

e un attributo di tipo float di nome ikelbow che riceverà la rotateY di j_L_Elbow_Ik.

In questo modo avrò tutti i dati che mi servono per effettuare uno snap IK/FK e FK/IK da script...ecco come:



string $allObjects[];

$allObjects = `ls -sl`;

int $numObjs = size($allObjects);

int $i;

for($i = 0; $i < $numObjs; $i++) {

    if(`attributeExists "fkpos" $allObjects[$i]`) {

        setAttr ($allObjects[$i] + ".translateX") `getAttr ($allObjects[$i] + ".fkposX")`;

        setAttr ($allObjects[$i] + ".translateY") `getAttr ($allObjects[$i] + ".fkposY")`;

        setAttr ($allObjects[$i] + ".translateZ") `getAttr ($allObjects[$i] + ".fkposZ")`;

    } else {

        if(`attributeExists "ikrot" $allObjects[$i]`) {

            setAttr ($allObjects[$i] + ".rotateX") `getAttr ($allObjects[$i] + ".ikrotX")`;

            setAttr ($allObjects[$i] + ".rotateY") `getAttr ($allObjects[$i] + ".ikrotY")`;

            setAttr ($allObjects[$i] + ".rotateZ") `getAttr ($allObjects[$i] + ".ikrotZ")`;

            if(`attributeExists "ikelbow" $allObjects[$i]`) {

                float $dummyf = `getAttr ($allObjects[$i] + ".ikelbow")`;

                if($dummyf > 0) $dummyf = 0;

                    setAttr ($allObjects[$i] + ".Elbow") $dummyf;

                }

        }

    }

}

Io non dovrò fare altro che muovere, l' IK....e quando voglio seleziono j_L_Shoulder_Fk e aziono lo script, oppure

muoverò, l' FK....e quando voglio seleziono ctrl_L_Arm_Ik e ctrl_L_Arm_Pv e aziono lo script.

La routine prende la mia selezione, e per ogni oggetto selezionato cerca se ha un attributo chiamato fkpos, se ce l'ha sa che deve copiarne i valori su translate...se invece trova ikrot sa che deve copiarne i valori sul rotate, se poi ci trova anche ikelbow ne copia il valore su Elbow.

Solita operazione per il gomito:

gomito_base = (gomito_ik * ikIndex) + (gomito_fk * fkIndex);

Sappiamo già come fare, no?

Per il polso...alla prossima

---
Questo articolo è stato importato automaticamente dal forum il 31/lug/2014
Per vedere il post originale e/o i commenti sul forum prima di quella data clicca qui