In questo post analizzeremo la metodologia per creare nuovi nodi in Tilemancer. Per una panoramica sul software, rimando al post dedicato.
Nota: il seguente articolo fa riferimento alla versione 0.2.0
Come è Composto un Nodo Tilemancer
Per essere considerato come nodo di Tilemancer, un file .lua deve possedere due metodi:
init()
che inizializza il nodoapply()
che viene chiamato ogni volta che il nodo va aggiornato, ad esempio quando vengono variati i parametri
Creando un file di questo genere:
ed inserendolo nella cartella Nodes di Tilemancer, sarà possibile visualizzarlo nella lista, come elemento vuoto (senza nome) e la stessa cosa succederà una volta che sarà inserito nel canvas.
Fig. 1 – Un nodo vuoto
Il Metodo init()
All’interno del metodo init()
è possibile effettuare una serie di chiamate di inizializzazione, alcune delle quali pressoché obbligatorie per il buon funzionamento del nodo: analizziamole nel dettaglio.
setName(name)
Questo metodo assegna un nome al nodo, che verrà utilizzato per identificare l’elemento all’interno della lista dei nodi e come titolo del nodo nel Canvas.
- name: il nome del nodo
setDesc(description)
Assegna al nodo un testo descrittivo.
- description: il testo della descrizione, visualizzato nel canvas quando si effettua un rollover sull’elemento nella lista dei nodi
setSize(width, height)
Assegna le dimensioni al nodo, una volta posizionato nel canvas.
- width: la larghezza del nodo una volta visualizzato nel canvas
- height: l’altezza del nodo una volta visualizzato nel canvas
Fig. 2 – Non è possibile interagire con un parametro al di fuori del nodo
addInput(name, y)
Aggiunge un elemento di input al nodo.
- name: l’etichetta visualizzata
- y: la posizione verticale dell’input sulla sinistra del nodo
addParameter(name, description, y, default, min, max, showPercent)
Aggiunge un parametro al nodo.
- name: l’etichetta visualizzata
- description: il testo della descrizione, visualizzato nel canvas quando si effettua un rollover sull’elemento
- y: la posizione verticale dell’input sulla sinistra del nodo
- default: il valore di partenza del parametro (effettuando doppio click sull’etichetta, il parametro verrà reinizializzato su questo valore)
- min: il valore minimo del parametro
- max: il valore massimo del parametro
- showPercent: se assegnato a true, visualizzerà il carattere
%
a fianco del valore del parametro
addInputParameter(name, description, y, default, min, max, showPercent)
Aggiunge un parametro al nodo, ma con la possibilità di ricevere il valore come input.
- name: l’etichetta visualizzata
- description: il testo della descrizione, visualizzato nel canvas quando si effettua un rollover sull’elemento
- y: la posizione verticale dell’input sulla sinistra del nodo
- default: il valore di partenza del parametro (effettuando doppio click sull’etichetta, il parametro verrà reinizializzato su questo valore)
- min: il valore minimo del parametro
- max: il valore massimo del parametro
- showPercent: se assegnato a true, visualizzerà il carattere
%
a fianco del valore del parametro
addOutput(y)
Aggiunge un elemento di output al nodo, comprensivo della sua anteprima al centro del nodo stesso.
- y: la posizione verticale dell’input sulla destra del nodo
addCRamp(y)
Aggiunge un componente per la selezione dei colori.
- y: la posizione verticale dell’elemento all’interno del nodo
Nota: questo metodo è specifico del nodo Colorizer e difficilmente avrebbe un utilizzo altrove. Viene riportato solo per completezza.
addInput
, addParameter
, addInputParameter
, l’elemento corrispondente viene inserito in una lista in modo crescente (il primo elemento avrà indice 0). Il valore dell’elemento potrà essere recuperato successivamente, durante l’esecuzione di apply()
, tramite questo indice.addOutput
, l’elemento corrispondente viene inserito in una lista in modo crescente (il primo elemento avrà indice 0). Il valore dell’elemento potrà essere modificato successivamente, durante l’esecuzione di apply()
, tramite questo indice.Il Metodo apply()
All’interno del metodo apply()
verranno effettuate tutte le operazioni che produrranno la texture in uscita. Analizziamo in dettaglio le operazioni disponibili.
getTileSize()
Ritorna le dimensioni scelte dall’utente per la texture generata.
getValue(index, x, y, divider)
Recupera il valore dell’input o parametro che si trova ad un determinato indice. Il metodo ritorna i valori normalizzati a 0-1 del colore (RGB) di un pixel in una determinata posizione.
- index: l’indice dell’elemento nella lista degli input e parametri
- x: la coordinata x del pixel da leggere. Nel caso la posizione sia al di fuori delle dimensioni della texture, verrà effettuato un wrap around
- y: la coordinata y del pixel da leggere. Nel caso la posizione sia al di fuori delle dimensioni della texture, verrà effettuato un wrap around
- divider: il divisore applicato al valore calcolato (viene utilizzato solamente se il valore analizzato è un parametro)
SetPixel(index, x, y, r, g, b)
Recupera l’output che si trova ad un determinato indice e setta i valori RGB di un determinato pixel.
- index: l’indice dell’elemento nella lista degli output
- x: la coordinata x del pixel da scrivere. Nel caso la posizione sia al di fuori delle dimensioni della texture, verrà effettuato un wrap around
- y: la coordinata y del pixel da scrivere. Nel caso la posizione sia al di fuori delle dimensioni della texture, verrà effettuato un wrap around
- r: il valore per il rosso (normalizzato a 0-1)
- g: il valore per il verde (normalizzato a 0-1)
- b: il valore per il blu (normalizzato a 0-1)
colorize()
Utilizzato in stretta connessione con addCRamp(y)
, colorizza la texture in ingresso che si trova all’indice 0 nella lista degli input.
Nota: questo metodo è specifico del nodo Colorizer e difficilmente avrebbe un utilizzo altrove. Viene riportato solo per completezza. Utilizzato in modo scorretto, potrebbe mandare in crash il programma.
Tutorial: Creare un Selettore di Input
In questo breve tutorial, ci proponiamo di creare un nodo che permetta, data una serie di input, di selezionarne uno come uscita, come se fosse una sorta di interruttore a più stati.
Creazione del file
Per prima cosa creiamo un file di testo chiamato switcher.lua, che andremo a salvare nella cartella Nodes di Tilemancer.
All’interno di esso creiamo i due metodi init()
e function apply()
:
Setup del Nodo
All’interno del metodo init()
andremo ad inserire, oltre ad i vari elementi necessari per l’inizializzazione, anche tre valori di input, un valore di output ed un parametro, che fungerà da selettore:
Come è possibile notare, sono stati inseriti i vari elementi.
_
.Se lanciamo Tilemancer, vedremo il nodo elencato nella lista e, cliccandoci sopra, lo potremo posizionare nel canvas (anche se al momento non effettuerà nessuna operazione).
Fig. 3 – Il nodo _Switcher
Processare la Texture
Il nostro nodo non dovrà fare altro che produrre come texture in uscita, l’input indicato dal parametro Selection.
Come è possibile vedere, per prima cosa andremo a leggere le dimensioni della texture, per poi creare un ciclo che vada a leggere ogni singolo pixel (utilizzerete questa operazione molto spesso…).
Subito dopo, recuperiamo l’indice selezionato tramite:
index = getValue(3, x, y, 1.0)
(il parametro Selection è al quarto posto, quindi con indice 3
).
La linea di codice successiva:
cr, cg, cb = getValue(index, x, y, 1.0)
recupera i valori RGB del pixel selezionato (per la texture selezionata).
Il passaggio successivo è banale: si tratta semplicemente di settare in uscita i colori appena letti.
Fig. 3 – Il nodo in azione