• Nenhum resultado encontrado

VRML Virtual Reality Modeling Language

N/A
N/A
Protected

Academic year: 2021

Share "VRML Virtual Reality Modeling Language"

Copied!
16
0
0

Texto

(1)

VRML

Virtual Reality Modeling Language

PRIMITIVAS AVANÇADAS III

Atualizada por Baseada na apresentação de:

Paulo Gonçalves de Barros, Dênio Mariz Judith Kelner Alejandro Frery

2

Roteiro

1.

O que é VRML

2.

Histórico

3.

Objetivos da VRML

4.

VRML, Internet e WWW

5.

Visão geral do VRML

6.

Estrutura do Arquivo VRML

7.

Conceitos-chave

8.

Semântica dos Nós

9.

Primitivas Básicas

10.

Primitivas Avançadas

Aí está o roteiro da apresentação. Como na aula passada, continuaremos de ver

primitivas avançadas. A aula provavelmente será mais curta que o normal,

deixando bastante tempo para vocês adiantarem as listas atrasadas e fazer a lista

número 5.

(2)

3

3

Informações Adicionais

„ Exercícios

„ Transparências

http://www.cin.ufpe.br/~if687/calendario.htm

„ Dúvidas

masb@cin.ufpe.br

Lembrando mais uma vez: os arquivos, tanto de exercícios quanto as

transparências estarão nesse endereço aí. Se vocês tiverem dúvidas (de projeto ou não) é só mandar um e-mail ou tirar em tempo real aqui na aula mesmo.

**Atualizar endereço onde os arquivos estão e e-mail para se tirar dúvidas!

4

4

Primitivas Avançadas

„ Group

„ Transform

„ Viewpoint

„ Anchor

„ Inline

„ Proto

„ Extern Proto

„ WorldInfo

„ Background

„ Panorama

„ Fog

„ IndexedFaceSet

„ IndexedLineSet

„ PointSet

„ Extrusion

„ Elevation Grid

„ Billboard

„ DirectionalLight

„ PointLight

„ SpotLight

„ Sound

„ AudioClip

„ NavigationInfo

„ TimeSensor

„ VisibilitySensor

„ ProximitySensor

„ Collision

„ TouchSensor

„ SphereSensor

„ CylinderSensor

„ PlaneSensor

„

ColorInterpolator

„

CoordinateInterpolator

„

NormalInterpolator

„

OrientationInterpolator

„

PositionInterpolator

„

ScalarInterpolator

„

Bindable

„

Script

„

Switch

„

LOD

Bem aqui está o assunto da aula mais detalhadamente. Percebam que não é muito o que veremos hoje. Já vimos todos os tópicos em cinza.

O que veremos serão apenas os dois tópicos em verde. São eles as primitivas avançadas:

•ColorInterpolator;

•CoordinateInterpolator;

•NormalInterpolator;

•OrientationInterpolator;

•PositionInterpolator;

•ScalarInterpolator;

•LOD;

•Bindable;

•Switch;

•Script

.

(3)

5

„ Modificam valores de campos ao longo do tempo

„ Funcionamento

Î O interpolator acompanha os ciclos do TimeSensor.

Î Interpolator recebe valor de Fraction_changed de um TimeSensor

Î Esse valor define o estágio em que o ciclo do interpolator se encontra.

Î O interpolator emite um valor final para o campo sendo alterado por ele.

Dando vida a objetos - Interpolators

TimeSensor fraction_changed

Interpolator value_changed set_fraction

Nó do objeto set_...

Os nós de interpolação tem como função variar um campo de um nó gradativamente entre dois valores. Esses campos podem afetar a posição, orientação, escala, normais, etc. Enfim, os interpoladores são a forma mais simples de animar seu mundo independentemente do que o usuário faça. Os tipos de nós interpolator são:

•ColorInterpolator;

•CoordinateInterpolator;

•NormalInterpolator;

•OrientationInterpolator;

•PositionInterpolator;

•ScalarInterpolator.

O funcionamento dos nós interpoladores é basicamente o seguinte:

•O Interpolator recebe o valor de fraction_changed de um TimeSensor;

•Esse valor define o estágio em que o interpolator se encontra na mudança de um valor inicial para o final;

•O interpolator emite o valor atual para o campo do nó que está sendo modificado.

Um fato importante a ser observado é o de que o interpolator acompanha os ciclos do TimeSensor. Ele leva um ciclo de relógio para completar a mudança de valor do campo.Outro ponto interessante a ser ressaltado é o de que, pelo fato de eles funcionarem dependentes apenas de suas entradas e saídas, podem ser postos em qualquer local do código sem afetar seu funcionamento.

6

„ Estrutura básica:

Î

eventIn SFFloat set_fraction: valor recebido do TimeSensor

Î

exposedField MFFloat key: seqüência de percentuais do tempo total indicando quando cada valor de interpolação ocorrerá.

Î

exposedField ? keyValue: valores de interpolação em si

Î

eventOut ? value_changed: valor enterpoladao a ser

passado para o campo do nó.

