Stretch control tutorial


--------------------------------------------------------------------------------



Questo tutorial serve per creare un controllo che permetta lo 'stretch' dei joints di un rig, per ottenere magari un effetto 'cartoon'

(anche se poi verrà proposto anche un utilizzo alternativo).

In questa prima parte eseguiremo lo stretch su un singolo joint, mentre nella seconda parte riggheremo un 'teorico' arto di un personaggio.



Creiamo quindi 2 joints in sequenza o selezioniamone due consecutivi da una catena esistente (non necessariamente il primo o l'ultimo, anche due nel mezzo della catena).

Rinominiamoli giusto per comodità j1 e j2.

Andiamo poi dalla sezione 'Animation' nel menu Skeleton->IK Handle Tool->[]

Nella finestra del tool settings che ci si aprirà a destra scegliamo come Current solver ikSCsolver

Creiamo la nostra catena IK da j1 a j2 e rinominiamola ik.

Creiamo una semplice curva come controllo e chiamiamola ctrl

Ora due locators, rinominiamoli l1 e l2

Posizioniamo il tutto...

Selezioniamo prima j1 poi l1 ed eseguiamo un Point Constraint con le opzioni di default

Selezioniamo prima ik poi l2 ed eseguiamo un Point Constraint con le opzioni di default

'Snappiamo' ctrl ad ik, eseguiamo quindi un Freeze Transformations su ctrl poi selezioniamo prima ctrl poi ik ed eseguiamo un Point Constraint con le opzioni di default, .

Selezioniamo ctrl e scegliamo la voce di menu Modify->Add Attribute...

Aggiungiamo un attributo o_dist di tipo Float, poi un altro attributo stretchy di tipo int, dandogli 0 come Minimum e 1 come Maximum.


La teoria:

dobbiamo innanzi tutto stabilire la distanza che intercorre nella posizione di partenza tra i due joints, poi, ad ogni spostamento,
calcolare la distanza dell 'ik handle dal primo joint, così da dividerla per quella originaria e sapere così la percentuale di stretch da attribuire al primo joint, un qualcosa tipo:

j1.stretch = distanza / distanzaOriginaria.

Assumiamo che i joints, come da default, abbiano l'asse X che punta verso il joint successivo(se non dovesse essere il vostro caso cambiatelo al bisogno),

quindi il valore di stretch andrà attribuito allo ScaleX del primo joint.


Perchè i locators e il controllo?

Già in questa maniera Maya ci dà un warning di un cycle presente, cosa che possiamo ignorare, ma se non utilizzassimo questo sistema potrebbero sorgere problemi,

sia per la maniera in cui viene calcolata la posizione tra i joints, sia perchè, nel caso di una catena di joints, succede a volte che il programma metta a 0 il valore di ScaleX, salvo poi rimetterlo a posto al primo movimento.


Ora apriamo l' hypershade e andiamo nella tabella utilities, creiamo quindi un Distance Between node e un Multiply Divide node (nell' hypershade menu Create->General Utilities...)

Rinominiamo il primo db ed il secondo md, apriamo l' Attribute Editor per md e settiamo il campo Operation su divide.

Ora un po' di connessioni.

l1.translate connesso a db.point1

l2.translate connesso a db.point2

Ora il nodo db ha nel suo campo distance il valore della distanza tra il due locators(e quindi tra i due joints)

questa è la nostra distanza iniziale, possiamo o copiarla nel campo o_dist di ctrl, oppure possiamo effettuare una connessione tra db.distance e ctrl.o_dist per poi rimuovere la connessione, il valore rimarrà copiato.


Ora: db.distance connesso a md.input1X

ctrl.o_dist connesso a md.input2X

md.outputX connesso a j1.scaleX


Ora selezionando e spostando ctrl, osserveremo come non solo j1 si allungherà in base al movimento, ma i suoi assi punteranno sempre nella stessa direzione

