Sistemi multimediali
Massimiliano Piscozzi – [email protected]
Definizione di nuovi nodi
• E’ possibile definire nuovi tipi di nodo a partire da nodi
esistenti (built-in o definiti dall’utente)
Zero o più campi:
PROTOTYPE
Uno o più nodi:
– Nome
– Nome
– Interfaccia
– Corpo
– Deve esistere un
nodo radice
– Tipo
– Tipo di accesso
(input/output per il
routing degli eventi)
– Valori di default
– Il nodo radice
determina quando
il prototipo può
essere istanziato
 A differenza di USE il prototipo può possedere dei campi il cui
valore può variare per ogni istanza
Esempio di prototipo
• Prototipo “Colonna” caratterizzato da un colore e un raggio
Colonna
Transform
children
·· ·
Shape
geometry
appearance
·· ·
raggio
colore
Cylinder
Appearance
radius
material
·· ·
·· ·
Material
diffuseColor
·· ·
Prototipi (1)
• Codifica in XML della dichiarazione di prototipi
<ProtoDeclare name=“nomePrototipo”>
<ProtoInterface>
...
</ProtoInteface>
<ProtoBody>
...
</ProtoBody>
</ProtoDeclare>
Interfaccia costituita da campi
<field name=“...” type=“...”
accessType=“...” value=“...”/>
Corpo costituito da dichiarazioni di nodi
- Il collegamento tra i campi dei nodi e i
campi dell’interfaccia avviene
attraverso i tag <IS> e <connect>
<unNodo>
<IS>
<connect nodeField=“...”
protoField=“...”/>
</IS>
</unNodo>
Prototipi (2)
• Codifica in XML della creazione di istanze di un prototipo
<ProtoInstance name=“nomePrototipo”>
...
</ProtoInstance>
Lista dei valori dei campi
<fieldValue name=“...” value=“...”/>
 Se il valore di un campo non viene specificato esso assume il
valore di default (specificato nell’interfaccia o in base alle
specifiche X3D)
Prototipi: esempio
<ProtoDeclare name="Colonna">
<ProtoInterface>
<field name="raggio" accessType="inputOutput"
type="SFFloat" value="0.3"/>
<field name="colore" accessType="inputOutput"
type="SFColor" value="0.8 0.7 0.3"/>
</ProtoInterface>
<ProtoBody>
<Transform translation="0 1.25 0">
<Shape>
<Cylinder height="2.5">
<IS>
<connect nodeField="radius" protoField="raggio"/>
</IS>
</Cylinder>
<Appearance>
<Material diffuseColor="0.8 0.7 0.3">
<IS>
<connect nodeField="diffuseColor" protoField="colore"/>
</IS>
</Material>
</Appearance>
</Shape>
</Transform>
</ProtoBody>
</ProtoDeclare>
<ProtoInstance name="Colonna"/>
<ProtoInstance name="Colonna">
<fieldValue name="colore" value="0 0 2"/>
</ProtoInstance>
<ProtoInstance name="Colonna">
<fieldValue name="raggio" value="0.1"/>
</ProtoInstance>
<ProtoInstance name="Colonna">
<fieldValue name="colore" value="0 0 2"/>
<fieldValue name="raggio" value="0.1"/>
</ProtoInstance>
Prototipi (3)
• La definizione di un prototipo può essere contenuta in un
file diverso da quello in cui vengono create le istanze
File A
File X3D-XML contenente
la dichiarazione
di uno o più prototipi
File B
File X3D-XML contenente
la dichiarazione
di uno o più prototipi
File C
File X3D-XML contenente
la dichiarazione
di uno o più prototipi
File D
File X3D-XML che
utilizza istanze di
prototipi definiti
esternamente
 Maggiore riusabilità dei nodi definiti dall’utente
 Semplificazione nella scrittura dei file X3D-XML