Dando vida a objetos - Interpolators

Variação de valores do campo (ex.: rotação) Percentual de interpolação

Tempo decorrido

0 s 5 s 10 s 15 s

0 0,25 0,5 0,75 1,0

0 1.57 3.14 4.71 6.28

Fraction_changed

Keys KeyValues 21.8% = 0.218

0.218

1.32 Value_changed

Os nós de interpolação possuem a mesma estrutura básica, variando apenas os tipos e a quantidade de valores passados como resultado.

Essa estrutura é formada pelos seguintes campos:

Set_fraction: valor recebido do TimeSensor que serve como medida do andamento (percentual concluído) da interpolação;

Key: seqüência de percentuais do tempo de interpolação indicando quando cada valor chave da interpolação deverá ocorrer.

KeyValue: valor de interpolação em si associado a cada percentual definido em Key;

Value_changed: valor interpolado a ser passado para o campo do nó.

(4)

7

7

#VRML V2.0 utf8

DEF mySensorTimeSensor {cycleInterval30loopTRUE} DEF myInterpolatorColorInterpolator {

key [0, 0.33, 0.66, 1]

keyValue [ 1 0 0, 0 1 0, 0 0 1, 1 0 0] } Shape {

appearance Appearance {

material DEF myIntTarget Material {emissiveColor1 0 0} } geometry Box { } }

ROUTE mySensor.fraction_changed TO myColorInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_emissiveColor

„ ColorInterpolator {

eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFColor keyValue []

eventOut SFColor value_changed }

Alterando Cor - ColorInterpolator

Valores iguais garantem continuidade entre ciclos

Esse é colorInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed são, contudo, cores:

•SFColor: única cor;

•MFColor: lista de cores.

Abaixo temos um exemplo de um cubo que muda de cor ao longo do tempo.

8

8

„

CoordinateInterpolator {

eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFVec3f keyValue []

eventOut MFVec3f value_changed }

Alterando Vértices - CoordinateInterpolator

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval30loopTRUE } DEF myInterpolatorCoordinateInterpolator{

key [0, 0.2, 0.4, 0.6, 0.8, 1]

keyValue [1 1 0,-1 1 0,-1 -1 0,1 -1 0,2 2 0,-2 2 0,-1 -1 0,1 -1 0 3 3 0,-3 3 0,-2 -2 0,2 -2 0,2 2 0,-2 2 0,-3 -3 0,3 -3 0 1 1 0,-1 1 0,-2 -2 0,2 -2 0,1 1 0,-1 1 0,-1 -1 0,1 -1 0]}

Shape {geometry IndexedFaceSet {

coord DEF myIntTargetCoordinate {point[1 1 0,-1 1 0,-1 -1 0,1 -1 0]}

coordIndex [0 1 2 3 -1] } }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_point

Valores iguais garantem continuidade entre ciclos

Esse é coordinateInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed são, contudo, listas de coordenadas de pontos:

O exemplo abaixo mostra um quadrado que se estica ao longo do

tempo.

(5)

9

„ NormalInterpolator {

eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFVec3f keyValue []

eventOut MFVec3f value_changed }

Alterando Normais - NormalInterpolator

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval 30 loop TRUE } DEF myInterpolatorNormalInterpolator{

key [0, 0.25, 0.5, 0.75, 1]

keyValue [0 0 1,0 1 0, 0 0 -1,0 -1 0,0 1 0, 0 0 -1, 0 -1 0, 0 0 1, 0 0 -1, 0 -1 0, 0 0 1, 0 1 0,0 -1 0, 0 0 1, 0 1 0, 0 0 -1, 0 0 1, 0 1 0, 0 0 -1,0 -1 0] }

Shape {appearance Appearance {material Material {diffuseColor1 0 0}}

geometry IndexedFaceSet {

coord Coordinate {point[1 1 0,-1 1 0,-1 -1 0,1 -1 0]}

coordIndex [0 1 2 3 -1]

normal DEF myIntTargetNormal{vector[0 0 1,0 0 -1,0 1 0 ,0 -1 0]}

normalPerVertex TRUE normalIndex [ 0 1 2 3 -1] } }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_vector

Valores iguais garantem continuidade entre ciclos

Esse é normalInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed são, contudo, listas de coordenadas de normais de pontos:

O exemplo abaixo mostra um quadrado que muda as normais de seus vértices ao longo do tempo.

10

„ OrientationInterpolator { eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFRotation keyValue []

eventOut SFRotation value_changed }

Alterando Orientação - OrientationInterpolator

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval30loopTRUE}

DEF myInterpolatorOrientationInterpolator{

key [0, 0.25, 0.5, 0.75, 1]

keyValue [1 1 0 0,1 1 0 1.57,1 1 0 3.14,1 1 0 4.71,1 1 0 6.28] } DEF myIntTargetTransform {

children Shape {

appearance Appearance {material Material {diffuseColor1 1 1} } geometry Cone {} } }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_rotation

Valores diferentes, mas com rotações relativas iguais garantem a continuidade entre ciclos

