|  | 
 |  | ||||
|  | 
ROBOTICA
video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori
|  | Approfondimenti sulle Textures |  | 
 
   Anticipo la parte di approfondimenti 
  sulle textures... (a gran richiesta di una persona ;) ).  
    Avevamo visto nella prima 
    parte come mappare textures sulle superfici degli oggetti. In particolare 
    si era analizzato il caso di mapping sulle semplici primitive geometriche 
    rese disponibili da Vrml (Cone,Sphere,Cylinder,Box). Ricapitoliamo velocemente 
    quanto visto con un banale esempio: 
    
    Nel campo texture del 
    nodo Appearance introduco un nodo ImageTexture il cui campo url contiene una 
    reference alla immagine da mappare.   Fin qui e' tutto noto. 
    
    Vediamo ora di approfondire 
    le nostre conoscenze su come gestire le textures. Si noti bene che nella maggior 
    parte dei casi si utilizzeranno le modalita' di default; quando pero' si vogliono 
    ottenere certi effetti e maggiore controllo sul mapping ci si deve preoccupare 
    di aspetti piu' 'complicati'. 
    Iniziamo con l'analizzare 
    un campo del nodo Appearance che ancora ci manca: textureTransform. Questo 
    campo serve per modificare le modalita' secondo cui mappare le textures sulle 
    superfici. Il campo textureTransform contiene al suo interno un nodo TextureTransform 
    (attenzione alle lettere maiuscole). La specifica del nodo TextureTransform 
    e' la seguente: 
    
    I campi sono molto semplici. 
    Il campo rotation offre la possibilita' di ruotare la texture da mappare. 
    La rotazione viene ovviamente effettuata attorno all'asse perpendicolare al 
    piano della texture. Il centro attorno a cui effettuare la rotazione viene 
    specificato nel campo center. Questo deve essere espresso in coordinate s,t 
    della texture. 
    Molto brevemente, le 
    coordinate s,t indicano le variabili utilizzate per la scansione dell'immagine 
    da mappare. s in pratica indica l'ascissa di un punto dell'immagine, mentre 
    t ne rappresenta l'ordinata. La coppia 0 0 indica l'angolo in basso a sinistra; 
    1 0 l'angolo in basso a destra, 0 1 l'angolo in alto a sinistra; 1 1 l'angolo 
    in alto a destra. Per cui .5 .5 indica il centro dell'immagine. 
    Il campo translation 
    serve per traslare la texture. Anche qui utilizziamo le coordinate s,t. Fornendo 
    la coppia .5 0 si trasla la texture verso destra di una quantita' di pixels 
    pari a meta' dell'immagine. La parte a sinistra che rimane scoperta viene 
    mappata con la parte destra dell'immagine stessa (si ha un rientro). 
    Il campo scale serve 
    per scalare l'immagine da mappare. Sotto certe condizioni questo consente 
    di mappare sulla superficie piu' copie della stessa texture. Vedremo poi come 
    ottenere questo effetto. 
    Non preoccupatevi se 
    ora vi sembra tutto abbastanza confuso. Con gli esempi successivi vedremo 
    di chiarirci le idee. 
    Tutte queste operazioni 
    hanno senso nel caso di un IndexedFaceSet; per le primitive il modo di mapping 
    e' quello standard. 
    Vediamo allora come mappare 
    una texture su un semplice oggetto creato con IndexedFaceSet. Il piu' semplice 
    oggetto di questo tipo e' una singola faccia. Definiamo dunque un quadrilatero 
    e vediamo gli effetti che otteniamo. 
    
    L'effetto che otteniamo 
    non e' affatto buono... tant'e' che non riusciamo neppure ad intravedere l'immagine 
    che forma la texture. Quando si ha un IndexedFaceSet il browser (Cosmo Player 
    beta 3 e' quello di riferimento in questo caso) mappa la texture sulla bounding 
    box che avvolge l'oggetto. Per cui in questo caso si vede solo una piccola 
    parte della texture. 
    Cio' che serve e' un 
    qualcosa che ci consenta di dimensionare la texture in modo opportuno. In 
    particolare dobbiamo indicare che nell'angolo in basso a sinistra della faccia 
    vogliamo che si vada a mappare l'angolo in basso a sinistra dell'immagine; 
    e lo stesso per tutti gli altri 3 angoli. 
    Il nodo IndexedFaceSet 
    offre appunto questa possibilita'. In particolare si utilizzano i campi texCoord 
    e texCoordIndex il cui funzionamento e' identico a quello dei campi usati 
    per definire la faccia. 
    Vediamo l'esempio e poi 
    spieghiamo in dettaglio questi nuovi campi. (nell'esempio riporto solo il 
    nodo Shape). 
    
    In questo caso otteniamo 
    il risultato che ci attendavamo. 
    Il campo texCoord contiene 
    il nodo TextureCoordinate. In pratica questo nodo contiene le stesse informazioni 
    contenute nel nodo Coordinate, con la sola differenza che qui ci si riferisce 
    alle coordinate della texture. Quindi si specifica una coppia di valori; in 
    particolare associamo al primo punto del quadrilatero la coppia 0 0 che indica 
    appunto l'angolo in basso della texture. E cosi' via per quanto riguarda gli 
    altri angoli. Il campo texCoordIndex contiene gli indici dei punti contenuti 
    nel campo point del nodo TextureCoordinate; in questo caso definiamo dunque 
    una texture quadrata che va a mapparsi sul quadrilatero generato. 
    Finche' ci si limita 
    a mappare textures su forme geometriche piuttosto semplici, si puo' fare questo 
    lavoro a mano; ma se avessimo geometrie molto piu' complicate allora la cosa 
    diventa ingestibile e l'ausilio di un tool di sviluppo risulta necessario. 
    
    Prima di passare ad analizzare 
    come impiegare le potenzialita' del nodo TextureTransform, mi interessa evidenziare 
    l'esistenza di altri due campi non ancora analizzati e che fanno parte del 
    nodo ImageTexture. Infatti, oltre al campo url, vi sono i campi repeatS e 
    repeatT. Questi due prendono un valore booleano e sono settati a TRUE di default. 
    In pratica abilitano la ripetizione delle textures in fase di mapping. Vediamo 
    subito un esempio. 
    Nell'esempio precedente 
    abbiamo mappato la Gioconda sopra un quadrilatero, senza preoccuparci molto 
    delle dimensioni della texture e del quadrilatero stesso. Imponendo che agli 
    angoli del quadrilatero le coordinate s,t devono assumere certi valori, si 
    impone al browser di interpolare nelle posizioni intermedie e in pratica di 
    riempire l'intero quadrilatero. 
    Supponiamo ora di volere 
    mappare piu' esemplari della Gioconda sul piano. In tal caso un modo possibile 
    e' quello di riscalare la texture tramite il nodo TextureTransform. Se i campi 
    repeatS e repeatT sono settati a TRUE il browser effettuera' il tiling della 
    texture. 
    Vediamo il risultato 
    con il seguente esempio: 
    
    Come si puo' vedere abbiamo 
    ora quattro copie della Gioconda mappate sul piano. Una tale operazione puo' 
    essere molto utile quando dobbiamo mappare una texture che rappresenta un 
    certo materiale sopra una superficie molto grossa. Applicando la texture singola 
    a tutto l'oggetto si ha una dilatazione eccessiva che porta a dettagli molto 
    grossolani. 
    Fornendo valori maggiori 
    di 1 al campo scale si ottiene il rimpicciolimento della texture. Valori minori 
    di 1 (ma comunque maggiori di 0) realizzano invece un ingrandimento. 
    Vediamo ora brevemente 
    il funzionamento degli altri campi. 
    Qui di seguito riporto 
    due esempi; il primo riguarda una traslazione della texture, mentre l'altro 
    una rotazione effettuata attorno al centro. 
    Primo esempio: 
    
    Secondo esempio: 
    Direi che possiamo fermarci 
    a questo livello con le textures. Penso che abbiamo analizato grossomodo tutti 
    gli aspetti piu' importanti. Solo un ultimo appunto: non si possono avere 
    oggetti con diverse textures, a meno che l'oggetto stesso non sia definito 
    da piu' nodi Shape. 
    Rimando inoltre al tutorial 
    sull'uso di Vrml che trovate al sito: 
    http://www.ywd.com/cindy/texture.html 
    
    Questo e' molto piu' 
    completo del presente documento e presenta inoltre diversi esempi, nonche' 
    una introduzione per comprendere come effettivamente lavorano le textures 
    (che qui non riporto per motivi di spazio). 
   
  #VRML V2.0 utf8
#esempio di mapping su primitiva
Shape {
 appearance Appearance {
  material Material { diffuseColor 1 1 1 }
  texture ImageTexture { url "immagine.jpg" }
 }
 geometry Sphere { }
}
  
    Il mapping sulle primitive viene eseguito secondo certe modalita' di default. 
    In particolare, per la sfera l'immagine viene avvolta sull'intera superficie; 
    per il cilindro si avvolge l'immagine sulla superficie laterale e due copie 
    delle immagini sono mappate sulle due basi; per il cono si effettua un avvolgimento 
    sulla superficie laterale e si pone una copia sulla base; per la box si riporta 
    una copia dell'immagine per ogni faccia. 
  TextureTransform {
  exposedField  SFVec2f  center      0 0
  exposedField  SFFloat  rotation    0
  exposedField  SFVec2f  scale       1 1
  exposedField  SFVec2f  translation 0 0
}
  #VRML V2.0 utf8
# esempio texture 1
DirectionalLight {
 direction 0 -1 -1
}
NavigationInfo {
 headlight FALSE
}
Viewpoint {
 position 0 10 50
}
Shape {
 appearance Appearance {
  material Material { diffuseColor 1 1 1 }
  texture ImageTexture { url "../textures/generali/gioconda.jpg" }
 }
 geometry IndexedFaceSet {
  coord Coordinate {
   point [ -10 0 0, 10 0 0, 10 20 0, -10 20 0 ]
  }
  coordIndex [0,1,2,3,-1]
 }
}
  Shape {
  appearance Appearance {
   material Material { diffuseColor 1 1 1 }
   texture ImageTexture { url "../textures/generali/gioconda.jpg" }
  }
  geometry IndexedFaceSet {
   coord Coordinate {
    point [ -10 0 0, 10 0 0, 10 25 0, -10 25 0 ]
   }
   coordIndex [0,1,2,3,-1]
   texCoord TextureCoordinate {
    point [0 0, 1 0, 1 1, 1 0]
   }
   texCoordIndex [0,1,2,3,-1]
  }
}
  Shape {
  appearance Appearance {
   material Material { diffuseColor 1 1 1 }
   textureTransform TextureTransform {
    scale 2 2 
   }
   texture ImageTexture { url "../textures/generali/gioconda.jpg" }
  }
  geometry IndexedFaceSet {
   coord Coordinate {
    point [ -10 0 0, 10 0 0, 10 25 0, -10 25 0 ]
   }
   coordIndex [0,1,2,3,-1]
   texCoord TextureCoordinate {
    point [0 0, 1 0, 1 1, 1 0]
   }
   texCoordIndex [0,1,2,3,-1]
  }
}
    TextureTransform {
                  translation .5 0
                }
   TextureTransform {
                    center .5 .5
                    rotation 1.57
                  }