6 - Animação,
Orientação e Escala
VRML permite um grande
número de animações, que podem ser disparadas por aproximações e toques.
Tais animações fazem
as formas se movimentarem baseadas num dado tempo, que, é controlado
por um relógio com tempos fracionados em números reais.
As frações de tempo
devem ser associadas a quadros que contêm as posições chaves da animação,
dando a noção de movimento da forma.
Para
adicionar movimento a seu mundo, você pode animar a posição,
a orientação e a escala de qualquer sistema de coordenadas.
Uma animação
requer três elementos:
Um
elemento de tempo (crônometro) usado para iniciar, parar e
controlar uma animação (TimeSensor);
A descrição
de como alguma coisa altera-se ao longo do tempo da animação
(PositionInterpolator, OrientationInterpolation, ...).
Um
elemento para estabelecer a ligação entre os nós acima (Route)
Exemplo 48: Animação 1
#VRML V2.0 utf8
Group {
children [
DEF Cubo Transform {
children Shape {
appearance Appearance {
material Material { }
}
geometry Box { size 1.0 1.0 1.0 }
}
},
DEF Tempo TimeSensor {
cycleInterval 4
loop TRUE
},
DEF Caminho PositionInterpolator {
key [ 0.00, 1.00 ]
keyValue [ -4 0 0, 4 0 0 ]
}
]
}
ROUTE Tempo.fraction_changed TO Caminho.set_fraction
ROUTE Caminho.value_changed TO Cubo.set_translation
Os Interpoladores são
nós muito importantes para fazer animação. Eles são utilizados para
animar outros nós por meio de interpolação linear. Em termos práticos,
os interpoladores são usados para alterar um determinado valor ao
longo do tempo. Dependendo do tipo de valor que se pretende alterar,
existem seis interpoladores diferentes, mas com o funcionamento muito
semelhante.
| Tipo de interpolador |
Para interpolar |
|
PositionInterpolator |
posições (translações) |
|
OrientationInterpolator |
orientações (rotações) |
|
ScalarInterpolator |
valores
escalares |
|
ColorInterpolator |
cores |
|
CoordinateInterpolator |
coordenadas de pontos |
|
NormalInterpolator |
normais
a superfícies |
6.1 - Eventos
Um evento é uma mensagem
enviada de um nó para outro. Existem dois tipos de eventos:
os eventos de entrada (eventIn),
e
os eventos de saída (eventOut).
Um evento
de entrada corresponde à recepção por um nó receptor de uma
mensagem (evento) enviada por um nó emissor, para que o nó receptor
altere o seu estado.
Um evento
de saída é uma mensagem emitida por um nó emissor. A mensagem
destina-se a notificar o nó receptor (ou nós receptores) de que o
estado do nó emissor foi alterado.
Por norma, os nomes
dos eventos de entrada devem ter o prefixo set_,
pois implicam uma alteração do estado do nó (set_position, set_color,
...);
os nomes dos
eventos de saída devem ter o sufixo _changed,
pois traduzem a alteração do estado (position_changed, color_changed,
...).
ROUTE Tempo.fraction_changed TO Caminho.set_fraction
ROUTE Caminho.value_changed TO Cubo.set_translation
Em geral, todos os
campos são privados e não podem ser alterados, mas os campos expostos
(exposedField) são «públicos»
e podem ser manipulados por outros nós exteriores.
Estes campos especiais
aliam as características dos campos e dos eventos, associando dois
eventos (um de entrada e outro de saída) ao campo. Assim, por exemplo:
exposedField SFColor color
é equivalente a:
field SFColor color
eventIn SFColor set_color
eventOut SFColor color_changed
6.2.
Nós de ligação - Rotas
De modo a estabelecer
uma ligação entre o nó que gera o evento e o nó que o recebe, existe
um elemento especial do VRML designado por ROUTE,
que não é um nó no sentido comum desta designação.
Só é permitido estabelecer
ligações ROUTE de um
evento de saída para um evento de entrada (unidireccional) quando
ambos são do mesmo tipo.
Por exemplo:
ROUTE NodeName.eventOutName_changed TO NodeName.set_eventInName
ROUTE Tempo.fraction_changed TO Caminho.set_fraction
ROUTE Caminho.value_changed TO Cubo.set_translatio
6.3.
Sensores
Sensores são nós que
geram eventos baseados na interação do utilizador com a cena, ou com
a passagem do tempo. Existem vários tipos de sensores em VRML:
-
ProximitySensor:
detecta quando o utilizador navega dentro de uma área invisível
mais específica do mundo;
-
VisibilitySensor:
detecta quando uma parte específica da cena se torna visível para
o utilizador;
-
TimeSensor: é um relógio sem geometria ou localização
associada, usado para iniciar ou finalizar nós dependentes do tempo;
-
Sensores
de seleção: detectam eventos
de selecção gerados pelo utilizador, tais como a ativação de um
objeto geométrico ao clicar-lhe. São exemplos deste tipo de sensores: CylinderSensor,
PlaneSensor,
SphereSensor e TouchSensor.
Cada tipo de sensor
define qual o momento de geração do evento, podendo ser ativado ou
desativado através do campo enabled.
6.4 -
A sintaxe do nó TimeSensor
A interação
nos mundos VRML é feita com a utilização de sensores.
6.4.1
- TimeSensor
TimeSensor - nó responsável pelo controle de tempos, funciona como
um cronômetro. Gera eventos de saída ao longo do tempo, tanto de natureza
discreta como de natureza contínua. Não possue posição ou geometria.
Sua sintaxe é:
TimeSensor
{
......cycleInterval 1
......enabled TRUE
......loop FALSE
......startTime 0
......stopTime 0
......cycleTime
......fraction_changed
......isActive
......time
}
cycleInterval
- especifica a duração do laço em segundos.
enabled
TRUE - liga/desliga o nó sensor.
loop
- repete indefinidamente quando loop=true, repete somente uma vez
quando loop=false.
startTime
- especifica quando o TimeSensor começa o evento.
stopTime
- especifica quando o TimeSensor para o evento.
cycleTime
- determina o tempo de cada ciclo.
O tempo
é sempre uma fração do valor máximo (que
é sempre 1.0).