Esse é orientationlInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed é, contudo, um vetor de rotação:

O exemplo abaixo mostra um cone que muda sua rotação ao longo do

tempo.

(6)

11

11

„ PositionInterpolator {

eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFVec3f keyValue []

eventOut SFVec3f value_changed }

Alterando Posição- PositionInterpolator

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval10loop TRUE} DEF myInterpolatorPositionInterpolator{

key [0, 0.2, 0.4, 0.6, 0.8, 1]

keyValue [0 0 0,1 0 0,0 1 0,-1 0 0,0 -1 0, 0 0 0] } DEF myIntTargetTransform {

children Shape {

appearance Appearance {material Material {diffuseColor1 1 1} } geometry Cylinder {} } }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_translation

Valores iguais garantem continuidade entre ciclos

Esse é positionlInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed é, contudo, um vetor de translação:

O exemplo abaixo mostra um cilindro que muda sua translação ao longo do tempo.

12

12

„ ScalarInterpolator {

eventIn SFFloat set_fraction exposedField MFFloat key []

exposedField MFFloat keyValue []

eventOut SFFloat value_changed }

Alterando Escalares - ScalarInterpolator

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval5loopTRUE} DEF myInterpolatorScalarInterpolator{

key [0, 0.5, 1]

keyValue [0, 0.9, 0] }

Shape {geometry Box {size3 3 0.1} } Shape {appearance Appearance {

material DEF myIntTargetMaterial {diffuseColor0 1 1} } geometry Sphere {} }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_transparency

Valores iguais garantem continuidade entre ciclos

Esse é scalarlInterpolator. Como todos os outros interpoladores, possui os quatro campos acima descritos. O conteúdo de keyValue e value_changed é, contudo, um número escalar. Esse número pode ser utilizado para variar transaprência de um objeto, intensidade de uma luz, etc. É possível utilizá-lo também para gerar funções lineares baseadas no tempo do TimeSensor, como f = 1/t (t = tempo emitido pelo timeSensor). Ainda, é possível gerar grosseiramente funções periódicas, como a seno, cosseno, etc.

O exemplo abaixo mostra um cone que muda sua rotação ao longo do

tempo.

(7)

13

„ Alteram o estado do mundo

„ Organizados em pilhas

„ Somente o de cima da pilha é utilizado para alterar o mundo. São eles:

Î Background Î Fog

Î NavigationInfo Î Viewpoint

„ Utilidades

Î Mudança do avatar e da navegação do usuário Î Mudança do ambiente do mundo (nível de

neblina, cores de background)

Î Movimentar usuário entre pontos de vista

Nós de Atuação Singular - Bindable

Bindable nodes são nós que alteram o estado do mundo.

Apenas um deles atua por vez. Para saber de quem é a vez de atuar, eles são organizados em pilhas. Somente o de cima da pilha é utilizado para alterar o mundo. Os nós bindable são os seguintes tipos:

•Background

•Fog

•NavigationInfo

•Viewpoint

Esses nós são muito úteis pois permitem a mudança do avatar e da navegação do usuário, a mudança do ambiente do mundo (nível de neblina, cores de background, etc) e ainda movimentar usuário entre pontos de vista (estando eles em movimento ou não).

14

„ Funcionamento

Î Nó ativado (bound) vai para cima da pilha

• Recebe TRUE em set_bind

• Emite TRUE em isBound

Î Nó anteriormente ativado fica embaixo

• Emite FALSE em isBound

Î Set_bind = FALSE remove nó da pilha. Se for o ativado:

• Emite FALSE em isBound

• É removido da pilha

• Nó abaixo é ativado

Nós de Atuação Singular - Bindable cont.

O funcionamento de nós bindable se dá da seguinte forma:

•Quando um nó é ativado, ele vai para cima da pilha. Isso é feito configurando o valor de seu campo set_bind para TRUE. Sendo ativado, o nó emite o valor TRUE no eventOut isBound. O nó anteriormente ativado é desativado e fica na pilha embaixo do nó que foi ativado. Esse, emite o valor FALSE no eventOut isBound.

•Se um nó tem seu valor de set_bind posto para FALSE, esse nó é removido da pilha. Se o nó que for removido tiver sido o que estava ativado, ele emite FALSE em no eventOut

isBound, é removido da pilha e o nó abaixo dele na pilha

passa a ser o nó ativado.

(8)

15

15

„ Exemplo:

Nós de Atuação Singular - Bindable cont.

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval5loopTRUE} Viewpoint { position0 0 10description "inicial"}

DEF myInterpolatorOrientationInterpolator{

key [0, 0.5, 1]

keyValue [0 1 0 0,0 1 0 3.14,0 1 0 6.28] } Shape { appearance Appearance {

material Material {diffuseColor0.8 0 0} } geometry Box {size5 0.1 5} }

DEF myIntTargetTransform { children [

DEF myTouchSensorTouchSensor {}

Shape {geometry Box {}}

DEF boxViewViewpoint {position0 3 0 orientation 1 0 0 -0.78

description "caixa"} ] }

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_rotation ROUTE myTouchSensor.isActive TO boxView.set_bind