ExternProtoDeclare
• La dichiarazione di un prototipo definito esternamente
avviene attraverso il tag ExternProtoDeclare
<ExternProtoDeclare name=“...” url=“...”/>
Indirizzo del file in cui è
definito il prototipo + nome
del prototipo:
nomeFile#nomePrototipo
Nome utilizzato localmente
per la creazione di istanze
del prototipo
• Esempio
FileA.x3d
...
<ProtoDeclare name=“oggetto”>
<ProtoInterface>
...
</ProtoInterface>
<ProtoBody>
...
</ProtoBody>
</ProtoDeclare>
...
FileB.x3d ...
<ExternProtoDeclare
name=“oggettoEsterno”
url=“FileA.x3d#oggetto”/>
...
<ProtoInstance name=“oggettoEsterno”>
...
</ProtoInstance>
...
Scripting
• Uno script:
– E’ un nodo facente parte dello scene graph
– Contiene un “comportamento” definito attraverso funzioni scritte
in ECMAScript
– Può generare eventi
• L’utilizzo di scripts permette di:
– Programmare comportamenti più evoluti rispetto a quelli ottenibili
tramite i nodi predefiniti (ex: pulsanti a più stati)
– Definire matematicamente delle traiettore (ex: parabole, ellissi)
– Automatizzare comportamenti (ex: creazione di un gran numero
di istanze di un oggetto)
– Convertire eventi (ex: rollOver button)
– Modificare dinamicamente lo scene graph e il behaviour graph
– ...
Nodo Script
<Script>
...
Interfaccia costituita da campi
<field name=“...” type=“...”
accessType=“...” value=“...”/>
<![CDATA[
...
]]>
</Script>
Funzioni definite in ECMAScript
<![CDATA[
ecmascript:
...lista funzioni...
]]>
• Per gestire gli eventi in input occorre definire delle funzioni
associate ai campi InputOnly o InputOutput
• Per spedire degli eventi associati ai campi OutputOnly o InputOutput
è sufficiente modificarne i valori all’interno delle funzioni
ECMAScript (1)
• Variabili
– Linguaggio debolmente tipizzato
– Tipi predefiniti:
boolean, number, string, object, ...
var a;
a = 5;
print(a);
a = ‘Hello World!’
print(a);
• Operatori
–
–
–
–
Unari: ! (NOT), -, ++ (incremento), -- (decremento)
Binari: +, - ,* ,/ ,% (modulo)
Relazionali: <, >, <=, >=, ==, !=
Logici: && (AND), || (OR)
• Strutture di controllo
– Condizionali: if..else, switch
– Iterative: for, while, do..while
if (condition) {
statements
}
else {
statements
}
switch (expr) {
case label:
statements
break;
...
default:
statements
}
for (expr1; epr2; expr3) {
statements
}
while (condition) {
statements
}
do {
statements
} while (condition)
ECMAScript (2)
• Funzioni
– Non occorre specificare il tipo del valore restituito
function myFunction(parameters) {
...
}
function somma(a,b) {
return (a+b);
}
• Oggetto Array
– Array dinamico costituito da elementi di qualsiasi tipo
– Proprietà: length
var a = new Array();
a[0] = 4;
a[1] = ‘BlaBlaBla’;
for (i=0; i < a.length; i++) {
print(a[i]);
}
• Oggetto Math
– Oggetto globale: non va istanziato tramite new
– Costanti matematiche (proprietà): PI, E, SQRT2, LN2, LN10, ...
– Funzioni matematiche (metodi): max(), min(), pow(), sqrt(),
sin(), cos(), tan(), random()
ECMAScript (3)
• ECMAScript e nodi “Script” (X3D)
– I tipi di dato booleani (SFBool), scalari (SFFloat, SFDouble,
SFInt32, SFTime) e le stringhe (SFString) sono rappresentati
attraverso i tipi base di ECMAScript (boolean, number, string)
– I restanti tipi di dato “singoli” (SFColor, SFVec3f, ...) sono
rappresentati attraverso degli oggetti
• Ex: verde = new SFColor(0,1,0);
• Ex: origine = new SFVec3f(0,0,0);
– I tipi di dato “multipli” (MFInt32, MFVec3f, ...) sono rappresentati
attraverso degli array
• Ex: v = new MFInt32(2,5,1,-3);
ECMAScript (4)
• ECMAScript e nodi “Script” (X3D)
– Per ogni campo di tipo InputOnly e InputOutput bisogna definire una
funzione con lo stesso nome
– E’ possibile definire due funzioni richiamate quando lo script è
caricato o eliminato dal Browser: initialize() e shutdown()
– La funzione print() permette di scrivere sulla console (debug)
– Tramite l’oggetto globale Browser() è possibile modificare
dinamicamente lo scene graph e il behaviour graph
• Browser.createFromVRMLString(stringVRML)
• Browser.addRoute(fromNode,fromField,toNode,toField)
• Browser.deleteRoute(fromNode,fromField,toNode,toField)
Script: esempio
• Movimento sinusoidale di un cubo
TimeSensor
Script
Transform
cycleInterval
set_fraction
translation
loop
value_changed
·· ·
fraction_changed
·· ·
·· ·
<Script DEF="MyScript">
<field name="set_fraction" type="SFFloat" accessType="inputOnly"/>
<field name="value_changed" type="SFVec3f" accessType="outputOnly"/>
<![CDATA[
ecmascript:
function initialize() {
print(‘Script inizializzato!’);
}
set_fraction(value)
oppure
set_fraction(value, timestamp)
function set_fraction(value) {
value_changed[0] = -3 + 6 * value;
value_changed[1] = 2 * Math.Sin(value*6.28);
value_changed[2] = 0;
}
]]>
</Script>
Esempio (1)
• Creazione di un prototipo di un pulsante a due stati
– Lo stato del pulsante deve essere rappresentato dal suo colore
(variazione del diffuseColor)
– Il pulsante deve illuminarsi al passaggio del mouse (variazione
dell’emissiveColor)
– Il pulsante può avere forme diverse
Button
Transform
·· ·
Shape
·· ·
geometry
TouchSensor
Appearance
·· ·
isOver
Script
touchTime
isOver
·· ·
touchTime
emissiveColor
diffusionColor
Sphere
·· ·
Material
diffuseColor
emissiveColor
·· ·
·· ·
Esempio (2)
• Dichiarazione del
prototipo
• Connessione del
campo geometry del
prototipo
<ProtoDeclare name=“Button”>
<ProtoInterface>
<field name="geometry" type="SFNode" accessType="inputOnly">
<Sphere/>
</field>
</ProtoInterface>
Campo costituito da un nodo:
<ProtoBody>
il valore di default non viene
...
specificato nell’attributo value,
</ProtoBody>
ma attraverso un tag innestato
</ProtoDeclare>
...
<Shape>
<Appearance>
<Material DEF=“materialButton”>
</Appearance>
<IS>
<connect nodeField="geometry" protoField="geometry"/>
</IS>
</Shape>
...
Esempio (3)
<Script DEF="MyScript">
• Nodo Script
<field name="isOver" type="SFBool"
accessType="inputOnly"/>
<field name="touchTime" type="SFTime"
accessType="inputOnly"/>
<field name="state" type="SFBool"
accessType="inputOutput"/>
<field name="emissiveColor_changed" type="SFColor"
accessType="outputOnly"/>
<field name="diffuseColor_changed" type="SFColor"
accessType="outputOnly"/>
<![CDATA[
ecmascript:
...
]]>
</Script>
Esempio (4)
function state(value) {}
• Funzioni definite
all’interno del nodo
Script
function touchTime(value) {
state = !state;
if (state) {
diffuseColor_changed = new SFColor(1, 0.2, 0.5);
}
else {
diffuseColor_changed = new SFColor(0.2, 1, 0.5);
}
}
function isOver(value)
{
if (value) {
emissiveColor_changed = new SFColor(0.2, 0.2, 0.2);
}
else {
emissiveColor_changed = new SFColor(0, 0, 0);
}
}
Esempio (5)
• Routing degli eventi
all’interno di
<ProtoBody>
• Creazione di istanze
del prototipo
<ROUTE fromNode="Sensor" fromField="isOver"
toNode="MyScript" toField="isOver"/>
<ROUTE fromNode="Sensor" fromField="touchTime"
toNode="MyScript" toField="touchTime"/>
<ROUTE fromNode="MyScript" fromField="emissiveColor_changed"
toNode="MaterialButton" toField="set_emissiveColor"/>
<ROUTE fromNode="MyScript" fromField="diffuseColor_changed"
toNode="MaterialButton" toField="set_diffuseColor"/>
<ProtoInstance name="button">
<fieldValue name="geometry">
<Box/>
</fieldValue>
</ProtoInstance>
Campo costituito da un nodo:
il valore di default non viene
specificato nell’attributo value,
ma attraverso un tag innestato
Scarica

pps