O nó
TimeSensor por si é incapaz de promover a animação.
A associação do mesmo com nós que controlam posição,
orientação e escala é essencial.
Exemplo:
DEF Tempo TimeSensor {
cycleInterval 4
loop TRUE
}
6.5
- Interpoladores
6.5.1
- Interpolação linear
Os
nós PositionInterpolator, OrientationInterpolation,
ScalarInterpolator,
ColorInterpolator,
CoordinateInterpolator
e NormalInterpolator usam
interpolação linear para computar valores intermediários entre os
valores chaves que você fornece.
Deve-se usar um interpolador
quando se pretende que um determinado valor varie ao longo do tempo.
Os interpoladores recebem sinais temporais gerados por um TimeSensor
ou equivalente, e realizam uma interpolação linear entre conjuntos
de valores designados por keyValues.
Um interpolador define
uma função linear através de n valores de tempo t, designados
por key, e de n valores
correspondentes a f(t), chamados keyValue.
Os campos key e keyValue
são campos expostos de todos os interpoladores.
6.5.2
- PositionInterpolator
PositionInterpolator
- nó que controla a posição em função de uma fração do tempo. Usado
para animar objetos movendo eles por um caminho especificado. O
nó PositionInterpolator está
associado à translação de nós geométricos.
Sua sintaxe é:
PositionInterpolator
{
......set_fraction
......key []
......keyValue []
......value_changed
}
key []
- lista de tempos fracionais
chaves - Lista de instantes de tempos
keyValue
[] - especifica o caminho para a animação - lista de posições chaves
- cada uma composta por X,Y,Z.
Para cada valor keyValue
existe um
key, que varia entre 0 e 1. Os n valores de key têm
de ser não decrescentes. O TimeSensor gera
fraction_changed eventos regularmente. Estes podem ser canalisados
para um set_function de um
interpolador para definir o valor correto no ciclo de interpolação.
Assim, se tivermos um TimeSensor com um cycleInterval
de 10, ligado a um interpolador, este irá passando de key em
key, e avaliando f(t), de 10 em 10 segundos. O resultado da avaliação
é enviado para o exterior através do evento value_changed
(do mesmo tipo de keyValue). Deste
modo, cada vez que um interpolador recebe um evento de entrada, gera
um evento de saída com o valor interpolado correspondente. Este valor
pode depois ser canalisado para qualquer nó, para alterar valores
do mesmo tipo.
Exemplo:
DEF Caminho PositionInterpolator {
key [ 0.00, 1.00 ]
keyValue [ -4 0 0, 4 0 0 ]
}
Exemplo 49: Animação 2
#VRML V2.0 utf8
Group {
== children [
== == DEF Cubo Transform {
== == == children Shape {
== == == == appearance Appearance {
== == == == == material Material { }
== == == == }
== == == == geometry Box { size 1.0 1.0 1.0 }
== == == }
== == },
== == DEF Tempo TimeSensor {
== == == cycleInterval 4
== == == loop TRUE
== == },
== == DEF Caminho PositionInterpolator {
== == == key [
== == == == 0.00, 0.25, 0.75, 1.00
== == == ]
== == == keyValue [
== == == == 0 0 0, 4 0 0, -4 0 0, 0 0 0
== == == ]
== == }
== ]
}
ROUTE Tempo.fraction_changed TO Caminho.set_fraction
ROUTE Caminho.value_changed TO Cubo.set_translation