Aqui temos um exemplo de uso do nó viewpoint como um nó bindable. Um cubo branco gira dentro de uma plataforma vermelha. O cubo branco é ligado a um touchSensor que, ao ser ativado ativa também um segundo viewpoint que passa a ser visão do usuário. Esse viewpoint está acoplado ao cubo branco, girando junto com ele.

Observe que, ao se soltar o botão do mouse, o viewpoint é posto para FALSE, removido da pilha, e o viewpoint anterior que estava abaixo e desativado é novamente ativado.

16

16

„ Script {

exposedField MFString url []

field SFBool directOutput FALSE Field SFBool mustEvaluate FALSE

#E mais quantos quiser desses campos:

eventIn Type? eventInName

field Type? fieldName default value?

eventOut Type? eventOutName }

„ Criação de um nó com quaisquer campos

„ Possbilita integração com linguagens como Javascript e Java

Inserindo código - Script

O nó script permite a criação de nó das mais diferentes formas.

Apesar de possuir três campos básicos e obrigatórios(url, directOutput e mustEvaluate), quaisquer outros podem ser inseridos para

complementar as características funcionais do nó que se deseja construir. Apesar de sua flexibilidade, o nó script não permite a criação de exposedFields dentro de sua estrutura. Em contrapartida, através desse nó é possível a integração de VRML com linguagens como Javascript e Java.

Os campos directOutput e mustEvaluate serão referenciados mais adiante nessa apresentação, mas não serão profundamente explicados.

Para mais informações consulte tutoriais na Web. Basicamente, o

mustEvaluate força o plug-in VRML a sempre avaliar o script e não

guardá-lo para avaliá-lo juntamente com outros de uma vez só. Já o

DirectOutput permite manipular diretamente com campo de nós, sem

utilizar passagem de eventos para isso. A utilização deles mais adiante

justificará melhor esses conceitos.

(9)

17

„ Exemplo:

Inserindo código - Script cont.

#VRML V2.0 utf8

DEF mySensorTimeSensor { cycleInterval5loopTRUE} DEF outViewViewpoint { position0 0 10description "inicial"}

DEF myInterpolatorOrientationInterpolator{key [0, 0.5, 1]

keyValue [0 1 0 0,0 1 0 3.14,0 1 0 6.28] }

Group { children [DEF myTouchSensor2TouchSensor {}

Shape { appearance Appearance {material Material {diffuseColor0.8 0 0} } geometry Box {size5 0.1 5} } ] }

DEF myIntTargetTransform { children [DEF myTouchSensorTouchSensor {}

Shape {geometry Box {}}

DEF boxViewViewpoint {position0 3 0orientation1 0 0 -0.78 description "caixa"} ] }

DEF myScriptScript { eventIn SFBool input eventOut SFBool output field SFBool boolValueTRUE

url "javascript: function input(value, time){

if(value==boolValue)output = TRUE;}"}

DEF myScript2Script { eventIn SFBool input eventOut SFBool output field SFBool boolValueTRUE

url "javascript:function input(value, time){

if(value==boolValue)output = TRUE;}"}

ROUTE mySensor.fraction_changed TO myInterpolator.set_fraction ROUTE myInterpolator.value_changed TO myIntTarget.set_rotation ROUTE myTouchSensor.isActive TO myScript.input

ROUTE myScript.output TO boxView.set_bind ROUTE myTouchSensor2.isActive TO myScript2.input ROUTE myScript2.output TO outView.set_bind

Bem, aqui temos um exemplo de uso do nós script, o exemplo é parecido com o feito para o nó bindable. A diferença é que não é necessário ficar com o botão pressionado do mouse para o viewpoint permanecer encima da caixa branca. Em contrapartida, um outro sensor foi acoplado à caixa vermelha. Esse ativa o viewpoint anterior toda vez que o usuário se sentir tonto e quiser uma visão externa e mais tranqüila.

18

„ Switch {

exposedField MFNode choice []

exposedField SFInt32 whichChoice -1 }

„ Diferentes representações para uma mesma entidade

„ Versões invisíveis continuam ativas

„ Como obter valores inteiros?

Mudança de Conteúdo – Switch

O nó Switch permite que um nó seja representado de diferentes formas, de acordo coma as necessidades do usuário. Basicamente, o nó possui uma lista de nós (campo choice) que são as N possíveis representações do nó no mundo. Todas elas estão presentes e ativas no mundo, mas só um delas realmente aparece. O campo

whichChoice possui o número X = N-1 referenciando o enésimo nó da lista (Ex.: para obter o 1º nó, X tem que ter valor 0). Os nós que não aparecem continuam ativados. Então, se existe um nó timeSensor dentro de um dos nós desativados do switch, ele continuará contando, mesmo que não apare

Para obter-se valores inteiros para inserir na whichChoice será

necessária a criação de scripts, como os que veremos no exemplo

seguinte.

(10)

19

19

„ Exemplo:

Mudança de Conteúdo – Switch cont.

#VRML V2.0 utf8 DEF myScriptScript {

eventIn SFTime touchTime field SFInt32 number4 eventOut SFInt32 output url "javascript:

function initialize() {output = 0;}

function touchTime(value, time) { if (output == number - 1) output = 0;

else ++output;}" } Group { children [

DEF mySensorTouchSensor {}

DEF mySwichSwitch { whichChoice0 choice [

Shape {geometry Box {}}

Shape {geometry Sphere {}}

Shape {geometry Cone {}}

Shape {geometry Cylinder {}} ] } ] } ROUTE mySensor.touchTime TO myScript.touchTime ROUTE myScript.output TO mySwich.whichChoice

Bem, aqui temos um exemplo de uso do nós switch. Nesse exemplo o switch varia sua forma entre as de um cubo, uma esfera, um cone e um cilindro. Para que fosse possível dar um movimento circular na escolhas das formas, fez-se necessário a inserção de um script, como pode ser visto para controlar o valor da posição de escolha da lista de nós do switch.

20

20

„ LOD {

exposedField MFNode level []

field SFVec3f center 0 0 0 field MFFloat range []

}

Níveis de Detalhe – LOD

#VRML V2.0 utf8 LOD {

range [10 20]

level [ Inline {url

"cadeiraBemDetalhada.wrl"}

Inline {url

"cadeiraDetalhada.wrl"}

Inline {url

"cadeiraSemDetalhes.wrl"}

] }

„ Diferentes

representações para uma mesma entidade

„ Mudança de

representações de acordo com distância do usuário

O nó LOD (do inglês Level of Detail) permite que um nó seja representado de diferentes formas como no nó switch. A diferença é que, nesse caso, a mudança se dá automaticamente de acordo com a distância entre o avatar do usuário e a localização do nó. A utilidade desse nó é permitir que versões com maior resolução (mais polígonos) só estejam presentes no mundo quando o usuário estiver mais perto e possa ver os detalhes apresentados. Quando os usuários estiverem longe, versões com menos detalhes e, conseqüentemente, com menos polígonos serão apresentadas.

Aqui ao lado , temos um exemplo de aplicação de LOD.

(11)

21

„ Linguagem oficial de VRML (Javascript 1.0)

„ Variáveis

Î Não precisam ter tipos nem valores definidos Î Podem mudar de tipo!

„ Uso em VRML

Script {url “javascript: (código)” ou

“myScript.js”}

„ Tipos/Valores básicos

Î Undefined Î Null Î Boolean

Codificação básica - ECMAScript

Î String Î Number Î Object

ECMAScript pode ser considerada a linguagem oficial de VRML.

Historicamente, ela é a primeira versão do Javascript que substituiu a VRMLScript por ter sido padronizada primeiro. Apesar de ser a linguagem oficial, nem todos os navegadores e plug-ins aceitam seus comandos. Portanto, é bom ter cuidado quando utilizá-la.

O uso de ECMAScript já foi apresentado aqui em exemplos anteriores. O código é inserido no nó Script, no campo url. Isso pode se dar de duas forma. A primeira, colocando-se o código entre chaves duplas e iniciado por “javascript: ”. A segunda é referenciar o arquivo de javascript, cuja terminação deve ser “.JS”, onde ele se encontra.

OS tipos básicos dessa linguagem são:

•Undefined: tipo de uma variável com tipo indefinido (quando um valor nem tipo ainda lhe foi atribuído);

•Null: tipo de uma variável quando um valor não lhe foi atribuído, ou seja (a variável já possui tipo definido);

•Boolean: tipo booleano (true ou false, como SFBool);

•String: seqüência de caracteres, como SFString;

•Number: tipo numérico com valores entre 2

53

a -2

53

. Possui também os valores: NaN (Not a Number), +infinity, -infinity, -0 e +0;

•Object: semelhante a um objeto Java, possui um conjunto de propriedades (atributos) e métodos. Será visto em mais detalhe daqui a pouco;

22

„ Sintaxe e estrutura semelhante à Java

Î “;” no fim de sentenças

„ Operadores

Î Unários:-, !, ++, --, typeof Î Binários: =, -, *, /, %

Î Relacionais: <, <=, >, >=, ==, !=

Î Lógicos: &&, ||

„ Estruturas

Î if(){}else{} ou a?b:c;

Î while(){}

Î for(;;){}

Î arrays: MFString, MFVect3F, MFNode

Codificação básica - ECMAScript cont.

A sintaxe e a estrutura de ECMAScript são iguais as da linguagem Java. Os operadores unários, binários, lógicos e relacionais funcionam e são representados da mesma forma.

Do mesmo modo, as estruturas de código também possuem a

mesma sintaxe e funcionamento.

(12)

23

23

„ Funções Básicas

Î initialize() Î shutDown() Î eventsProcessed()

Î Funções de processamento de eventos

„ Exemplo:

Codificação básica - ECMAScript cont.

#VRML V2.0 utf8 Script {