(cioè, nel nostro caso, l'asse X punterà sempre verso j2).


Aggiungiamo un 'interruttore' per attivare o disattivare la modalità 'stretch', utilizzeremo il campo stretch di ctrl.


Riportiamo ctrl ai valori di traslate 0 0 0, potremmo notare che j1 non ritorna alla sua lunghezza iniziale, possiamo non tenerne conto per ora,
oppure possiamo settare una key per i valori di traslate di ctrl al frame 1, e un' altra al frame 2 dove ctrl è a 0 0 0.

Azionando la timeline tutto tornerà normale, possiamo così rimuovere le 2 keys create e riprendere il nostro tutorial.


Sempre nell' Hypershade creiamo un condition node e chiamiamolo c.

ctrl.stretchy connesso a c.firstTerm

di default le impostazioni di c sono 'Equal' e il secondTerm è 0, lasciamole così

Settiamo manualmente (dal Channel Box ad esempio) ColorIfTrueR a 1

md.outputX connesso a c.colorIfFalseR

In questa maniera, se ctrl.stretchy è uguale a 0, il valore di j1.scaleX sarà 1, mentre in caso contrario sarà il risultato ottenuto dalle operazioni precedenti

c.outColorR connesso a j1.scaleX


Ora riproviamo, muovendo il nostro ctrl avendo stretchy = 0 avremo una semplice catena ik, mentre con stretchy = 1 osserveremo il risultato del nostro lavoro.


Ho utilizzato questo sistema quando ho creato uno script per un auto-rig, veniva creato uno skeleton che poi riposizionavo per adeguarlo al character, e ruotare i joints era lungo, muovendoli perdevo l'orientamento degli assi e un aim constraint non sempre era possibile, con questo sistema, semplicemente spostavo ad esempio
l'ossatura delle dita e, una volta rimossi i nodi inutili ed eseguendo un Freeze Transformations tutto era ok.



--------------------------------------------------------------------------------

--------------------------------------------------------------------------------


Seconda Parte, il rigging di un braccio



--------------------------------------------------------------------------------


In questa seconda parte creeremo un controllo 'stretch' per un arto, nel nostro esempio un braccio.


Dobbiamo tenere conto di due cose fondamentali:

- per avere una distorsione ottimale distribuiremo lo stretch su due ossa diverse (Braccio e Avambraccio)

- dobbiamo considerare una distanza minima (pari a quella iniziale) alla quale annullare automaticamente lo stretch, altrimenti non riusciremo più a piegare il nostro braccio, ma semplicemente continuerà ad accorciarsi.


Naturalmente per avere un braccio 'stretchabile' dobbiamo usare un tipo di rig IK, e non FK.



Facciamo finta di avere già un braccio composto da 3 joints, spalla, gomito e polso (j1, j2, j3)

applichiamogli una ik handle chiamata ik (stavolta un ikRPsolver, ricordiamoci però di settare il preferred angle al gomito)

creiamo un controllo per il Pole Vector (un locator andrà bene)

Assicuriamoci che il tutto sia settato a dovere e funzioni...possiamo iniziare.

Il tutto è molto simile all'esempio precedente, solo con qualche aggiunta...


Creiamo una curva di controllo ctrl e due locators, l1 e l2.

come prima:

Selezioniamo prima j1 poi l1 ed eseguiamo un Point Constraint con le opzioni di default

Selezioniamo prima ik poi l2 ed eseguiamo un Point Constraint con le opzioni di default

'Snappiamo' ctrl ad ik, eseguiamo quindi un Freeze Transformations su ctrl poi selezioniamo prima ctrl poi ik ed eseguiamo un Point Constraint con le opzioni di default, .


Selezioniamo ctrl e scegliamo la voce di menu Modify->Add Attribute...

Aggiungiamo un attributo o_dist di tipo Float, e due altri attributi, sempre Float, di nome ratio1 e ratio2(saranno i coefficienti per cui moltiplicheremo le scaleX
dei due joints, così che, volendo, potremo scalarli non proporzionalmente)settiamo di default i loro valori ambedue a 0.5(la somma darà 1)

Aggiungiamo un ulteriore attributo o_distH di tipo Float, questo non sarà altro che la metà di o_dist (H sta per half).


Ora apriamo l' hypershade e andiamo nella tabella utilities, creiamo quindi un Distance Between node (db)e due Multiply Divide nodes (md e md_ratios), ricordiamoci di settare su divide il valore operation di md.

Creiamo inoltre un condition node(c_min), settiamo ad 1 i valori per ColorIfTrue(sia R che G) e come Operation mettiamo Less or Equal.

Ora un po' di connessioni.

l1.translate connesso a db.point1

l2.translate connesso a db.point2

Ora il nodo db ha nel suo campo distance il valore della distanza tra il due locators(e quindi tra i due joints)

questa è la nostra distanza iniziale, possiamo o copiarla nel campo o_dist di ctrl, oppure possiamo effettuare una connessione tra db.distance e ctrl.o_dist per poi rimuovere la connessione, il valore rimarrà copiato, dividiamo per due tale distanza e scriviamola in o_distH.


Ora: db.distance connesso a md.input1X

ctrl.o_distH connesso a md.input2X


md.outputX connesso a md_ratios.input1X

md.outputX connesso(anche) a md_ratios.input1Y


ctrl.ratio1 connesso a md_ratios.input2X

ctrl.ratio2 connesso a md_ratios.input2Y


Avremo così nell'output di md_ratios i valori da attribuire allo scaleX dei due joints.

Se la distanza attuale è minore o uguale alla distanza iniziale, smettiamo di utilizzare lo stretch ed attribuiamo sempre 1 come valore di scale.


db.distance connesso a c_min.firstTerm

ctrl.o_dist connesso a c_min.secondTerm


md_ratios.outputX connesso a c_min.colorIfFalseR

md_ratios.outputY connesso a c_min.colorIfFalseG


c_min.outcolorR connesso a j1.scaleX

c_min.outcolorG connesso a j2.scaleX


Ora muovendo ctrl e allontanandolo il braccio si allungherà, mentre avvicinandolo ritornerà
fino alla lunghezza iniziale per poi piegarsi...

--------------------------------------------------------------------------------


That's all folks...

stretchme

---
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