eventIn SFInt32 input eventOut SFInt32 output field SFInt32 mult field SFInt32 result url “javascript:

function initialize() { mult = 2; }

function input (value, time) {result = value*mult;}

function eventsProcessed(){output = result;}

function shutDown(){result = mult =0;}”

}

ECMAScript possui quatro tipos de funções básicas. São elas:

initialize(): chamada quando o mundo é construído, serve para iniciar variáveis;

shutDown(): chamada quando se sai do mundo, é utilizada para limpar variáveis ou locais em que se deixou lixo de informação;

eventsProcessed(): é processada quando um conjunto de eventos ocorre sempre que possível (não é garantido o seu processamento toda vez que aquele conjunto de eventos ocorre) ao final dos mesmos;

Funções de processamento de eventos: são aquelas que obterão os eventos de VRML e farão algo a respeito. Essas são as funções que possuem a maior parte do processamento normalmente.

Abaixo, temos um exemplo bem simples de utilização desses campos.

24

24

„ Objetos

Î Criação

• function Vector() { this.x = 0; this.y = 0; this.z = 0; }

Î Instanciação

• myVector1 = new Vector();

• myVector2 = new Vector(1,2,3);

Î Adição de atributos

• myVector2.name = “vetorNinja";

Î Criação de Métodos

• functionvectorMultiply(scalar) {

this.x *= scalar; this.y *= scalar; this.z *= scalar; }

• function Vector() { this.x = 0; this.y = 0; this.z = 0;

this.multiply = vectorMultiply; } Exemplo de chamada:myVector2.multiply(a);

Codificação básica - ECMAScript cont.

O tipo Objeto é uma agregado de propriedades (campos) e métodos(funções). Funciona de forma parecida com Java.

Ele possui um construtor para sua iniciação, cujos campos são referenciados pelo prefixo “this.”.

Para instanciar um objeto, basta atribuir a nova variável um “new object()” com o sem parâmetros. Caso haja passagem de parâmetros, eles serão atribuídos de maneira seqüencial, condizendo com a ordem de inicialização no construtor.

É possível adicionar novos atributos em um objeto mesmo após usa construção, como mostra o exemplo.

Para se criar métodos num objeto, deve-se, primeiramente, criar uma função definida externamente ao objeto para representar esse método e, após isso, associá-lo a uma variável com o nome do método em si.

A chamada se dá, então, pelo nome do método que representa a

função dentro do objeto seguido pela passagem dos parâmetros dessa

função. Temos aí um exemplo de chama de método.

(13)

25

„ Objetos VRML

Î Objetos ECMAScript pré-definidos Î Mapeiam tipos em VRML, adicionando

funcionalidades

• SFFloat, SFInt32, SFTime -> Number

• SFBool -> Boolean

• SFSTRING -> String

• ...

Î Exemplos de funções em objetos ECMAScript

• Vector: produto escalar, produto vetorial, tamanho normalização;

• Array: tamanho, conversão para String;

Î Procurar referências de objetos antes de programar!

Codificação básica - ECMAScript cont.

Existem objetos pré-definidos em ECMAScript que mapeiam os tipos de dados existentes em VRML. Esses objetos, além de auxiliarem na interação entre as duas linguagens, provêem funções extras para facilitar a vida do programador. Exemplo disso são funções de cálculo de produtos escalar e vetorial para vetores ou de tamanho de um array e sua conversão para String.

É importante, então, que sempre se leia sobre os métodos existentes nos objetos ECMAScript que mapeiam os tipos que se vai utilizar em um script para aumentar o reuso e poupar tempo de implementação.

No final das transparências serão dadas referências para esse assunto.

26

„ Browser Object

Î Permite modificar o mundo virtual e a relação entre seus objetos

„ Métodos

„ Browser.getName()

„ Browser.getVersion()

„ Browser.getWorldURL()

„ Browser.getCurrentFrameRate()

„ Browser.getCurrentSpeed()

„ Browser.setDescription(string description)

„ Browser.loadURL(MFString url, MFString parameter)

„ Browser.replaceWorld(MFNode nodes)

„ Browser.createVrmlFromString(String string)

„ Browser.createVrmlFromURL(MFString url, SFNode node, String eventIn)

„ Browser.addRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn)

„ Browser.deleteRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn)

Codificação básica - ECMAScript cont.

LEGENDA

(campos do nó Script a ativar):

•Script.directOutput = TRUE

•Script.mustEvaluate = TRUE

•Nenhum do dois

Aqui apresentamos um dos objetos disponíveis em ECMAScript e de grande importância na garantia de total controle sobre o seu mundo. O objeto Browser serve para manipular informações de seu navegador, obviamente. Mas, além disso, ele permite manipular seu mundo e a interação entre seus objetos. Observe a descrição de seus métodos abaixo. Alguns desses métodos requerem que o nó Script a que pertencem tenham valores específicos para os campos directOutput e mustEvaluateOutput. Distinguimos tal necessidade de acordo com a legenda. Os métodos que necessitam de mustEvaluate ativado estão em cor verde enquanto que os que precisam de directOutput ativado estão em laranja. Vamos à descrição dos nós:

Browser.getName(): obtém nome (String) do navegador VRML utilizado. Ex.: “Cortona”;

Browser.getVersion():obtém versão (String) do navegador;

Browser.getWorldURL(): obtém a URL (String) onde o mundo se encontra;

Browser.getCurrentFrameRate(): obtém a taxa de frames em que o mundo está rodando;

Browser.getCurrentSpeed():obtém a velocidade de deslocamento do avatar do usuário;

Browser.setDescription(string description):define a descrição do mundo (configura o campo de Description do nó WorldInfo). Parâmetro description: string contendo descrição do mundo. Esse método precisa que o campo mustEvaluate do nó Script ao qual pertence esteja ativado (TRUE);

Browser.loadURL(MFString url, MFString parameter):carrega um novo mundo de um outro arquivo. Parâmetros:MFString url:lista de URLs onde possivelmente o mundo a ser carregado se encontra;MFString parameter:outros parâmetros a serem passados (igual ao nó AnchorMode - consultar). Esse método precisa que o campo mustEvaluate do nó Script ao qual pertence esteja ativado (TRUE);

Browser.replaceWorld(MFNode nodes): substitui o mundo atual por um outro passado como parâmetro. Esse método precisa que o campo mustEvaluate do nó Script ao qual pertence esteja ativado (TRUE);

Browser.createVrmlFromString(String string): cria um objeto VRML no mundo a partir de sua descrição em VRML passada em formato String (sem o cabeçalho”VRML V2.0 utf8”);

Browser.createVrmlFromURL(MFString url, SFNode node, String eventIn): cria um objeto VRML no nó passado como segundo parâmetro a partir de um arquivo VRML localizado numa das URLs (pode ser um array delas) passadas no primeiro parâmetro. O terceiro parâmetro indica a que campo de entrada de evento do browser o nó a receber os novos objetos (que foi passado como segundo parâmetro) será passado quando na chamada desse método;

Browser.addRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn):cria uma nova rota do campo passado no segundo parametro (pertencente ao nó passado no primeiro parâmetro) para o campo passado no quarto parâmetro (pertencente ao nó passado no terceiro parâmetro). Esse método precisa que o campo directOutput do nó Script ao qual pertence esteja ativado (TRUE);

Browser.deleteRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn):destrói a rota que liga o campo passado no segundo parametro (pertencente ao nó passado no primeiro parâmetro) ao campo passado no quarto parâmetro (pertencente ao nó passado no terceiro parâmetro) . Esse método precisa que o campo directOutput do nó Script ao qual pertence esteja ativado (TRUE);

(14)

27

27

„

VRML permite uso de chamada a classes Java

„

Passos para se gerar uma classe Java compatível com o nó Script de VRML

1.

Importa pacote VRML de Java;

2.

Classe deve estender classe Script;

3.

Atrela variáveis do nó Script a variáveis da classe Java;

4.

Processa/Captura-se eventos recebidos de VRML;

5.

Processa os dados...;

6.

Atribui resultados às variáveis atreladas a eventOut;

7.

Adiciona localização das classes VRML do navegador VRML no CLASSPATH;

8.

Gera o “.class”;

9.

Adiciona-o ao campo url do nó Script.

Codificação Avançada - Java

É possível adicionar código Java à seu mundo virtual. O processo é bastante simples. Basta seguir os passos abaixo. Esses passos estão relacionados, em sua maioria, ao exemplo dado a seguir:

1. Colocar i mportação do pacote VRML de Java no arquivo onde as classes estão descritas;

2. Fazer com que a classe estenda a classe Script;

3. Atrelar variáveis do nó Script a variáveis da classe Java. Faz-se isso dentro do método initialize();

4. Processar eventos recebidos de VRML através do método processEvent;

5. Processa dados da maneira que quiser

6. Atribui resultados às variáveis atreladas a eventOut;

7. Adicionar localização das classes VRML do navegador VRML no CLASSPATH;

8. Gera o “.class” – gerar para a versão 1.1 para garantir compatibilidade com navegadores;

9. Adiciona o arquivo “.class” ao campo url do nó Script no arquivo VRML;

28

28

„ Exemplo: gerador de ondas senoidais

„ Objetivo

Î Transformar sinal de um TimeSensor em valores de seno

Codificação Avançada - Java

TimeSensor fraction_changed

Script fraction_changed set_fraction

Interpolador set_...

#VRML V2.0 utf8 DEF myTimerTimeSensor {

cycleInterval5 loop TRUE startTime0 stopTime-1} DEF myScriptScript {

eventIn SFFloatset_fraction eventOut SFFloatfraction_changed field SFFloat amplitude 1 url “GeraSeno.class" }

ROUTE myTimer.fraction_changed TO myScript.set_fraction

Aqui temos um exemplo que explicará melhor o processo. Esse exemplo transformará o sinal emitido por um TimeSensor em valores de uma onda senoidal (de -1 a 1). Esse valor pode então ser ligado a um interpolador para gerar movimentos senoidais em objetos. Aqui, entretanto, abordaremos, apenas, o time Sensor e o nó Script.

Veja abaixo o arquivo VRML que descreve esses dois nós. Observem que eles estão ligados entre si por uma rota e que o nó Script possui um campo de entrada para receber sinais do TimeSensor e um de saída pro onde enviará os sinais de seno. Ainda, ele possui um campo de amplitude, onde pode se definir a amplitude da onda senoidal sendo criada.

O nó script faz referência a um arquivo “.class” que contém o código

Java responsável por transformar o sinal do Timer, código esse

descrito a seguir.

(15)

29

„ Exemplo: GeraSeno.java

Codificação Avançada - Java cont.

import vrml.*;

import vrml.node.*;

import vrml.field.*;

public class SineGen extends Script { private SFFloatfraction_changed;

private SFFloatamplitude;

public void initialize() {

fraction_changed = (SFFloat) getEventOut("fraction_changed");

amplitude = (SFFloat) getField("amplitude"); } public void processEvent (Event e) {

if (e.getName().equals("set_fraction")) { sine((ConstSFFloat)e.getValue()); } } private voidsine(ConstSFFloat fraction) {

double result = Math.sin(fraction.getValue() * Math.PI * 2);

result *= amplitude.getValue();

fraction_changed.setValue((float)result); } }

1. Pacotes VRML 2. Extensão de Script

3. Atrelamento entre variáveis

4. Processamento de eventos 5. Processamento

de dados

5. Resultados passados para EventOut

A descrição da classe do exemplo anterior segue aqui. Aqui temos um exemplo bem simples de como uma classe em Java deve ser adaptada para seu uso com VRML. O código está relacionado aos passos anteriormente mencionados:

• Colocar i mportação do pacote VRML de Java no arquivo onde as classes estão descritas;

• Fazer com que a classe estenda a classe Script;

• Atrelar variáveis do nó Script a variáveis da classe Java. Faz-se isso dentro do método initialize();

• Processar eventos recebidos de VRML através do método processEvent;

• Processa dados da maneira que quiser

• Atribui resultados às variáveis atreladas a eventOut;

30

„ Exemplo: Gerando o .class

Î Modifica o classpath

• set CLASSPATH=C:\Arquivos de programas\Arquivos comuns\ParallelGraphics\Cortona\classes.zip;

Î Gera o class

• javac-target 1.1GeraSeno.java

Î Adiciona o nome do “.class” ao nó Script

• DEF myScript Script {

eventIn SFFloat set_fraction eventOut SFFloat fraction_changed field SFFloat amplitude 1

url “GeraSeno.class"

}

Codificação Avançada - Java

Aqui temos os passos para compilação e geração do classe. Acredito que todos vocês já saibam fazer isso.

6. Adicionar localização das classes VRML do navegador VRML no CLASSPATH;

7. Gera o “.class” – gerar para a versão 1.1 para garantir compatibilidade com navegadores;

8. Adiciona o arquivo “.class” ao campo url do nó Script no

arquivo VRML;

(16)

31

31

„

Transparências comentadas!!

„

Referências

Î

Floppy’s VRML 97 Tutorial:

•http://web3d.vapourtech.com/tutorials/vrml97/

Î

Web 3D Consortium – VRML Archives

•http://www.web3d.org/x3d/vrml/index.html Î

Funções de ECMAScript:

•http://www.web3d.org/x3d/specifications/ISO-IEC-19777- FCD-X3dLanguageBindings/Part1/functions.html

Referências

Documentos relacionados

OS BENS SERÃO VENDIDOS NO ESTADO DE CONSERVAÇÃO EM QUE SE ENCONTRAM, NÃO CABENDO AOS COMITENTES NEM AO LEILOEIRO QUALQUER RESPONSABILIDADE QUANTO À GARANTIA,

• Nunca tente consertar o produto em casa por si ou por terceiros não autorizados, para evitar acidentes e problemas técnicos e para não perder a garantia contratual.. Quando

evento, contudo, as meninas tendem a aumentar a quantidade de gordura corporal de forma mais acentuada que os meninos. Estes, por outro lado, aumentam de

Entretanto, para se explorar de forma mais otimizada a fixação biológica de nitrogênio (FBN) é necessário que se conheça a ecologia das bactérias do grupo dos rizóbios

crático, decorrendo daí certa negativa de aceitação de políticas de ação afirmativa para as mulheres; (3) na sua maioria, embora não acreditem na discriminação

A utilização de água e nutrientes é cíclica (ocorrem numa ordem determinada) desde que, retirados do solo, tais elementos retornem ao mesmo através dos

Descobriu-se mais tarde que o Jorge tinha desaparecido depois da sua mãe, Janine, lhe ter dado 60 euros para pagar a aparelhagem que tínhamos levado de minha casa!. Mas ele não deu

Este trabalho tem como objetivo a elaboração de uma tabela regional que servirá para estimar os volumes comer- ciais de fustes de árvores em pé, para um grupo de espécies