Sunteți pe pagina 1din 326

1

2
3
4
5
1. INTRODUÇÃO A VISUALIZAÇÃO DE INFORMAÇÃO. ............... 13

1.1 Modelos de Interação...................................................................................................17

1.2 Características de uma Ferramenta de Visualização de Informação .........................17

1.3 Tipos de Dados Versus Tipos de Visualização.............................................................18

1.4 Regras para um bom gráfico de visualização de informação......................................19

1.5 Representação de Dados ..............................................................................................20


1.5.1 Tamanho ..............................................................................................................20
1.5.2 Comprimento e Altura ..........................................................................................21
1.5.3 Espacialidade e Ampliação ...................................................................................21
1.5.4 Faces e Ícones Multidimensionais .........................................................................22
1.5.5 Som......................................................................................................................23
1.5.6 Mundos Virtuais ...................................................................................................23
1.5.7 Cor.......................................................................................................................24

1.6 Técnicas de visualização ..............................................................................................24

1.7 Aplicações ....................................................................................................................27


1.7.1 SpotFire................................................................................................................27
1.7.2 Paralax. ................................................................................................................28
1.7.3 Treemap ...............................................................................................................29
1.7.4 Eureka - LENTE DE MESA .................................................................................30
1.7.5 ThemeScape.........................................................................................................31
1.7.6 NetViz..................................................................................................................31
1.7.7 Máquina de busca AMORE (Advanced Multimedia Oriented Retrieval Engine) ....33
1.7.8 Espaço Hiperbólico...............................................................................................33
1.7.9 Cat-a-Cone ...........................................................................................................34
1.7.10 Perspective Wall...................................................................................................35

1.8 Estudo de Caso: Construção de um Protótipo para Visualização de Informação


Utilizando VRML e JAVA .................................................................................................................36

1.9 Referências deste capítulo............................................................................................45

2 RV SUPORTADA PELAS TECNOLOGIAS VMRL E X3D ............ 47

2.1 Introdução....................................................................................................................47
2.1.1 VRML97..............................................................................................................48
2.1.2 X3D .....................................................................................................................50
6
2.2 Grafo de Cena ..............................................................................................................53
2.2.1 Definições básicas ................................................................................................53
2.2.2 Atributos ..............................................................................................................54
2.2.3 Nós em VRML e X3D ..........................................................................................55

2.3 Codificação VRML97 ..................................................................................................65


2.3.1 Formas Geométricas Básicas e primeiros exemplos ...............................................65
2.3.2 Textos ..................................................................................................................65
2.3.3 Transformações Geométricas ................................................................................66
2.3.4 Alterando Aparência - nó appearance ....................................................................68
2.3.5 Reutilizando Formas, Elementos e Definições .......................................................71
2.3.6 Compondo formas como conjunto de Faces...........................................................73
2.3.7 Fundos e Cenários ................................................................................................74
2.3.8 Iluminação............................................................................................................76
2.3.8.1 DirectionalLight..............................................................................................76
2.3.8.2 PointLight.......................................................................................................77
2.3.8.3 SpotLight........................................................................................................78
2.3.9 Controlando Detalhamento de Elementos - nó LOD ..............................................78
2.3.10 Animando as formas.............................................................................................79
2.3.10.1 Animações básicas........................................................................................79
2.3.10.2 Controlando as animações .............................................................................83
2.3.11 Controlando o Ponto de Vista e a Navegação ........................................................86
2.3.12 Adicionando Sons e Filmes ao Cenário .................................................................87
2.3.13 Sentindo a proximidade do usuário .......................................................................87
2.3.14 Unindo Cenários Virtuais - Links..........................................................................89
2.3.15 Combinando VRML e JavaScript..........................................................................91
2.3.15.1 Introdução.....................................................................................................91
2.3.15.2 Exemplos......................................................................................................92

2.4 Codificação X3D ..........................................................................................................94

2.5 Transição do VRML para o X3D ................................................................................97

2.6 Utilização de Ferramentas ...........................................................................................99


2.6.1 Editando os arquivos VRML97 e X3D..................................................................99
2.6.2 Editando os arquivos VRML97 e X3D de forma mais avançada .......................... 101

2.7 Referências deste capítulo.......................................................................................... 102

3 AMBIENTES VIRTUAIS EM JAVA.............................................. 104

3.1 Introdução.................................................................................................................. 104


7
3.2 A Linguagem Java ..................................................................................................... 104
3.2.1 Carregamento Dinâmico de Classes .................................................................... 104
3.2.2 Controle de Segurança ........................................................................................ 107

3.3 Java 3D ...................................................................................................................... 108


3.3.1 Grafo de Cena .................................................................................................... 108
3.3.2 NodeComponents................................................................................................ 109
3.3.3 Principais Classes do Java 3D ............................................................................. 110
3.3.4 Capabilities ........................................................................................................ 111
3.3.5 Loaders .............................................................................................................. 112
3.3.6 Behaviors ........................................................................................................... 113
3.3.7 Configuração de Ambiente e Visualização .......................................................... 117
3.3.8 Views................................................................................................................. 119
3.3.9 InputDevices ...................................................................................................... 120

3.4 Transição do VRML.................................................................................................. 123


3.4.1 VRML e X3D..................................................................................................... 123
3.4.2 Xj3D .................................................................................................................. 124

3.5 Comunicação em Rede............................................................................................... 124


3.5.1 RMI ................................................................................................................... 124
3.5.2 JSDT.................................................................................................................. 126
3.5.3 Sockets............................................................................................................... 127

3.6 Conclusão................................................................................................................... 129

3.7 Bibliografia Recomendada ........................................................................................ 129

3.8 Sites para Referência ................................................................................................. 130

4 DESENVOLVIMENTO DE APLICAÇÕES DE REALIDADE


VIRTUAL 131

4.1 Introdução.................................................................................................................. 131

4.2 Introdução à Realidade Virtual................................................................................. 131

4.3 Cenários para Ambientes de Realidade Virtual........................................................ 134

4.4 Transformações Geométricas.................................................................................... 135


4.4.1 Translação.......................................................................................................... 135
4.4.2 Rotação .............................................................................................................. 135
4.4.3 Escala................................................................................................................. 136
8
4.4.4 Reinicializando as Transformações ..................................................................... 136
4.4.5 Limitando o Escopo das Transformações ............................................................ 136

4.5 Navegação em ambientes de Realidade Virtual ........................................................ 137


4.5.1 Andando "para frente" com a gluLookAt............................................................. 137
4.5.2 Olhando "para os lados" com a gluLookAt .......................................................... 138

4.6 Geração de Visão Estereoscópica .............................................................................. 139


4.6.1 Posicionamento do Observador........................................................................... 139
4.6.2 Imagens Entrelaçadas: técnicas e dispositivos...................................................... 140
4.6.3 Imagens Alternadas: técnicas e dispositivos ........................................................ 142

4.7 Interação em Ambientes de Realidade Virtual ......................................................... 143


4.7.1 Técnicas de Interação.......................................................................................... 143
4.7.1.2 Metáfora de Mapeamento Direto ................................................................... 144
4.7.1.3 Metáforas de extensão de braço..................................................................... 145
4.7.1.4 Metáforas de apontamento por raio................................................................ 146

4.8 Apontamento de Objetos ........................................................................................... 149

4.9 Movimentação de objetos – Transformações hierárquicas ....................................... 151


4.9.1 Representando Transformações Geométricas por Matrizes .................................. 151
4.9.2 Aplicando novas Matrizes de Transformação ...................................................... 152
4.9.3 Armazenando as Transformações de um objeto em uma matriz ........................... 152
4.9.4 Alterando a Matriz de Transformação antes de desenhar um objeto ..................... 153
4.9.5 Montando Transformações Hierárquicas ............................................................. 153
4.9.5.1 Montando o vínculo de hierarquia ................................................................. 154
4.9.5.2 Desfazendo o vínculo de hierarquia ............................................................... 154

4.10 Ambientes Virtuais Colaborativos ........................................................................ 155


4.10.1 Memória distribuída ........................................................................................... 156
4.10.2 Remote Memory................................................................................................. 156
4.10.2.1 Compilando a RemoteMemory..................................................................... 156
4.10.2.2 Montando uma Aplicação Cliente................................................................ 158

4.11 Exibição de Cenários em Múltiplas Telas............................................................. 160


4.11.1 Dividindo o View Frustum em Múltiplas Telas ................................................... 162

4.12 Geração de Tato em Ambientes Virtuais .............................................................. 164

4.13 Referências ............................................................................................................ 165


9
5 REALIDADE AUMENTADA: CONCEITOS E AMBIENTES DE
HARDWARE .................................................................................................. 168

5.1 Introdução.................................................................................................................. 168

5.2 Conceitos.................................................................................................................... 169


5.2.1 Mutimídia........................................................................................................... 169
5.2.2 Realidade Virtual................................................................................................ 169
5.2.3 Realidade Misturada ........................................................................................... 170
5.2.4 Realidade Aumentada ......................................................................................... 171
5.2.5 Virtualidade Aumentada ..................................................................................... 172
5.2.6 Hiper-realidade................................................................................................... 173

5.3 Ambiente de Hardware para Realidade Aumentada ................................................ 174


5.3.1 Concepção da Plataforma.................................................................................... 174
5.3.2 Ambiente Dedicado ............................................................................................ 176
5.3.2.1 Classificação de Plataformas Disponíveis ...................................................... 177
5.3.2.2 A Plataforma DRAI ...................................................................................... 177
5.3.2.3 Opção por Software Livre ............................................................................. 178
5.3.3 Arquitetura ......................................................................................................... 179
5.3.4 Análise de Desempenho...................................................................................... 181

5.4 Conclusões.................................................................................................................. 185

5.5 Referências deste capítulo.......................................................................................... 185

6 ARTOOLKIT – ASPECTOS TÉCNICOS E APLICAÇÕES


EDUCACIONAIS............................................................................................ 188

6.1 Introdução.................................................................................................................. 188

6.2 Versões e Instalação................................................................................................... 190


6.2.1 Instalação no PC-Windows ................................................................................. 192
6.2.2 Programação de Aplicações ................................................................................ 195
6.2.3 Hardware necessário........................................................................................... 196
6.2.4 A saída do simple.exe ......................................................................................... 196
6.2.5 A saída do simpleVRML.exe .............................................................................. 198
6.2.6 O funcionamento do ARToolKit ......................................................................... 200
6.2.7 Escrevendo a aplicação....................................................................................... 201
6.2.7.1 init() ............................................................................................................. 204
6.2.7.2 mainLoop ..................................................................................................... 207
6.2.7.3 cleanup ......................................................................................................... 210
10
6.2.8 Reconhecendo outros padrões ............................................................................. 210
6.2.9 Outros programas de exemplo............................................................................. 212
6.2.9.1 ExView ........................................................................................................ 212
6.2.9.2 Simple .......................................................................................................... 213

6.3 Calibração de Câmeras com o ARToolKit................................................................ 214


6.3.1 Executando o calib_dist ...................................................................................... 215
6.3.2 Executando o calib_cparam.......................................................................... 220

6.4 Bibliotecas e Funções do ARToolKit ......................................................................... 225


6.4.1 Estruturas de Dados Básicas................................................................................ 227
6.4.2 Funções de Realidade Aumentada ....................................................................... 227
6.4.2.1 arInitCparam .................................................................................... 228
6.4.2.2 arLoadPatt......................................................................................... 228
6.4.2.3 arDetectMarker e arDetectMarkerLite................................ 228
6.4.2.4 arGetTransMat.................................................................................. 229
6.4.2.5 arSavePatt......................................................................................... 230
6.4.3 Funções de Aquisição de Vídeo .......................................................................... 230
6.4.3.1 arVideoOpen ...................................................................................... 230
6.4.3.2 arVideoClose .................................................................................... 231
6.4.3.3 arVideoInqSize................................................................................ 231
6.4.3.4 arVideoGetImage ............................................................................. 231

6.5 Limitações da RA baseada em Visão Computacional ............................................... 231

6.6 Aplicações Educacionais em Ambientes de Realidade Aumentada com ARToolKit233


6.6.1 Introdução .......................................................................................................... 233
6.6.2 Intervenções Educacionais com Realidade Aumentada ........................................ 234
6.6.3 Sistema de Realidade Aumentada........................................................................ 236
6.6.4 Quebra-cabeças .................................................................................................. 238
6.6.5 Livro Interativo com Realidade Aumentada......................................................... 238
6.6.6 Pá de transporte de objetos virtuais ..................................................................... 239
6.6.7 Aprendizagem de mecânica quântica com realidade aumentada: O Orbitário....... 240
6.6.7.1 Dificuldades de aprendizagem da Mecânica Quântica .................................... 241
6.6.7.2 O computador e a aprendizagem da Mecânica Quântica ................................. 241
6.6.8 Conclusões ......................................................................................................... 246

6.7 REFERENCIAS BIBLIOGRÁFICAS ...................................................................... 247

ALICE: UMA FERRAMENTA DE AUTORIA ...................................... 251


11
7 – INTRODUÇÃO À FERRAMENTA ALICE ................................. 251

7.1 O que é Alice? ............................................................................................................ 251

7.2 Configurações necessárias e instalação ..................................................................... 251

7.3 Conceitos básicos ....................................................................................................... 253


7.3.1 O ambiente do Alice ........................................................................................... 253
7.3.2 Utilização de mundos exemplo............................................................................ 255
7.3.3 Introdução à interface “drag-and-drop” do Alice................................................. 258
7.3.4 Coleção de objetos.............................................................................................. 259
7.3.5 Usando o mouse.................................................................................................. 261
7.3.6 Introdução aos comandos Alice........................................................................... 262
7.3.7 Partes de objetos................................................................................................. 263

7.4 – Construindo mundos em Alice................................................................................ 264


7.4.1 Mundos existentes .............................................................................................. 264
7.4.1.1 World Window ............................................................................................. 264
7.4.1.2 Manipulação da câmera................................................................................. 265
7.4.1.3 Editor Area ................................................................................................... 265
7.4.1.4 Como mudar um mundo................................................................................ 266
7.4.1.5 Mudando a cena de abertura .......................................................................... 266
7.4.1.6 Mudando o roteiro......................................................................................... 266
7.4.1.7 O comando DoInOrder.................................................................................. 267
7.4.1.8 O comando DoTogether ................................................................................ 267
7.4.2 Mundos novos .................................................................................................... 268
7.4.2.1 Criação ......................................................................................................... 268
7.4.2.2 Ajustando a cena de abertura ......................................................................... 270
7.4.2.3 Escrevendo o roteiro ..................................................................................... 270
7.4.2.4 Mudanças ..................................................................................................... 274
7.4.2.5 O comando Loop .......................................................................................... 274
7.4.2.6 O comando RespondTo ................................................................................. 274

7.5 Detalhes em comandos Alice...................................................................................... 275


7.5.1 Palavras-chave e dicas ........................................................................................ 275
7.5.1.1 A palavra-chave Duration.............................................................................. 275
7.5.1.2 A palavra-chave Speed.................................................................................. 275
7.5.1.3 A palavra-chave AsSeenBy ........................................................................... 275
7.5.1.4 A dica EachFrame......................................................................................... 276
7.5.2 Interação ............................................................................................................ 276

7.6 Ajuda.......................................................................................................................... 279


12
7.7 Resumo dos comandos ............................................................................................... 280

7.8 Palavras-chave que Alice reconhece.......................................................................... 280

8 MODELAGEM E IMPLEMENTAÇÃO DE ANIMAÇÕES PARA


AMBIENTES VIRTUAIS UTILIZANDO O.D.E. .............................................. 282

8.1 Histórico..................................................................................................................... 282

8.2 Instalação ................................................................................................................... 283


8.2.1 Instalação em C/C++ .......................................................................................... 283
8.2.2 Instalação em Delphi .......................................................................................... 284

8.3 Passos básicos............................................................................................................. 285

8.4 Tipos de Dados e Conversões..................................................................................... 286


8.4.1 Os Tipos básicos de Dados.................................................................................. 286
8.4.2 Objetos e identificações ...................................................................................... 286
8.4.3 Argumentos de conversão ................................................................................... 287

8.5 Dinâmica de Corpos Rígidos (Rigid Body Dynamics)............................................... 287

8.6 Articulações (Joints) .................................................................................................. 289


8.6.1 Tipos, parâmetros e configuração de articulações ................................................ 290
8.6.2 Hinge ................................................................................................................. 291
8.6.3 Hinge-2 .............................................................................................................. 293
8.6.4 Articulação Fixa ................................................................................................. 294
8.6.5 Contato............................................................................................................... 294
8.6.6 Motor Angular.................................................................................................... 298

8.7 Informações Gerais.................................................................................................... 300


8.7.1 Parâmetros de Parada e de Motor ........................................................................ 300
8.7.2 Configurando forças e torques direcionais ........................................................... 302

8.8 Redução de Erros em Simulação – E.R.P. e C.F.M................................................... 302


8.8.1 Erros de articulação e parâmetros para redução de erros ...................................... 302

8.9 Detecção de colisão..................................................................................................... 304

8.10 Exemplos ............................................................................................................... 312


8.10.1 Exemplo 1 – Máquina e Aplicação de Forças ...................................................... 312
8.10.2 Exemplo 2 – Bola e Aplicação de Gravidade....................................................... 319

8.11 Referências ............................................................................................................ 326


13
Visualização de Informação
Bianchi Serique Meiguins1, Aruanda Simões Gonçalves2, Marcelo de Brito
Garcia2, Rosevaldo Dias de Souza Júnior2.
1
Departamento de Informática – Centro de Exatas e Naturais –
Universidade Federal do Pará – C.P. 8619 CEP 66075-900 - Belém – PA – Brasil

2
Programa de Pós-Graduação - Universidade Federal do Pará (UFPA)
Departamento de Engenharia Elétrica, C.P. 8619 - CEP 66075-900 - Belém - PA –
Brasil.

bianchi.serique@terra.com.br, aruanda@redeinformatica.com.br,
mbgarcia_pa@yahoo.com.br, rosico@amazon.com.br

1. Introdução a Visualização de Informação.


A sobrecarga de informação, atualmente, é considerada um dos grandes
problemas da interação humano-computador. Tomar uma decisão correta, em qualquer
área do conhecimento, com uma enorme quantidade de dados e pouco tempo, quase
sempre é uma tarefa difícil de realizar. O computador pode, em poucos segundos,
recuperar informações que um ser humano levaria anos talvez. Contudo, muitas dessas
informações são irrelevantes para o usuário, ou perdem-se informações úteis por não
conhecer o relacionamento entre os dados.
Mesmo antes do advento da computação, a visualização de informação era
utilizada para perceber o relacionamento entre os dados, como foi o caso de cólera em
um Bairro de Londres em 1845 (Spence, 2001). A relevância para visualização de
informação está clara na Figura 1. É possível observar o mapa da área: pontos de preto
representam mortes individuais de cólera e “x” marca as posições das bombas de água.
O Dr John Snow, criador do mapa, observou que a maioria das mortes estava
concentrada ao redor da bomba de Rua Broad. O desligamento daquela bomba foi
seguido por uma diminuição no número de mortes de cólera.
14

Figura 1-1 - Exemplo do uso de visualização de informação para controle da epidemia de


cólera em Londres em 1845 (Spence, 20001).
Nos dias atuais, há uma grande quantidade de informação eletronicamente
armazenada em bancos de dados e repositórios de informações eletrônicas. Na maioria
dos casos, a análise dessas informações é feita na forma de relatórios tabulares e
planilhas eletrônicas. Esses relatórios na maioria das vezes são apresentados com
poucos dados (5 colunas e 20 linhas) ou grande quantidade de dados (300 páginas de
relatório detalhados, com 20 colunas e 40 linhas por página). Na primeira opção, o
usuário perde informação, na segunda opção o usuário se perde nas informações. Além
disso, pode-se citar que os relatórios tabulares limitam a percepção do usuário, pois não
se adaptam muito bem em representar outros tipos de informações não numéricas, como
texto ou imagens.
O uso de técnicas de visualização de informação para melhorar o processo de
busca e tomada de decisão sobre essa grande quantidade de informações tem se tornado
cada vez mais utilizada.
Quando se pensa em criar ou utilizar uma ferramenta de visualização de
informação, deve estar claro o domínio, dados e processos de workflow que neles serão
representado, pois qualquer alteração desses itens pode resultar em uma nova
ferramenta, escolhida ou desenvolvida. Pesquisa citada por Brath (Brath, 1999) com 130
15
projetos de aplicação de visualização para clientes coorporativos mostrou que estes
clientes não querem uma visualização genérica. Ao invés, disto eles querem uma
solução visual que cumpra uma necessidade específica. Todas as 130 visualizações
foram diferentes.
A visualização de informação (às vezes chamada de visualização de negócios,
ou simplesmente visualização) é uma representação visual interativa que transforma
dados abstratos em uma representação visual que é compreendida prontamente por um
usuário, podendo então gerar um novo conhecimento da relação entre os dados. Pode
ser usada para tarefas como identificação, correlação multivariada, procura, consulta,
exploração e comunicação. Os dados são tipicamente quantitativos ou categorizados,
mas também pode incluir: texto não estruturado, tipos de mídias diferentes e objetos
estruturados (Spence, 2001) (Card, 1999).
Há um campo relacionado, e algumas vezes sobreposto, à visualização de
informação chamada de “visualização científica”. A visualização científica se preocupa
em representar visualmente uma simulação tridimensional de uma “coisa” física real,
por exemplo, nuvens fluindo através de uma cadeia de montanhas, dada uma certa
condição do vento (Spence, 2001). Este texto não trata de visualização científica,
entretanto muitas das técnicas que serão apresentadas são pertinentes às duas áreas.
Para exemplificar a potencialidade da representação gráfica, um exemplo é
mostrado na Figura 1-2 , e sugere ao usuário que ele descreva a relação entre os pontos
das tab,elas (Brath, 1999):

Figura 1-2 - Quatro tabelas similares.


Cada tabela tem o mesmo número de elementos, significado, regressão linear,
etc. Porém, os mesmo dados apresentados visualmente no gráfico X-Y aparecem como
na Figura 1-3:
16

Figura 1-3 - Quatro gráficos


Os mesmos dados representados visualmente permitem uma percepção imediata
nas relações entre os pontos no conjunto de dados. Um usuário pode identificar
prontamente, de maneira visual, pontos desordenados, correlações lineares e correlações
quadráticas.
Desenvolver um sistema de visualização de informação pode não ser uma tarefa
trivial. De acordo com Freitas (Freitas, 2001), os itens que podem aumentar essa
complexidade são:
• Necessidade de criação de uma metáfora visual que permita codificar
visualmente o conjunto de informações com o grau de fidelidade necessário
à aplicação;
• Mecanismos de interação necessários para manipular os freqüentemente
volumosos e/ou complexos conjuntos de dados;
• Implementação freqüente de algoritmos geométricos complexos tanto para a
criação da representação visual como para sua manipulação;
• Integração com sistemas de mineração de dados, já que a busca de facilitar o
entendimento dos dados passa pelo reconhecimento de padrões, estruturas e
outras informações ocultas no próprio conjunto de dados.
Uma nova tendência no projeto de interfaces é a produção de interfaces
tridimensionais para dar suporte ao armazenamento e a recuperação de textos e dados
abstratos. A crença comum atrás desta tendência é que a representação tridimensional
do mundo real permite uma percepção mais direta entre as informações do ambiente e
suas representações eletrônicas.
17
Para ambientes virtuais tridimensionais a interação é fundamental para melhorar
a percepção. Assim, o desenvolvedor deve lançar mão das mais diversas técnicas, tais
como: menus e botões virtuais, painéis com filas e colunas de dados, etc (Chen, 1999),
nos mais diversos sistemas, como sistema sistemas de realidade imersivos e não
imersivos ou sistemas de realidade aumentada. E toda essa tecnologia deve estar focada
em permitir ao usuário realizar tarefas para melhorar sua percepção do relacionamento
entre os dados, essas tarefas serão comentas nas próximas seções.

1.1 Modelos de Interação.


Na época anterior ao advento do computador, exemplificado pelo mapa do Dr.
John Snow para o controle da cólera em Londres, o autor de gráfico de visualização teve
que executar a seleção, representação e apresentação dos dados de acordo com a sua
compreensão da tarefa a ser executada, compreensão essa que deveria ser igual ao do
espectador, mas que nem sempre era por serem pessoas diferentes. Assim, o usuário
ficava limitado à visão do autor (Figura 1.4a). Agora, com a disponibilidade de
computadores com alto poder de processamento, permitiu-se a possibilidade do usuário
interferir em todas as etapas do processo de visualização (Figura 1-4 – direita), com
uma liberdade definida (Spence, 2001).

Dados Dados
Brutos Brutos

ESPECTADOR
SELEÇÃO CODIFICAÇÃO APRESENTAÇÃO
SELEÇÃO CODIFICAÇÃO APRESENTAÇÃO

Engenheiro da Ferramenta de Visualização


AUTOR

Figura 1-4 : Usuário não participa da Com o advento do computador o usuário pode
concepção da visualização da informação interagir em qualquer parte do processo de
visualização.

1.2 Características de uma Ferramenta de Visualização de


Informação
De acordo com Carr (Carr, 2004) uma ferramenta de visualização de informação
deve permitir os usuários realizar as seguintes tarefas:
• Visão geral: o usuário precisa ganhar uma noção sobre todos os dados que
serão analisados. Essa noção está baseada nos parâmetros que o usuário
18
escolheu para a visualização, nos limites do dispositivo gráfico usado e de
sua percepção. A maioria dos atributos gráficos é posição, cor, tipo de
representação e tamanho.
• Zoom: a técnica de zoom é importante porque permite focar em certo
subconjunto dos dados para análise, ou seja, analisar um determinado
contexto. Além disso, conforme se vai aplicando o zoom, mais detalhes
sobre uma determinada visão dos dados são mostrados, o que se chama de
zoom semântico.
• Filtro: usuários freqüentemente precisam reduzir o tamanho do conjunto de
dados, eliminando itens baseados em seus atributos. Uma das maneiras mais
eficientes é o uso de Consultas Dinâmicas.
• Detalhes sob demanda: quando os usuários estão explorando um conjunto de
dados, eles necessitarão ver detalhes sobre um item em particular. Isto é
normalmente feito usando o clique do mouse, onde as informações
adicionais podem aparecer em uma janela auxiliar, ou na própria visão dos
dados.
• Relacionamentos: Se o usuário descobre um item de interesse, ele pode
precisar saber sobre outros itens com atributos similares, a ferramenta então
poderia apontar esses itens similares.
• Histórico: o usuário precisa de suporte para desfazer uma ação, mostrar os
passos até aquele ponto, etc.

1.3 Tipos de Dados Versus Tipos de Visualização


É natural pensar que um ambiente tridimensional seja um ambiente melhor para
a representação de dados, uma vez que há mais uma dimensão. Contudo, nem sempre
três dimensões são necessariamente melhor do que duas dimensões. Um dos critérios
para essa escolha é o tipo de dado que se quer visualizar. De acordo com Shneiderman
(Shneiderman, 1996), há sete tipos dados diferentes, e descreve diferentes visualizações
os mesmos, são eles:
• 1-Dimensão: este tipo de dado é representado por texto ou dados similares,
como linhas de código. Pode haver outras informações associadas a ele,
como data da criação, tamanho, data da última modificação, etc. Uma
técnica bastante associada a esse tipo de dado é o uso de linhas com cores e
larguras variadas, representando outros atributos.
19
• 2-Dimensões: Este tipo de dado inclui dados geográficos, plantas de
engenharia, etc. Pode-se associar uma grande quantidade de atributos com
uso de cores, tamanhos e formas diferentes.
• 3-Dimensões: aqui o volume de um objeto torna-se importante, um tributo a
mais. Se o contexto do mundo real puder ser incluído para melhorar a
percepção do usuário é mais indicado ainda. Não se deve deixar de
mencionar problemas inerentes a uma visualização 3D, como a oclusão,
quando parte de um dado esconde um outro. Para isso técnicas de visões
diferenciadas, transparência e slicing são necessárias.
• Temporal: este tipo de dado reúne todas as características dos dados acima
mais o atributo tempo. Para o atributo tempo o mais indicado é formar uma
dimensão. Os gráficos “tempo versus algum atributo” são bastante utilizados
e conhecidos. A animação deve ser considerada quando há uma grande
quantidade de dados.
• Multidimensional: base de dados relacional ou estatística pode ser
considerada como pontos em um espaço multidimensional. Técnicas como
consultas dinâmicas e diagramas de dispersão são bastante úteis.
• Hierárquico: muito útil para classificação de dados. Normalmente é
representado por diagramas com nós, com ligações entre os mesmos.
• Rede: dados de rede são nós conectados por links previamente definidos.
Esses links podem ser organizados em árvores ou em hierarquias, e a melhor
maneira de manipulação é permitindo mudar o foco sobre os nós.

1.4 Regras para um bom gráfico de visualização de informação


Segundo Brath (Brath, 1999), um gráfico de informação efetiva deve ter as
seguintes metas:
• Induzir o espectador a pensar no que é mais importante,
• Apresentar muitos números em um pequeno espaço,
• Fazer com que grande quantidade de dados se torne coerente,
• Encorajar comparações de diferentes pedaços de dados, e;
• Revelar dados a vários níveis de detalhe.
Para alcançar estas metas recomendam-se os seguintes princípios:
• Mostrar os dados;
20
• Maximizar a relação dos dados (remover a informação de não dados e
reduzir a informação de dados redundante),
• Evite percepção de “lixos”;
• Utilizar elementos multifuncionais (por exemplo, rótulos e linhas de grade
deveriam ser dependentes de dados);
• Maximizar os dados mostrados (mostrar mais dados);
• Aumentar a densidade de dados encolhendo a área usada para o gráfico;
• Usar múltiplos exemplos de gráficos para facilitar comparações visuais;
• Usar palavras, números e gráficos juntos,
• Fornecer uma qualidade narrativa,
• Usar as palavras por completo com orientação padrão,
• Evitar as legendas colocando rótulos diretamente no gráfico,
• Usar cores cuidadosamente (realçar a informação mais importante e separar
classes diferentes, e também, evitar combinações de cores similares), e;
• Separar as classes diferentes de informação em camadas (planos diferentes
com destaques diferentes).

1.5 Representação de Dados


Uma grande variedade de representações simbólicas está disponível para a
codificação de dados (Brath, 1999). Infelizmente, há muito pouco de teoria de base que
ajude a explorar essas técnicas codificação. A principal idéia, de acordo Card. (Card,
1999), é inovar, e gerar soluções teóricas para reforçar a teoria geral. Algumas das quais
serão comentadas a seguir.

1.5.1 Tamanho
Um exemplo do uso de tamanho para codificar dados pode ser visualizado em
um projeto de um circuito elétrico. Um círculo é sobreposto em componentes de
interesse (Figura 1-5), o tamanho de cada círculo indica a extensão da influência
daquele componente em relação a uma propriedade do circuito. Quando o projetista
altera um componente, automaticamente os tamanhos se ajustam, afim de que o
projetista possa perceber a influencia de sua mudança nos pontos em estudo (Spence,
2001).
21

Figura 1-5– Utilização do tamanho para codificação de dados (Spence, 2001).

1.5.2 Comprimento e Altura


Dados numéricos codificando por comprimento ou altura são populares. E
normalmente são utilizados quando um sentimento qualitativo para os dados é
necessário, e pode ser útil para fazer comparações (Spence, 2001). A Figura 1-6 mostra
um usuário analisando as constantes mudanças de altura das barras, conforme ele altera
os parâmetros da aplicação.

Figura 1-6 – Codificação de dados pela altura (Spence, 2001).

1.5.3 Espacialidade e Ampliação


É possível utilizar o conhecimento prévio do usuário para codificar dados, e
gerar novos conhecimentos. É possível utilizar o conhecimento sobre o Atlas mundial
22
convencional para codificar dados geográficos. Por exemplo, sabendo a posição de um
determinado país, o usuário poderá saber a população do mesmo e comparar por
tamanho com outro país (Figura 1-7) (Spence, 2001).

Figura 1-7 – Codificação de dados com conhecimento prévio do usuário (Spence, 2001).

1.5.4 Faces e Ícones Multidimensionais


Professor Herman Chernoff, um estatístico da Universidade de Stanford,
observou que os seres humanos são muito sensíveis a uma grande variedade de
expressões faciais e aparências. Assim, sugeriu que características faciais como o
tamanho dos olhos (Figura 1-8), altura de sobrancelhas, tamanho do nariz e forma da
boca pudessem representar vários atributos, uma vez que são bastante numerosos em
uma caricatura de face (Spence, 2001).

Figura 1-8– Faces de Chernoff (Spence, 2001).


Uma face de Chernoff é um exemplo de um ícone multidimensional. Chernoff
chegou a codificar 18 atributos em uma face. Não é difícil de propor outros ícones
multidimensionais que se destinem as tarefas diferentes e domínios diferentes, por
exemplo, procura de imóveis para compra ou aluguel em um classificado. A cor
codifica uma faixa de preço (vermelho é R$ 500.00,00 a R$ 4000.000,00 e branco de
23
R$ 50.000,00 a R$ 100.000,00), um pequeno desenho para o tipo de moradia: casa, casa
flutuante, apartamento, ou cabana (variável categórica), o número de quartos foi
indicado pelo número de janelas, e estes eram coloridos de preto ou branco para
caracterizar o bom estado de conservação do imóvel, existe ainda informações sobre
tamanho de jardim, presença de uma garagem, aquecimento central, tempo da moradia
ao centro da cidade (Spence, 2001). Portanto, são representadas oito dimensões (Figura
1-9).

Figura 1-9 - Ícones Multidimensionais aplicados ao mercado imobiliário (Spence, 2001).

1.5.5 Som
Infelizmente o termo 'visualização' contém o termo 'visual', mas uma
representação de dados por som – por si só ou combinada com apresentação visual - tem
muito para oferecer. Freqüentadores de concertos e fãs de bandas de rock são capazes
não só de identificar os instrumentos musicais diferentes, entre vinte ou mais, mas
também as notas diferentes, cordas, tempo, e ritmo em que estão sendo tocadas. Assim,
o potencial uso do som para codificar dados parece considerável. Por exemplo, ao usar
um banco 24 horas as pessoas estão acostumadas a ouvir um 'bip' indicando uma
mudança de estado da máquina, um modo muito simples, mas extremamente eficiente
de codificar dados em som e permitir visualizar assim o estado da máquina (Spence,
2001).

1.5.6 Mundos Virtuais


Ao ver uma página de Web, percebe-se que milhares de outras pessoas podem
estar vendo a mesma página simultaneamente. Não obstante, a pessoa não tem nenhum
modo de ter certeza. Porém, uma observação mais interessante é a impossibilidade de
interação social com eles: Não há oportunidade de lhes perguntar sobre o conteúdo
sendo visto ou de conhecer alguém com interesses semelhantes. Para superar estas
restrições, têm-se feito pesquisas sobre mundos virtuais tridimensionais compartilhados
por diversos usuários. Em tais mundos uma pessoa pode explorar, socializar, adquirir
24
informação, ensinar, jogar, e em geral fazer a maioria das coisas possíveis no mundo
real (Sherman, 2003).
O conceito de mundos virtuais identifica muitos assuntos de visualização. Um
deles é representar o usuário dentro do mundo virtual. Uma abordagem óbvia é
empregar uma representação tão semelhante quanto possível do usuário. Mas por muitas
razões, como privacidade, pode ser preferida uma representação simbólica.

1.5.7 Cor
Como já demonstrado anteriormente, dados numéricos podem ser codificados
através de cor. Uso de cor deve ser utilizado com cautela. Por exemplo, não utilizar
cores semelhantes para dados muito próximos, pois poderá prejudicar a percepção do
usuário. Cores em escala representam magnitude, e uma escolha popular é o espectro de
freqüência, com elementos grandes denotando vermelho e azul para os elementos
pequenos (Spence, 2001).

1.6 Técnicas de visualização


A seguir serão comentadas algumas técnicas de visualização de dados (Chen,
1999) (Brath, 1999), (Spence, 2001) e (Furuhata, 2004) (Freitas, 2001).
Uma abordagem para a exibição de dados unidimensionais, que pode ser
estendido para dados multidimensionais, envolve o uso de histogramas (Figura 1-10).
Enquanto um histograma separado associado com cada variável é de uso limitado, dois
melhoramentos podem conduzir a uma ferramenta de visualização extremamente útil.
Primeiro, utilizar uma escala com limites ajustáveis por meio dos quais um subconjunto
dos dados pode ser identificado. Segundo, deve-se assegurar que os objetos sejam
identificados por todos os conjuntos de limites que são codificado por cores. A exibição
fica muito mais “interessante” agora como a influência de uma variável sobre a(s)
outra(s), podendo ser explorado manualmente.
25
Figura 1-10 - Histogramas inter-relacionados (Spence, 2001).
O desafio de visualizar dados multivariados é contínuo, e certamente motivado
pelas muitas situações nas quais os inter-relacionamentos entre as muitas variáveis são
de interesse vital. Diagramas de coordenadas paralelas (Inselberg, 1998; Wegman,
1990) oferece uma técnica que pode controlar um número grande de variáveis. O
princípio é simples: tomar todos os eixos do espaço multidimensional e os organizar em
ordem, mas paralelo um ao outro, e poder ser estendido a qualquer número de variáveis,
como ilustrado na Figura 1-11.

Figura 1-11- Diagramas de coordenada paralelos aplicado a seis variáveis. (Wegman, 1990)
Árvore de cones (Figura 1-12) e perspective wall (Figura 1-13) usam uma
representação tridimensional para permitir ao usuário uma visão geral ou uma visão
com detalhes. Nenhuma das duas técnicas tem como objetivo filtrar informação nem de
permitir a escolha de novas representações. Contudo, no modelo perspective wall é
possível realizar pesquisa, isso não implica em filtrar dados, uma vez que a informação
é apresentada sempre na sua totalidade, havendo uma adaptação da representação de
forma a salientar o foco de interesse do usuário.

Figura 1-12: Árvore de Cone.


26

Figura 1-13: Perspective Wall (Freitas, 2001).


Árvore hiperbólica (Figura 1-14) é uma técnica de distorção que exibe
hierarquias com grandes quantidades de dados. O usuário pode interagir mudando o
foco dos dados, assim a árvore se reorganiza dinamicamente. É possível ter vários
níveis hierárquicos de dados.

Figura 1-14: Árvore hiperbólica (Freitas, 2001).


A técnica de Treemap foi desenvolvida por Johnson e Shneiderman
(Shneiderman, 1996), utilizando o espaço da tela para representar os dados. Nesta
técnica (Figura 1-15), uma estrutura hierárquica é representada pela subdivisão
sucessiva do espaço de tela. Cada subespaço representa um novo nível hierárquico.

Figura 1-15: Treemap (Freitas, 2001).


Rede de dados ou rede de conectividade de dados (Figura 1-16) permite ao
usuário perceber o relacionamento entre os dados, e assim descobrir padrões entre eles.
27
É muito simples identificar subgrafos não conectados. Pode-se usar cores, largura dos
links de ligações entre os nós, direção dos links, tamanho dos nós, para representar
outros atributos (Spence, 2001).

Figura 1-16- Métodos de codificar parâmetros que caracterizam uma ligação (Spence,
2001).

1.7 Aplicações
A seguir serão apresentadas algumas ferramentas de visualização de dados
(Chen, 1999) (Brath, 1999), (Spence, 2001) e (Furuhata, 2004). A maioria delas será
voltada para ambientes virtuais tridimensionais, contudo as bidimensionais mais
famosas na literatura também serão citadas.

1.7.1 SpotFire.
SpotFire (Figura 1-17), assim como outras ferramentas, faz uso das técnicas de
consultas dinâmicas, que permite que um usuário formule um problema
simultaneamente com sua resolução, relatado primeiramente por Williamson e
Shneiderman (Shneiderman, 1994). O SpotFire usa uma diagrama de dispersão, pode
utilizar outros gráficos simultâneos, que dada uma coleção de objetos, cada um descrito
pelos valores associados com um conjunto de atributos, é possível achar o mais
aceitável de tais objetos ou, talvez, um número pequeno de objetos candidatos
merecedor de uma consideração mais detalhada. E pode ser aplicado em qualquer área
do conhecimento. Mais detalhes em http://www.spotfire.com.
28

Figura 1-17- O uso de consultas dinâmicas aplicadas à seleção de um filme no Spot Fire
(Spence, 2001).

1.7.2 Paralax.
O software (Figura 1-18) está baseado em Coordenadas Paralelas que são uma
metodologia para visualização não ambígua de dados e relações multivariadas. A
descoberta de relações multidimensionais em um conjunto de dados é transformada em
um problema bidimensional de reconhecimento de padrão. A interface oferece
descobertas visuais, através de consultas com operadores booleanos, de relações
complexas em conjunto de dados de multivariados. Mais detalhes em:
http://www.kdnuggets.com/software/parallax/
29

Figura 1-18– Paralax (Spence, 2001).

1.7.3 Treemap
Treemap (Figura 1-19) é um método de visualização capaz de representar
grandes coleções de dados que possuem hierarquia entre si em um espaço limitado,
como o monitor de vídeo, e consiste em dividir a área de visualização em seqüências de
retângulos cujas dimensões são definidas por um atributo dos dados. A peça chave de
um treemap é o algoritmo usado para criar os retângulos que o compõem, o original é o
“slice and dice”. Outros algoritmos já foram propostos para solucionar algumas
desvantagens do algoritmo original. Mais detalhes em
http://www.cs.umd.edu/hcil/treemap-history.
30

Figura 1-19– Ferramenta Treemap (Spence, 2001).

1.7.4 Eureka - LENTE DE MESA


Lente de mesa (Figura 1-20) apresenta conjunto de grande quantidade de dados
de múltiplas variáveis em linhas e colunas, com dois (ou mais) níveis simultâneos de
detalhe. Quando o dado é apresentado como linhas finas, a informação é muito densa.
Isso permite que o usuário tenha uma visão geral dos dados, e decidir que dados valem a
pena detalhar. Mais detalhes em http://www.inxight.com.

Figura 1-20– Aplicação Lente de mesa.


31
1.7.5 ThemeScape
ThemeScape (Figura 1-21) desenvolvido pelos Laboratórios Noroestes Pacífico,
tenta organizar dados altamente multidimensionais como paisagens tridimensionais de
terreno. A representação resultante mostra áreas de relações fortes como montanhas.
Bandeiras ao topo da montanha identificam elementos comuns.

Figura 1-21– Aplicação ThemeScope.

1.7.6 NetViz
O software NetViz (Figura 1-22) auxilia organizações a entender e administrar
sua tecnologia de informação e sistema empresarial. Importa dados de vários tipos de
fonte, e é baseada na representação de rede de dados.
32

Figura 1-22: Uma representação de rede de dados em 3D (Furuhata, 2004).


A técnica de histograma é uma técnica tipicamente bidimensional. Contudo, sua
idéia pode ser estendida e adaptada pra o espaço tridimensional (Figura 1-23). Seu uso é
bastante tradicional e pode ser utilizada com outras técnicas e metáforas, por exemplo,
mapas ou redes de dados (Figura 1-24).

Figura 1-23: Operação de seleção de dados em um “histograma” tridimensional no SAGE


http://www.cs.cmu.edu/Groups/sage/sage.html (Spence, 2001).
33

Figura 1-24- Visualização de tráfego no backbone da NSFNET (Chen, 1999).

1.7.7 Máquina de busca AMORE (Advanced Multimedia Oriented


Retrieval Engine)
É uma máquina de busca que retorna sua consulta dentro de um cubo (Figura
1-25). Conforme a posição do documento, ele pode ter uma característica mais ou
menos forte do que o resultado ideal (Chen, 1999).

Figura 1-25- Estrutura do AMORE

1.7.8 Espaço Hiperbólico


O espaço hiperbólico (Figura 1-26) segue a técnica de árvores hiperbólicas, mas
agora em três dimensões. Mais detalhes em http://graphics.stanford.edu/~munzner/h3/
34

Figura 1-26– Espaço hiperbólico em três dimensões.

1.7.9 Cat-a-Cone
É uma ferramenta para categorização de documentos. Os usuários navegam pela
árvore de cones até o livro de desejado, e uma representação virtual do livro se torna
disponível (Figura 1-27).

Figura 1-27– Busca utilizando árvore de cones.


35
Outro exemplo de navegação por árvore de cone é no LyberWorld para
visualização de documentos (Figura 1-28). Mais detalhes em:
http://www.darmstadt.gmd.de/ ~hemmje/Activities/ Lyberworld/

Figura 1-28– LyberWorld como exemplo da utilização da técnica de árvore de cones.

1.7.10 Perspective Wall


Com a técnica perspective wall o usuário terá uma visão de dados em foco,
podendo rapidamente navegar na linha do tempo para poder analisar dados passados ou
futuros (Figura 1-29). Como dito anteriormente não há filtro, pois todos os dados no
período são mostrados.

Figura 1-29– Aplicação que utiliza Perspective Wall.


Há várias aplicações que utilizam diferentes metáforas para representar
informações. Uma delas é para acompanhamento e gerenciamento do desenvolvimento
de um sistema computacional (Figura 1-30). As linhas de código são representadas por
36
prédios em uma cidade, quanto maior o prédio maior o número de linhas de um módulo.
As cores representam à última vez os módulos foram modificados ou executados sem
erros. Pode-se ter visão área da cidade e analisar o andamento do projeto todo (Panas,
2003).

Figura 1-30: Metáfora de cidade para gerenciamento de desenvolvimento de software


(Panas, 2003).
Um outro exemplo de metáfora é para acesso a um banco de dados com
informações musicais (Figura 1-31).

Figura 1-31- Usuário buscando informações em um banco de dados (Chen, 1999)

1.8 Estudo de Caso: Construção de um Protótipo para


Visualização de Informação Utilizando VRML e JAVA
Antes da concepção de uma ferramenta de visualização necessariamente precisa-
se conhecer os dados e o domínio onde eles serão aplicados. Não é fácil conseguir uma
base de dados privada de uma empresa multinacional conhecida. Assim, normalmente
se faz uso de bases de domínio público, podem-se achar várias em
37
http://www.ics.uci.edu/~mlearn/MLRepository.html. A base de dados usada neste
protótipo é domínio público e de aproximadamente 30.000 registros. São dados
referentes a 70 pacientes dependentes de insulina para o controle da diabete. Estes dados
incluem nível de glicose do sangue antes depois das refeições, o uso da insulina,
sintomas de hipoglicemia, atividades físicas relacionadas a um horário e dia.
Antes de se aplicar uma ferramenta de visualização de informação a uma base de
dados qualquer, é necessário garantir a consistência das informações armazenadas.
Nesta fase de preparação dos dados, deve-se eliminar informações nulas ou
redundantes, estabelecendo estratégias para o tratamento de valores não informados.
Ainda na fase de preparação, é feita a seleção das características mais adequadas
para a representação dos dados. Com o objetivo de reduzir o volume de informações
tratadas pela ferramenta de visualização, os atributos considerados irrelevantes ou
redundantes são eliminados. A seleção dos atributos é uma atividade importante e
aconselhável, mas deve ser realizada cuidadosamente. Em alguns casos, a eliminação de
atributos supostamente irrelevantes prejudica a descoberta de informações realmente
surpreendentes.
Outra atividade de preparação é a codificação dos dados. É geralmente
interessante transformar dados quantitativos em categóricos, estipulando-se uma
identificação para cada intervalo. Por exemplo, o atributo Idade poderia ser
representado por faixa etária. Esta medida reduz o tempo de processamento e favorece
compreensão das informações visualizadas.
Para tornar o desenvolvimento mais eficiente, principalmente na parte de
colaboração, foi utilizado um middleware que trata toda a comunicação de uma
aplicação de realidade virtual colaborativa usando protocolos padrões da Internet
(Meiguins 2004). Resumidamente, faz uso do protocolo TCP/IP e mensagens padrões.
Foram concebidos dois módulos, um para o cliente e um outro para o servidor. O
módulo cliente pode ser dividido em duas grandes partes, uma chamada de aplicação e a
outra de infra-estrutura para comunicação. Na primeira parte do módulo cliente,
encontra-se a aplicação genérica com seus vários módulos, tais como, visualizador 3D,
visualizador Web, vídeo, etc., já a segunda parte, chamada de infra-estrutura de
comunicação, tem a função de receber e tratar a interação do usuário com qualquer um
dos componentes da aplicação, e tomar as decisões necessárias para que os outros
usuários possam perceber as ações do mesmo. Com isto, percebe-se que o módulo da
aplicação é independente, assim o processo de criação de novas aplicações fica
38
otimizado. A idéia principal do servidor é ser simples, onde seu principal objetivo é
replicar as mensagens pré-definidas da maneira mais eficiente possível. A Figura 1-32
mostra uma visão simplificada da arquitetura para um estudo de caso usando Java
(Horstmann, 2001), VRML (Roehl, 1997) e EAI (Roehl, 1997). A External Authoring
Interface faz a comunicação entre a applet Java e o ambiente tridimensional modelado
em VRML (Virtual Reality Modeling Language). A Applet se comunica com um
servidor Web onde esta o servidor de aplicação que faz uma consulta a um banco de
dados, tudo isso através de mensagens padronizadas.

USUÁRIO11 USUÁRIO22 ... USUÁRIONN


USUÁRIO USUÁRIO USUÁRIO

APPLETJAVA
JAVA Ambiente3D
Ambiente 3D Ambiente3D
Ambiente 3D
APPLET
Compartilhado
Compartilhado Individual
Individual

Basede
Base de
EAI
Dados
Dados

Servidor JDBC//ODBC
JDBC ODBC
Servidor

Figura 1-32 - Arquitetura da aplicação


A aplicação cliente é caracterizada por três partes principais: duas delas são
ambientes virtuais tridimensionais, um para a visão compartilhada, ou seja, qualquer
modificação que um usuário fizer será vista por todos, e o outro ambiente virtual é para
visão individual, que pode ter uma visão diferente da visão compartilhada. A terceira
parte é uma applet que permite ao usuário personalizar a consulta tanto para o ambiente
compartilhando quanto para o individual, bem como trocar informações com outros
usuários. As três partes estão embutidas em uma página Web (Figura 1-33).
39

Figura 1-33 : Protótipo de Visualização de Informação 3D Colaborativa Baseado na Web.


O ambiente virtual tridimensional exibe um plano onde o gráfico 3D é gerado de
acordo com a solicitação do usuário. O usuário solicita a geração do gráfico de
informações selecionando algumas opções, tais como: ano, mês e paciente a ser
visualizado. Após esta primeira seleção o usuário poderá interagir tanto no ambiente
tridimensional através de zoom, rotação, etc, como na applet através dos atributos dos
campos Insulina, Glicose no Sangue, Refeição e Atividade Física. O gráfico a ser
gerado pode ser tanto Mensal quanto Anual, ambos representados nas Figuras Figura
1-34 e Figura 1-35 respectivamente.

Figura 1-34: Ambiente Tridimensional Figura 1-35 : Ambiente Tridimensional


Compartilhado Mensal. Individual Anual.
40
O processo de montagem de uma representação mensal, por exemplo, passa por
uma consulta ao banco de dados agrupando os dados de um paciente de acordo com os
parâmetros (ano, mês e paciente), que são capturados das respectivas barras de rolagem.
Ao clicar no botão visualizar, uma mensagem será enviada ao servidor com esses
parâmetros. Um processo gerenciador do banco de dados é o responsável por realizar
esta consulta. No caso de uma consulta mensal, será retornado um vetor com
informações classificadas por dia, envolvendo cada uma das informações disponíveis e
solicitadas pelo usuário.
De posse dessas informações, uma classificação é feita por blocos de
informações. As quatro colunas existentes na visualização correspondem
respectivamente às informações sobre Insulina, Glicose no Sangue, Refeição e
Atividade Física, ou seja, se a informação for relacionada a uma medição durante uma
refeição, ela será inserida na terceira coluna.
Nas visualizações geradas foram utilizadas cores e formas geométricas
diferentes para representar os diferentes dados e suas grandezas, as cores fornecem os
diversos atributos, e a forma está relacionada ao valor numérico do dado (dependendo
do filtro de dados: anual, mensal). Por exemplo, para unidade (paralelepípedo), dezena
(cone), centena (cilindro), milhar (elipse), etc, esta diferenciação nas grandezas e
atributos se deu pela grande diferença entre os valores dos mesmos. Para saber o valor
real de qualquer atributo basta passar o mouse sobre o dado desejado (Figura 1-36).

Figura 1-36 - Técnica de Brush utilizada no protótipo.


41
Os elementos do ambiente virtual (AV) foram construídos em VRML, o código
para uma forma geométrica pode ser visto na Figura 1-37.

Shape { Shape { Shape { Shape {


appearance Appearance appearance Appearance appearance Appearance appearance Appearance
{ { { {
material Material { material Material { material Material { material Material {
diffuseColor 0 .36 .8 diffuseColor 1 .36 .1 diffuseColor 0 1 0 diffuseColor .5 .36 .5
} } } }
} } } }
geometry Cone { geometry Cylinder {
geometry Box { geometry Sphere { height 0.1 height 0.1
size 0.1 0.1 0.1 radius 0.1 bottomRadius 0.1 radius 0.1
} } } }
} } } }
Figura 1-37 – Formas básicas
Neste exemplo (Figura 1-38), têm-se exemplos de várias formas para representar
os tipos de dados. Como mencionado anteriormente, uma cor representa o tipo de dado
(por exemplo, uma medida de glicose) que se está analisando. Em termos de código isto
é configurado no campo diffuseColor. O tamanho do objeto representa, por exemplo, a
quantidade medida de glicose depois do almoço. Para esta representação utiliza-se um
multiplicador sobre o objeto chamado scale apenas no eixo Y (Figura 1-39). O valor 15
em scale significa 15 mg / dl (miligramas por decilitro).
Código em VRML Imagem do Objeto
Transform {
scale 1 15 1
children [
Shape {
appearance Appearance
{
material Material {
diffuseColor .5 .36 .5
}
}
geometry Cylinder {
height 0.1
radius 0.1
}
}
]
}
Figura 1-38– Alteração do tamanho do objeto
Essa construção basicamente é baseada em protótipos (). São utilizadas
informações do banco de dados, como o código do tratamento e a quantidade da
medição para a criação de um objeto baseado no protótipo. O campo posição depende
do grupo do código da informação (Insulina, Glicose no Sangue, Refeição e Atividade
Física).
42

PROTO Informacao [
exposedField SFVec3f posicao 0 0 0
exposedField SFColor cor 0 0 0
field SFFloat qtdade 0
]
Figura 1-39 – Protótipo para a exibição de uma informação do banco de dados
A exibição da quantidade no AV o deixaria extremamente poluído visualmente.
Para contornar esta situação, faz-se uso de sensores em cada objeto (Figura 1-40). Desta
forma ao passar o mouse sobre um determinado objeto, o usuário terá um painel
mostrando o valor real associado.
Transform {
scale 1 15 1
children [
Shape {
appearance Appearance
{
material Material {
diffuseColor .5 .36 .5
}
}
geometry Cylinder {
height 0.1
radius 0.1
}
}
DEF Toque TouchSensor {}
]
}

Figura 1-40 - Utilização de sensores em cada objeto.


Além disso, é preciso usar scripts para controlar este processo interativo (Figura
1-41).
DEF ScriptObjeto Script {
eventIn SFBool sobreSensor
eventOut MFString texto"
field SFString valorReal parametro
url "javascript:
function sobreSensor(value, time){
if (value == true)
texto[0] = 'qtdade: ' + valorReal;
else
texto[0] = '’;
}
"
}

Figura 1-41 - Script


O que acontece aqui é que quando o usuário “sobrevoar” com o mouse o objeto,
um evento sobreSensor será gerado e capturado pelo script. De acordo com um valor
valorReal passado como parâmetro, será inserido um texto sobre o objeto
correspondente a quantidade medida do respectivo dado sobre o paciente (Figura 1-42).
43

Figura 1-42– Utilização de sensor e script para controlar a interação do usuário sobre um
objeto
Na applet, podem-se encontrar cinco áreas principais (Figura 1-43). A primeira
trata dos pontos de visões disponibilizadas no ambiente, tais como, visão frontal, aérea,
etc. como também movimentos que não foram pré-definidos anteriormente utilizando as
barras de rolagem para interagir no ambiente. A segunda área trata da troca de
informações entre os usuários de modo textual, além de guardar o histórico das trocas
de informações. No campo histórico também ficam registradas as ações dos usuários,
que podem pode ser inserção, remoção, construção do plano e troca de mensagens entre
os usuários que compartilham o ambiente. A terceira área trata da configuração do plano
tais como escolher qual o tipo de gráfico 3D a ser gerado (Mensal ou Anual), o plano a
ser colocado o gráfico (Compartilhado ou Individual), ano, paciente e o mês quando
necessário. Todo novo plano inserido é colocado no lugar do anterior. A quarta parte
trata da visualização ou não dos dados contidos no gráfico gerado, o estado default é
inserir todos os dados da consulta baseado no ano, mês (opcionalmente) e paciente.

Figura 1-43: Applet do Web Info 3D.

Caso o usuário não queira visualizar certos dados, basta desmarcar a opção
referente a uma determinada medição para realizar a ocultação no AV. Ao fazer isso,
uma mensagem é enviada para cada objeto com alteração do valor do campo
transparency correspondente às características de cor do objeto (Figura 1-44Figura
1-44).
44
Shape {
appearance Appearance {
material Material {
transparency 0.8
}
}
geometry Box {}
}

Figura 1-44– Utilização da transparência para ocultação de dados.

As figuras a seguir mostram as instancias da aplicação para dois usuários


diferentes.

Figura 1-45: Instancia do Protótipo com o Usuário Bianchi.


45

Figura 1-46: Instância do Protótipo com o Usuário Rosevaldo.

1.9 Referências deste capítulo

Brath, Richard Karl Effective Information Visualization Guidelines and Metrics for 3D
Interactive Representations of Business. Master Project of Toronto University. 1999
Data. Disponível em: http://www3.sympatico.ca/blevis/thesis49toc.html
Card, S., Mackinlay, J., and Shneiderman, B. eds. Readings in Information
Visualization Using Vision to Think. Morgan Kaufmann, 1999.
Carr, D. A. Guidelines for Designing Information Visualization Applications. 2004
(disponível em: http://www.sm.luth.se/~david/papers/VizGuidelines.pdf
Chen, Chomei. Information Visualization and Virtual Environments, Springer, 1999.
Freitas, Carla M. Dal Sasso et. al. Visualização de Informações. RITA - Volume VIII -
Número 2 - págs. 143-158, Porto Alegre - RS, 2001.
Furuhata, R.; Fujishiro, I.; Maekawa, K; Yamashita, Y. Information Visualization and
Visualization Techniques. 2004. Disponível em:
http://www.imv.is.ocha.ac.jp/MIKY/
Horstmann, Cay S., Cornell, Gary. Core Java 2 – Volume II – Recursos Avançados,
Makron Books, São Paulo, 2001.
Meiguins, Bianchi S., Guedes, Luis A., Araújo, Marcos V., Garcia, Marcelo B., Souza,
Rosevaldo D. A Proposal for Collaborative Virtual Environments Architecture Using
Internet Patterns. Proceedings of IASTED International Conference on Software
Engineering (SE 2004). Innsbruck, Austria. 2004.
46
Panas, T.; Berrigan, R.; Grundy, J. A 3D Metaphor for Software Production
Visualization. Proceedings of the Seventh International Conference on Information
Visualization (IV’03). IEEE. 2003
Roehl. B.; et al. Late Night VRML 2.0 with Java. ZD Press. Emeryville, California.
1997.
Shneiderman, B. The eyes have it: a task by data type taxonomy for information
visualizations, Procedings of 1996 IEEE Visual Language. 336-343
Shneiderman, B., Dynamic queries for visual information seeking, IEEE Software 11, 6
(1994), 70-77.
Spence, Robert. Information Visualization. Addison-Wesley. 2001.
Inselberg, A. Multidimensional Detective, IEEE, Proceedings of Information
Visualization’97, pág.100-107, 1998.
Wegman, E. J. Hyperdimensional Data Analysis Using Parallel Coordinates, Journal of
the American Statistical Associations, pág. 270 – 277, 1990
Sherman, William R., Craig, Alan B. Understanding Virtual Reality: Interface
Application and Design. Morgan Kaufmann Publishers. 2003
47

2 RV suportada pelas tecnologias VMRL e X3D

Alexandre Cardoso1, Luciano Pereira Soares 2


1
Faculdade de Engenharia Elétrica – Universidade Federal de Uberlândia
Av. João Naves de Ávila, 2121 – Uberlândia - MG – Brasil

2
VR Centre - CAVERNA Digital LSI - POLI - USP
Av. Prof. Luciano Gualberto,158 trav.3 CEP 05508-900 São Paulo/SP/Brazil

2.1 Introdução
VRML tem uma história fundamentada na colaboração de diversos
pesquisadores e importantes empresas relacionadas com a Computação Gráfica e
Realidade Virtual.
O Scenario nasce a partir de um projeto, iniciado em 1989, na Silicon Graphics
Inc. por Rikk Carey e Paul Strass, fundamentada em duas características básicas:
capacidade de criação de uma gama variada de aplicações 3D e a possibilidade de usar
este ambiente para construir uma nova interface para 3D.
Em 1992, baseado nas proposições do Scenario, surge o Iris Inventor 3D, uma
ferramenta fundamentada em C++ que, posteriormente, fundamenta muito da semântica
de VRML. A revisão do Inventor realizada em 1994 origina o Open Inventor
caracterizada por sua portabilidade a uma grande variedade de plataformas e baseada no
Open GL da Silicon. O manual de referência da mesma descrevia os objetos e formatos
de arquivos que, adequados por Gavin Bell, originariam a especificação da primeira
versão da Virtual Reality Modeling Language, VRML 1.0.
Em 1994, Mark Pesce e Tony Parisi construíram um protótipo de um navegador
3D para a World Wide Web - WWW, chamado Labyrinth. Um ano depois, Mark e Brian
Behlendorf criaram a lista de discussão do VRML e publicaram uma chamada para
propostas de uma especificação formal para 3D na WWW.
De discussões nesta lista, iniciadas por Gavin BellI, usando como ponto de
partida o manual do Inventor nasce a especificação do VRML 1.0. Em 1995, o VRML
1.0 foi alvo de muitas correções e novas discussões, de forma que nasce a proposta de
uma segunda especificação, a do VRML 1.1 (ou VRML 2.0).
48
Aprimorada e capaz de definir comportamentos (com mais interação e
animação) para elementos 3D, a nova proposição foi submetida à lista em 1996. As
propostas apresentadas pela Silicon em colaboração com a Sony e com a Mitra
receberam a grande maioria dos votos e originaram o documento de definição de
VRML 2.0. Em agosto de 1996, esta versão foi publicada no SIGGRAPH´96 em New
Orleans.
A versão final deste texto, com correções e modificações técnicas foi publicada
em Abril de 1997, definida como VRML´97. Suas principais características estão
relacionadas com o desenvolvimento de cenários mais realísticos, prototipação
(capacidade de encapsular novos recursos de forma a criar novos nós), interação direta
com o usuário através de sensores, interpoladores e criação de animações usando
scripts.
Desde então, VRML (Virtual Reality Modeling Language) tem sido aplicada em
diversos projetos para concepção de mundos virtuais [ELLIS 1994, CHEN 1997,
MATSUBA 1999, CARDOSO et al. 1999] e é uma importante aliada no
desenvolvimento de mundos tridimensionais interativos na Web.

2.1.1 VRML97

Arquivos que simulam ambientes tridimensionais em VRML, são na verdade


uma descrição textual, na forma de textos ASCii. Por meio de qualquer processador de
textos, o desenvolvedor pode conceber tais arquivos, salvá-los e visualizar resultados no
navegador de Internet associado a um plug-in interpretador de VRML. Estes arquivos
definem como estão as formas geométricas, as cores, as associações, os movimentos,
enfim, todos os aspectos relacionados com a idéia do autor [AMES 1997]. Quando um
dado navegador - browser - lê um arquivo com a extensão .wrl, o mesmo constrói o
cenário descrito, usando os recursos do plug-in compatível.
De forma simplificada, um arquivo VRML se caracteriza por quatro elementos
principais:

• Header – obrigatório;

• Prototypes – usado para descrever classes de objetos que podem ser usados na
descrição do cenário;

• Shapes, Interpolators, Sensors, Scripts – usados para descreverem o cenário que


se deseja construir;
49
• Routes – rotas: essenciais na definição de comportamento dos objetos que estão
descritos no cenário.

Nem todos os arquivos contêm todos estes componentes. Na verdade o único


item obrigatório em qualquer arquivo VRML é o cabeçalho (header). Porém, sem pelo
menos uma figura, o navegador não exibirá nada ao ler o arquivo. Outros componentes
que um arquivo VRML também pode conter:

• Comments;

• Nodes;

• Fields, field values;

• Defined node names;

• Used node names;

O cabeçalho (header) é composto pela instrução "#VRML V2.0 utf8" e sua


omissão impossibilita o plug-in do navegador de ler o arquivo em questão. Os
protótipos (proto) contém a definição de novos nós que podem ser usados no arquivo
em definição. A seção de descrição de formas (shapes etc) apresenta a descrição das
formas que serão exibidas no navegador e a seção de rotas (routes) contém a definição
das trocas de mensagens entre os nós de descrição de formas, interpoladores, sensores e
scripts.
A concepção de cenários tridimensionais, usando VRML, se baseia na
elaboração de uma grafo direcionado acíclico, contendo diferentes ramos - nós - que,
associados de forma correta podem ser agrupados ou estarem independentes uns dos
outros. A grande diversidade destes nós (54 pré-definidos), incluindo primitivas
geométricas, propriedades de aparência, sons (e propriedades) e vários tipos de nós de
agrupamentos, é uma das principais características e qualidades da linguagem.
É permitida reutilização de código através da prototipação, baseada na definição
de novos nós (protos) que podem ser utilizados por outros arquivos e ativados dentro de
um arquivo como um nó externo, sem duplicação de códigos. Ou senão, ser reconhecido
internamente pelo navegador utilizado.
A concepção de formas se dá através da associação de elementos 3D
geométricos pré-definidos, tais como Cones, Cilindros, Esferas, Caixas, etc que
possuem atributos variáveis e que podem estar associados a texturas.
50
A modificação de fundos de ambiente está possibilitada pelo uso de nós
específicos - backgrounds, - que permitem simular ambientes diferenciados que se
assemelham a condições que variam de um lindo dia de sol, um dia nublado ou com
muita neblina até a noites.
É possível o controle de aparência de elementos do cenário, bem como a
inserção de diferentes formas de fontes de luz (pontuais, direcionais, ambiente), visando
dar mais realismo ao cenário concebido. Recursos de acrescentar sons e filmes também
estão disponíveis por utilização de nós específicos e são compatíveis com os principais
formatos de áudio e vídeo: .mpeg, .mpg, .mid., .wav.
Podem ser elaborados scripts que facilitam as animações utilizando-se Java ou
JavaScript de forma a complementar a troca de informações entre os elementos do
mundo virtual. Esta propriedade provê possibilidade de animações e de dinamismo às
formas concebidas e inseridas no cenário. O código em JavaScript pode fazer parte do
arquivo original.

2.1.2 X3D
O X3D é um padrão aberto para distribuir conteúdos de realidade virtual em 3D,
em especial pela Internet. Ele combina tanto dados geométricos como descrições de
comportamentos instantâneos em um simples arquivo que tem inúmeros formatos de
transmissão, sendo que o padrão de codificação ideal é o XML (Extensible Markup
Language). O X3D é a próxima revisão da especificação ISO VRML97, incorporando
os avanços dos recursos disponíveis nos últimos dispositivos gráficos comerciais tanto
quanto melhoras na sua arquitetura baseado nos anos de retorno da comunidade de
desenvolvimento do VRML97. Este padrão esta sendo desenvolvido por um consórcio
internacional, conhecido como Web3D, que tem o objetivo de propor e manter o padrão,
e manter ele como um sistema aberto para a comunidade.
O X3D pode ser utilizado para Modelagem e animação, interação,
interoperabilidade com outras tecnologias da web, treinamento, visualização científica,
suporte a vendas, etc.
O XML foi adotado como sintaxe para o X3D para resolver um grande número
de problemas reais, A sintaxe do VRML 97 é estranha para todos com exceção da
comunidade do VRML. Ela é similar a sintaxe do grafo de cena do Open Inventor, na
qual foi baseada e algumas notações de objetos. Todavia, a sintaxe dominante na Web
51
atualmente é o XML. Linguagens de marcações tem provado ser a melhor solução para
o problema de um longo ciclo de vida de arquivamento de dados.
Integração baseada em páginas XML vai direto ao problema de manter o sistema
mais simples, assim mais pessoas podem desenvolver páginas web, tanto em conteúdo
como implementações. Extensível suporte ao XML é esperado na última versão do
Mozilla e do Internet Explorer. O X3D, como um formato que define informações
visuais, é tipicamente o último estágio em uma linha de produção. Usando um conjunto
de ferramentas disponíveis, como stylesheets, você pode trabalhar em qualquer formato
nativo XML que você queira, e ver que uma representação 3D é tão trivial quanto um
processo de transformação.
Existe uma Document Type Definition (DTD) para X3D, definida como parte do
padrão. A URL do DTD é: http://www.web3d.org/specifications/x3d-3.0.dtd. Também
existe um Schema para X3D aceito. Ele é definido como parte do padrão. A URL do
Schema é: http://www.web3d.org/specifications/x3d-3.0.xsd.
O X3D é um padrão aberto que não tem royalties associados com ele - você
pode usar livremente aonde você quiser. Não existe nenhum política de limite de
Propriedade Intelectual para a tecnologia, além de existir um acordo com a ISO para
publicar a especificação para o público sem nenhum custo.
Existe um esforço para um programa de conformidade para a especificação do
X3D que tem o objetivo de prover consistência e confiabilidade para as implementações
que suportem X3D pelos diversos vendedores das múltiplas plataformas, e para criar
uma definição objetiva de conformidade com o padrão X3D. Somente produtos que
passe pela conformidade poderão usar a marca registrada X3D.
Profiles e components são a nova forma do X3D de definir ambas,
extensibilidade e o conjunto de serviços que o conteúdo dos usuários necessita. Um
componente (component) define uma específica coleção de nós. Tipicamente esta
coleção tem em comum um conjunto de funcionalidades - por exemplo a estruturas
NURBS e as habilidades de texturização. Um componente (component) consiste da
definição dos nós e um conjunto de níveis que prove um cada vez maior conjunto de
implementações. Um nível simples requer apenas poucos nós e talvez uma seleção de
campos a serem suportados, enquanto que níveis maiores requerem todos os níveis mais
simples, mais nós mais complexos.
Por exemplo, o nível 1 de NURBS requer apenas linhas e curvas 2D básicas,
enquanto que o nível 4 requer, costura, junção e superfícies de revolução. Um perfil
52
(profile) é uma coleção de componentes para um específico nível de suporte. Um perfil
(profile) pode não conter outro perfil, porém ele necessita todos os mesmos
componentes (components) e níveis como outro perfil (profile), e ainda mais. Todos os
arquivos X3D requerem a definição do perfil (profile) que está em uso, na qual pode ser
suprida com a requisição de componentes adicionais pelo usuário - ou por níveis
maiores que aqueles providos pelo perfil (profile) ou que ainda não foram definidos no
perfile (profile). Empresas podem criar novos Componentes com suporte para seus
produtos e submetê-los para a diretoria do X3D para sua aprovação.
Quando um componente é submetido, este contém um prefixo para a empresa
que submete o componente similar como as extensões OpenGL que têm o prefixo da
empresa que criou a extensão. Componentes vão sofrer os testes e revisões pela diretoria
do X3D, o Consórcio Web3D e a comunidade como um todo. Uma vez que um
componente seja aceito e implementado por mais de uma empresa, o prefixo muda para
EXT_. Se o componente é classificado pela diretoria, ele então recebe o prefixo X3D_.
A diretoria pode julgar que certos componentes são tão largamente adotados e
importantes que deveriam ser incluídos em um conjunto de modificações para a
especificação ISO oficial. Uma vez que um grupo de componentes (components) e/ou
perfils (profiles) são julgados importantes para a inclusão através das várias aplicações,
uma nova versão do X3D pode ser criada incluindo, por padrão, um conjunto de perfis
(profiles).
Uma nova versão implica mais funcionalidade que as versões anteriores.
Empresas podem criar navegadores, ferramentas, importadores e exportadores X3D na
qual suportam diferentes versões, perfils (profiles) e componentes (components). Por
exemplo, um exportador para o 3DSMax que é usado nos ambientes de produção de
video-games pode suportar somente o perfil Interchange, enquanto que um plug-in para
navegador da Internet pode suportar o perfil Immersive ou Full.
As empresas não precisam suportar todos os Profiles, Components e Levels.
Perfis e componentes existem para que as empresas precisem somente suportar perfis e
componentes para suas necessidades. Por ter perfis, seus produtos podem ter certeza que
o conteúdo que eles lerem irá funcionar nas suas aplicações, e que aquele conteúdo que
eles criaram irá funcionar em outras aplicações que suportem seus componentes ou
perfis. Muitas empresas não vão querer suportar uma especificação grande e complexa
como o VRML97. Porém a estrutura modular do X3D significa que eles podem
começar suportando perfis (profiles) e componentes (components) simples, e
53
gradualmente adicionar perfis adicionais conforme eles se sentirem preparados. Por
haver empresas capazes de desenvolver componentes e submetê-los, o X3D força os
avanços da indústria a serem rápidos e eficientes. Isto também garante que o X3D
crescerá e florescerá, e não se tornará tecnicamente obsoleto.

Figura 2-1 – Diagrama de Profiles

2.2 Grafo de Cena

2.2.1 Definições básicas


A concepção de ambientes 3D deve começar pela definição de uma hierarquia e
de seus componentes. Como exemplo, para a construção de um avião, suas partes
devem ser definidas e agrupadas, hierarquicamente, através de um grafo de cena, como
pode ser visto na Figura 2-2.
Um nó é um componente construtivo do grafo de cena. No caso da Figura 2-2,
cada asa será um nó. Os nós podem ser outros grafos de cena e, sucessivamente,
definirem como cada instância primitiva será usada para montar o cenário final.
54

Figura 2-2 - Grafo de Cena para uma aeronave simples

Assim, a construção dos grafos de cena requer a união, usando a estrutura de


árvores ou de grafos direcionados acíclicos – DAG – de primitivas gráficas. Cada
componente do cenário final será uma associação de primitivas, que, no grafo de cena
representa um nó. Neste contexto, é muito importante o conhecimento das primitivas
disponibilizadas pela linguagem.
Cada primitiva Shape está associada a dois nós (necessariamente):
- nó aparência: que descreve a aparência final da forma;
- nó geometria: usado para definir a geometria da forma.
Estruturalmente, a sintaxe dos nós em VRML e X3D que permite acomodar a
definição das primitivas tem, portanto, o aspecto:
Forma Geométrica {
Definição da aparência {}
Definição da geometria{}
}
A seção seguinte apresenta alguns nós e suas definições.

2.2.2 Atributos
Os atributos declarados em cada nós podem conter um valor simples ou
múltiplos, isto é definido pelas duas primeiras letras. Caso o tipo do atributo comece
com SF (Single Field) somente suportará um valor, caso seja MF (Multiple Fields), este
suportara vários valores. Estes também podém se referenciar outros nós com o tipo
abstrato básico SFNode and MFNode.
55
Dentre os tipos básicos de atributos temos:
 Bool - para valores booleanos
 Color - para a descrição de RGB de uma dada cor
 ColorRGBA- para a descrição de RGBA de uma dada cor
 Double – para valores reais com altíssima precisão
 Image – para imagem
 Int32 - para valores inteiros
 FLoat - para valores reais
 Node - para a descrição de um nó
 Rotation – para os valores de uma rotação
 String – para um texto
 Time – para um valor de tempo
 Vec2d, Vec2f – para um vetor de 2 elementos de alta e menor precisão
 Vec3d, Vec3f – para um vetor de 3 elementos de alta e menor precisão

2.2.3 Nós em VRML e X3D

• Geometrias
Box : X3DGeometryNode {
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [] size 2 2 2 (0,∞ )
SFBool [] solid TRUE
}

Figura 2-3 — Nó Caixa


56
Cone : X3DGeometryNode {
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [] bottom TRUE
SFFloat [] bottomRadius 1 (0,∞ )
SFFloat [] height 2 (0,∞ )
SFBool [] side TRUE
SFBool [] solid TRUE
}

Figura 2-4 – Nó Cone


Cylinder : X3DGeometryNode {
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [] bottom TRUE
SFFloat [] height 2 (0,∞ )
SFFloat [] radius 1 (0,∞ )
SFBool [] side TRUE
SFBool [] solid TRUE
SFBool [] top TRUE
}

Figura 2-5 – Nó Cilindro


ElevationGrid : X3DGeometryNode {
MFFloat [in] set_height
SFNode [in,out] color NULL [X3DColorNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFNode [in,out] normal NULL [X3DNormalNode]
SFNode [in,out] texCoord NULL [X3DTextureCoordinateNode]
SFBool [] ccw TRUE
SFBool [] colorPerVertex TRUE
SFFloat [] creaseAngle 0 [0,∞ )
MFFloat [] height [] (-∞ ,∞ )
SFBool [] normalPerVertex TRUE
SFBool [] solid TRUE
SFInt32 [] xDimension 0 [0,∞ )
Figura 2-6 – Nó ElevationGrid
SFFloat [] xSpacing 1.0 (0,∞ )
SFInt32 [] zDimension 0 [0,∞ )
SFFloat [] zSpacing 1.0 (0,∞ )
}
57
Extrusion : X3DGeometryNode {
MFVec2f [in] set_crossSection
MFRotation [in] set_orientation
MFVec2f [in] set_scale
MFVec3f [in] set_spine
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [] beginCap TRUE
SFBool [] ccw TRUE
SFBool [] convex TRUE
SFFloat [] creaseAngle 0 [0,∞ )
MFVec2f [] crossSection [1 1 1 -1 -1 -1 -1 1 1 1] (-∞ ,∞ )
SFBool [] endCap TRUE
MFRotation [] orientation 0 0 1 0 [-1,1] or (-∞ ,∞ )
MFVec2f [] scale 11 (0,∞ )
Figura 2-7 – Nó Extrusion
SFBool [] solid TRUE
MFVec3f [] spine [0 0 0 0 1 0] (-∞ ,∞ )
}
IndexedFaceSet : X3DComposedGeometryNode {
MFInt32 [in] set_colorIndex
MFInt32 [in] set_coordIndex
MFInt32 [in] set_normalIndex
MFInt32 [in] set_texCoordIndex
SFNode [in,out] color NULL [X3DColorNode]
SFNode [in,out] coord NULL [X3DCoordinateNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFNode [in,out] normal NULL [X3DNormalNode]
SFNode [in,out] texCoord NULL [X3DTextureCoordinateNode]
SFBool [] ccw TRUE
MFInt32 [] colorIndex [] [0,∞ ) or -1 Figura 2-8 – Nó IndexedFaceSet
SFBool [] colorPerVertex TRUE
SFBool [] convex TRUE
MFInt32 [] coordIndex [] [0,∞ ) or -1
SFFloat [] creaseAngle 0 [0,∞ )
MFInt32 [] normalIndex [] [0,∞ ) or -1
SFBool [] normalPerVertex TRUE
SFBool [] solid TRUE
MFInt32 [] texCoordIndex [] [-1,∞ ) Figura 2-9 – Texture para IndexedFaceSet
}
Sphere : X3DGeometryNode {
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFFloat [] radius 1 (0,∞ )
SFBool [] solid TRUE
}

Figura 2-10 – Nó Esfera


58
IndexedLineSet : X3DGeometryNode {
MFInt32 [in] set_colorIndex
MFInt32 [in] set_coordIndex
SFNode [in,out] color NULL [X3DColorNode]
SFNode [in,out] coord NULL [X3DCoordinateNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFInt32 [] colorIndex [] [0,∞ ) or -1
SFBool [] colorPerVertex TRUE
MFInt32 [] coordIndex [] [0,∞ ) or -1
} Figura 2-11 – Nó IndexedLineSet
PointSet : X3DGeometryNode {
SFNode [in,out] color NULL [X3DColorNode]
SFNode [in,out] coord NULL [X3DCoordinateNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
}

Figura 2-12 – Nó PointSet


Text : X3DGeometryNode {
SFNode [in,out] fontStyle NULL [X3FontSyleNode]
MFFloat [in,out] length [] [0,∞ )
SFFloat [in,out] maxExtent 0.0 [0,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFString [in,out] string []
SFBool [] solid FALSE
}
Figura 2-13 – Nó Text

Group : X3DGroupingNode {
MFNode [in] addChildren [X3DChildNode]
MFNode [in] removeChildren [X3DChildNode]
MFNode [in,out] children [] [X3DChildNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [] bboxCenter 000 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
}

Transform : X3DGroupingNode {
MFNode [in] addChildren [X3DChildNode]
MFNode [in] removeChildren [X3DChildNode]
SFVec3f [in,out] center 000 (-∞ ,∞ )
MFNode [in,out] children [] [X3DChildNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFRotation [in,out] rotation 0 0 1 0 [-1,1] or (-∞ ,∞ )
SFVec3f [in,out] scale 111 (0,∞ )
SFRotation [in,out] scaleOrientation 0 0 1 0 [-1,1] or (-∞ ,∞ )
59
SFVec3f [in,out] translation 000 (-∞ ,∞ )
SFVec3f [] bboxCenter 000 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
}

Shape : X3DShapeNode {
SFNode [in,out] appearance NULL [X3DAppearanceNode]
SFNode [in,out] geometry NULL [X3DGeometryNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [] bboxCenter 0 0 0 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
}

Appearance : X3DAppearanceNode {
SFNode [in,out] fillProperties NULL [FillProperties]
SFNode [in,out] lineProperties NULL [LineProperties]
SFNode [in,out] material NULL [X3DMaterialNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFNode [in,out] texture NULL [X3DTextureNode]
SFNode [in,out] textureTransform NULL [X3DTextureTransformNode]
}

Material : X3DMaterialNode {
SFFloat [in,out] ambientIntensity 0.2 [0,1]
SFColor [in,out] diffuseColor 0.8 0.8 0.8 [0,1]
SFColor [in,out] emissiveColor 000 [0,1]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFFloat [in,out] shininess 0.2 [0,1]
SFColor [in,out] specularColor 000 [0,1]
SFFloat [in,out] transparency 0 [0,1]
}

Inline : X3DChildNode, X3DBoundedObject, X3DUrlObject {


SFBool [in,out] load TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFString [in,out] url [] [url or urn ]
SFVec3f [] bboxCenter 0 0 0 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
}

Background : X3DBackgroundNode {
SFBool [in] set_bind
MFFloat [in,out] groundAngle [] [0,π/2]
MFColor [in,out] groundColor [] [0,1]
MFString [in,out] backUrl [] [urn]
MFString [in,out] bottomUrl [] [urn]
MFString [in,out] frontUrl [] [urn]
MFString [in,out] leftUrl [] [urn]
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFString [in,out] rightUrl [] [urn]
60
MFString [in,out] topUrl [] [urn]
MFFloat [in,out] skyAngle [] [0,π]
MFColor [in,out] skyColor 0 0 0 [0,1]
SFTime [out] bindTime
SFBool [out] isBound
}

DirectionalLight : X3DLightNode {
SFFloat [in,out] ambientIntensity 0 [0,1]
SFColor [in,out] color 1 1 1 [0,1]
SFVec3f [in,out] direction 0 0 -1 (-∞ ,∞ )
SFFloat [in,out] intensity 1 [0,1]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [in,out] on TRUE
}

PointLight : X3DLightNode {
SFFloat [in,out] ambientIntensity 0 [0,1]
SFVec3f [in,out] attenuation 1 0 0 [0,∞ )
SFColor [in,out] color 1 1 1 [0,1]
SFFloat [in,out] intensity 1 [0,1]
SFVec3f [in,out] location 0 0 0 (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [in,out] on TRUE
SFFloat [in,out] radius 100 [0,∞ )
}
SpotLight : X3DLightNode {
SFFloat [in,out] ambientIntensity 0 [0,1]
SFVec3f [in,out] attenuation 100 [0,∞ )
SFFloat [in,out] beamWidth π/2 (0,π/2]
SFColor [in,out] color 111 [0,1]
SFFloat [in,out] cutOffAngle π/4 (0,π/2]
SFVec3f [in,out] direction 0 0 -1 (-∞ ,∞ )
SFFloat [in,out] intensity 1 [0,1] Figura 2-14 - Elementos de SpotLight
SFVec3f [in,out] location 000 (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFBool [in,out] on TRUE
SFFloat [in,out] radius 100 [0,∞ )
}

LOD : X3DGroupingNode {
MFNode [in] addChildren [X3DChildNode]
MFNode [in] removeChildren [X3DChildNode]
MFNode [in,out] children [] [X3DChildNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [] bboxCenter 000 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
SFVec3f [] center 000 (-∞ ,∞ )
MFFloat [] range [] [0,∞ ) or -1
61
}

AudioClip : X3DSoundSourceNode, X3DUrlObject {


SFString [in,out] description ""
SFBool [in,out] loop FALSE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFTime [in,out] pauseTime 0 (-∞ ,∞ )
SFFloat [in,out] pitch 1.0 (0,∞ )
SFTime [in,out] resumeTime 0 (-∞ ,∞ )
SFTime [in,out] startTime 0 (-∞ ,∞ )
SFTime [in,out] stopTime 0 (-∞ ,∞ )
MFString [in,out] url [] [urn]
SFTime [out] duration_changed
SFTime [out] elapsedTime
SFBool [out] isActive
SFBool [out] isPaused
}
Sound : X3DSoundNode {
SFVec3f [in,out] direction 0 0 1 (-∞ ,∞ )
SFFloat [in,out] intensity 1 [0,1]
SFVec3f [in,out] location 0 0 0 (-∞ ,∞ )
SFFloat [in,out] maxBack 10 [0,∞ )
SFFloat [in,out] maxFront 10 [0,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFFloat [in,out] minBack 1 [0,∞ )
SFFloat [in,out] minFront 1 [0,∞ )
SFFloat [in,out] priority 0 [0,1]
SFNode [in,out] source NULL [X3DSoundSourceNode] Figura 2-15 - Elementos do nó Sound
SFBool [] spatialize TRUE
}

ImageTexture : X3DTexture2DNode {
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFString [in,out] url [] [urn]
SFBool [] repeatS TRUE
SFBool [] repeatT TRUE
}

MovieTexture : X3DTexture2DNode, X3DSoundSourceNode, X3DUrlObject {


SFBool [in,out] loop FALSE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFTime [in,out] resumeTime 0 (-∞ ,∞ )
SFTime [in,out] pauseTime 0 (-∞ ,∞ )
SFFloat [in,out] speed 1.0 (-∞ ,∞ )
SFTime [in,out] startTime 0 (-∞ ,∞ )
SFTime [in,out] stopTime 0 (-∞ ,∞ )
MFString [in,out] url [] [urn]
SFBool [] repeatS TRUE
SFBool [] repeatT TRUE
SFTime [out] duration_changed
62
SFTime [out] elapsedTime
SFBool [out] isActive
SFBool [out] isPaused
}

TimeSensor : X3DTimeDependentNode,X3DSensorNode{
SFTime [in,out] cycleInterval 1 (0,∞ )
SFBool [in,out] enabled TRUE
SFBool [in,out] loop FALSE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFTime [in,out] pauseTime 0 (-∞ ,∞ )
SFTime [in,out] resumeTime 0
SFTime [in,out] startTime 0 (-∞ ,∞ )
Figura 2-16 - Elementos do nó TimeSensor
SFTime [in,out] stopTime 0 (-∞ ,∞ )
SFTime [out] cycleTime
A figura apresenta os elementos do nó
SFTime [out] elapsedTime
SFFloat [out] fraction_changed TimeSensor. É importante destacar que o tempo é sempre
SFBool [out] isActive uma fração do valor máximo (que é sempre 1.0). Assim,
SFBool [out] isPaused quando define-se que o intervalo de tempo
SFTime [out] time (cycleInterval) será de 10.0 s, em 2 s teremos o tempo
} relativo à fração 0.2.

PositionInterpolator : X3DInterpolatorNode {
SFFloat [in] set_fraction (-∞ ,∞ )
MFFloat [in,out] key [] (-∞ ,∞ )
MFVec3f [in,out] keyValue [] (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [out] value_changed
}

OrientationInterpolator : X3DInterpolatorNode {
SFFloat [in] set_fraction (-∞ ,∞ )
MFFloat [in,out] key [] (-∞ ,∞ )
MFRotation [in,out] keyValue [] [-1,1] or (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFRotation [out] value_changed
}

ScalarInterpolator : X3DInterpolatorNode {
SFFloat [in] set_fraction (-∞ ,∞ )
MFFloat [in,out] key [] (-∞ ,∞ )
MFFloat [in,out] keyValue [] (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFFloat [out] value_changed
}

NavigationInfo : X3DBindableNode {
SFBool [in] set_bind
MFFloat [in,out] avatarSize [0.25 1.6 0.75] [0,∞ )
63
SFBool [in,out] headlight TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFFloat [in,out] speed 1.0 [0,∞ )
MFString [in,out] transitionType [LINEAR] ["TELEPORT" "LINEAR" "ANIMATE"]
MFString [in,out] type ["EXAMINE" "ANY"]
SFFloat [in,out] visibilityLimit 0.0 [0,∞ )
SFTime [out] bindTime
SFBool [out] isBound
}

Viewpoint : X3DBindableNode {
SFBool [in] set_bind
SFVec3f [in,out] centerOfRotation 0 0 0 (-∞ ,∞ )
SFString [in,out] description ""
SFFloat [in,out] fieldOfView π/4 (0,π)
SFBool [in,out] jump TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFRotation [in,out] orientation 0 0 1 0 [-1,1],(-∞ ,∞ )
SFVec3f [in,out] position 0 0 10 (-∞ ,∞ )
SFTime [out] bindTime
SFBool [out] isBound
}

PlaneSensor : X3DDragSensorNode {
SFBool [in,out] autoOffset TRUE
SFString [in,out] description ""
SFBool [in,out] enabled TRUE
SFVec2f [in,out] maxPosition -1 -1 (-∞ ,∞ )
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec2f [in,out] minPosition 0 0 (-∞ ,∞ )
SFVec3f [in,out] offset 0 0 0 (-∞ ,∞ )
SFBool [out] isActive
SFBool [out] isOver
SFVec3f [out] trackPoint_changed
SFVec3f [out] translation_changed
}

SphereSensor : X3DDragSensorNode {
SFBool [in,out] autoOffset TRUE
SFString [in,out] description ""
SFBool [in,out] enabled TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFRotation [in,out] offset 0 1 0 0 [-1,1],(-∞ ,∞ )
SFBool [out] isActive
SFBool [out] isOver
SFRotation [out] rotation_changed
SFVec3f [out] trackPoint_changed
}

TouchSensor : X3DTouchSensorNode {
64
SFString [in,out] description ""
SFBool [in,out] enabled TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [out] hitNormal_changed
SFVec3f [out] hitPoint_changed
SFVec2f [out] hitTexCoord_changed
SFBool [out] isActive
SFBool [out] isOver
SFTime [out] touchTime
}

VisibilitySensor : X3DEnvironmentalSensorNode {
SFVec3f [in,out] center 0 0 0 (-∞ ,∞ )
SFBool [in,out] enabled TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [in,out] size 0 0 0 [0,∞ )
SFTime [out] enterTime
SFTime [out] exitTime
SFBool [out] isActive
}

ProximitySensor : X3DEnvironmentalSensorNode {
SFVec3f [in,out] center 0 0 0 (-∞ ,∞ )
SFBool [in,out] enabled TRUE
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFVec3f [in,out] size 0 0 0 [0,∞ )
SFTime [out] enterTime
SFTime [out] exitTime
SFVec3f [out] centerOfRotation_changed
SFBool [out] isActive
SFRotation [out] orientation_changed
SFVec3f [out] position_changed
}

Collision : X3DGroupingNode, X3DSensorNode {


MFNode [in] addChildren [X3DChildNode]
MFNode [in] removeChildren [X3DChildNode]
SFBool [in,out] enabled
MFNode [in,out] children [] [X3DChildNode]
SFNode [in,out] metadata NULL [X3DMetadataObject]
SFTime [out] collideTime
SFBool [out] isActive
SFVec3f [] bboxCenter 000 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
SFNode [] proxy NULL [X3DChildNode]
}

Anchor : X3DGroupingNode {
MFNode [in] addChildren
MFNode [in] removeChildren
65
MFNode [in,out] children [] [X3DChildNode]
SFString [in,out] description ""
SFNode [in,out] metadata NULL [X3DMetadataObject]
MFString [in,out] parameter []
MFString [in,out] url [] [url or urn]
SFVec3f [] bboxCenter 000 (-∞ ,∞ )
SFVec3f [] bboxSize -1 -1 -1 [0,∞ ) or − 1 − 1 − 1
}

2.3 Codificação VRML97


Usando a idéia básica apresentada na seção anterior, serão detalhados, nesta
seção, o formato de codificação em VRML 97.

2.3.1 Formas Geométricas Básicas e primeiros exemplos


Para começar a discutir as formas geométricas, será iniciada a definição de um
cone. Tal definição teria a descrição textual abaixo como arquivo VRML:
Shape {
appearance Appearance {}
geometry Cone {
height 2.0
bottomRadius 1.0 }}
Observe que não foram feitas quaisquer definições de aparência, levando a
forma gerada, de acordo com o texto acima, a ter aparência branca.
Para gerar o Cilindro, os elementos de geometria seriam os apresentado na Figura
2-5.

Visando a construção da chaminé, temos de deslocar o cone, de forma que sua


base coincida com o topo do cilindro. Tal deslocamento refere-se a uma translação da
forma "Cone" no eixo Y, do valor da metade da altura do cilindro (height/2) mais a
metade da altura do Cone (height_cone/2), uma vez que, conforme ilustra a Figura 2-5,

teríamos metade do cilindro acima e metade do cilindro abaixo do eixo 'x' (o mesmo
vale para o Cone).

2.3.2 Textos
É possível inserir textos nos ambientes 3D concebidos através do nó Text, cuja
sintaxe foi apresentada no grafo de cena.
A apresentação do texto pode ser formatada com uso do nó FontStyle, que
permite definir a fonte que será utilizada, seu tamanho, espaçamento de caracteres,
como o texto será justificado etc.
66
O trecho de código abaixo, relativo à geometria, gera um texto simples como
Comentário: NÃO ACHEI ESTA
exemplo da Figura 2-17 - Exemplo de texto em VRML FIGURA, POR FAVOR REINSERIR
!!!!.
geometry Text {
string ["SVR 04 - Curso de VRML e X3D"]
fontStyle FontStyle {
size 0.9
justify "MIDDLE"
spacing 0.3
style "BOLD"
family "SERIF"
}
}

Figura 2-17 - Exemplo de texto em VRML

2.3.3 Transformações Geométricas


O nó VRML que permite que façamos transformações geométricas (translação,
rotação e escala) sobre as formas definidas é o nó 'Transform'. 'Transform' é, de fato,
um nó de agrupamento, que, para todas as formas de seus filhos ('children') aplica as
transformações definidas nos campos 'scale', 'translation' e 'rotation':
'Scale' escala em X,Y,Z, respectivamente;
'Translation': translação nos eixos X,Y,Z respectivamente;
'rotation': rotação em X, Y, Z pelo argumento (em rad) do quarto campo;
'children': lista dos elementos a qual devem ser aplicadas as transformações.
Assim, o arquivo final para geração da chaminé deveria ter um código
semelhante às linhas abaixo:
Group{
children [
Transform {
scale 1.0 1.0 1.0
translation 0.0 3 0.0
children [
Shape {
appearance Appearance {}
geometry Cone {
height 3.0
bottomRadius 2.5 }
67
}
]
}
Shape {
appearance Appearance {}
geometry Cylinder {
bottom TRUE
top TRUE
radius 1.0
height 3.0
}
}
]
}
As linhas de código equivalem à uma árvore como a apresentada na Figura 2-18.

Figura 2-18 - Estrutura de árvore da Chaminé Exemplo


Observa-se que um código simples, iniciado por um cabeçalho padrão (#VRML
V2.0 utf8) e seguido por uma árvore que contém a descrição de dois elementos
geométricos, um cilindro e um cone gera o efeito da construção de uma pequena
chaminé. O grafo que descreve a cena é dado por um nó principal Group que contém
dois nós como filhos - children:

 nó Transform, capaz de promover a translação de uma dada forma, no caso, de um


dado cone;

 nó Shape que é usado para definir uma outra forma, no caso, um cilindro.
68
A facilidade de implementar formas geométricas é facilmente observada através
deste exemplo, que permite verificar que um arquivo que tem menos de 1kb é capaz de
produzir uma forma geométrica 3D,que a partir dos recursos do navegador VRML pode
ser vista de diferentes ângulos, rotacionada para verificação, aproximada ou afastada,
girada, apontada etc, tornando a navegação uma agradável experiência interativa com a
forma.
Até meados do ano de 2000, a edição de textos que descreviam formas em
VRML não dispunha de um editor de textos exclusivo para este fim. De olho neste
nicho de mercado, a empresa Parallel Graphics lançou o VrmlPad® [VRMLPAD
2000], que se encontra na versão 2.0 e que facilita sobremaneira a edição de tais textos.

2.3.4 Alterando Aparência - nó appearance


De maneira a acomodar a definição adequada da aparência de uma forma, o nó
appearance tem a seguinte sintaxe no VRML:
appearance Appearance {
material Material {
ambientIntensity 1.0
diffuseColor 1.0 0.0 0.0
emissiveColor 1.0 0.0 0.0
specularColor 1.0 0.0 0.0
transparency 0.3
shininess 0.4
}
texture ImageTexture {url ""}
}}
As variáveis diffuseColor, emissiveColor e specularColor referem-se à definição
das cores do objeto relativas à iluminação difusa, especular e a cor que o mesmo emite.
A transparência do mesmo é dada pelo campo 'transparency' e caso seja necessário,
podemos aplicar a textura relativa à uma imagem (JPEG, GIF etc) ao objeto dando o
endereço da mesma no campo ImageTexture. Neste caso, as definições de cores feitas
em 'Material' são perdidas.
Como exemplo, para alterar o cone já definido anteriormente, dando-lhe uma
aparência acinzentada, poderíamos definir o nó appearance como:
appearance Appearance {
material Material {
diffuseColor .8 0 .13
specularColor .77 .77 .77
emissiveColor .1 0 .02
ambientIntensity .0767
}
69
}
O resultado da alteração da forma do cone pode ser visto na Figura 2-19.

Figura 2-19 - Cone colorido - uso de 'appearance'


Algumas vezes, no entanto, deseja-se aplicar uma textura a uma dada forma, ao
invés de definir propriedades de cor para a mesma. Neste caso, imagens do tipo JPEG,
GIF e PNG podem ser aplicadas à forma desejada com uso do nó 'Material'. São
campos possíveis de serem utilizados: ImageTexture, PixelTexture e MovieTexture.
Como exemplo, a aplicação de uma textura feita ao cone, similar ao definido
anteriormente, conforme o código abaixo pode ser visto na Figura 2-20.
Transform {
scale 1.0 1.0 1.0
translation 0.0 3 0.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor .8 0 .13
specularColor .77 .77 .77
emissiveColor .1 0 .02
ambientIntensity .0767
}
texture ImageTexture {
url "brick.jpg"}
}
geometry Cone {
height 3.0
bottomRadius 1.5 }
}
]
}
70

Figura 2-20 - Cone com aplicação de Textura


Há possibilidade de controlar o mapeamento de texturas com utilização dos nós
TextureCoordinate e TextureTransform. O nó TextureTransform pode ser usado como
um valor do campo de valor no nó Appearance.
O trecho de código abaixo altera a aplicação de textura no cone, por uma escala
de 2.0 para as direções S e T, respectivamente. A Figura 2-21 apresenta o plano de
aplicação de texturas S x T.

Figura 2-21 - Plano de aplicação de textura S x T


O resultado pode ser visto na Figura 2-22.
textureTransform TextureTransform {
scale 2.0 2.0
}
texture ImageTexture {
url "brick.jpg"
}
71

Figura 2-22 - Alterando Aplicação de Textura - textureTransform

2.3.5 Reutilizando Formas, Elementos e Definições


Quando se faz necessário reutilizar uma dada forma, são usados os termos DEF
e USE. DEF define o nome de um dado elemento, forma ou definição. A reutilização
deste nome a partir de sua chamada por USE dispensa a redefinição.
Como exemplo, será definido um conjunto de colunas, a partir da definição de
uma única coluna. A coluna básica será definida por "Coluna" e terá aparência definida
por "White". Ao longo da descrição do conjunto a reutilização se dará pela chamada
destes termos com USE, como pode ser visto no código abaixo:
Group {
children [
# Coluna da Esquerda
DEF ColEsquerda Transform {
translation -2.0 3.0 0.0
children DEF Coluna Shape {
appearance DEF White Appearance {
material Material { }
}
geometry Cylinder {
radius 0.3
height 6.0
}
}
},
# Coluna da Direita:
DEF ColDireita Transform {
translation 2.0 3.0 0.0
children USE Coluna
},
# Coluna Superior
DEF Superior Transform {
72
translation 0.0 6.0 0.0
rotation 0.0 0.0 1.0 1.57
children Shape{
appearance USE White
geometry Cylinder {
radius 0.3
height 4.6
} }
}
]}
O resultado é mostrado na Figura 2-23, onde um elemento foi reutilizado com
uso de DEF e USE.

Figura 2-23 - Coluna com uso de DEF e USE


Podem ser inseridos elementos definidos em um dado arquivo dentro de um
cenário 3D, com uso do nó Inline.
No exemplo abaixo, o grupo de colunas é combinado, formando um conjunto de
grupos de colunas, através da chamada feita pelo Inline combinada com uso de "DEF" e
"USE". O resultado pode ser visto na Figura 2-24.
Group {
children [
Transform {
translation 0.0 -2.0 0.0
children DEF coluna Inline {url "colunas.wrl"} }
Transform {
translation 0.0 -2.0 -2.0
children USE coluna
}
Transform {
translation 0.0 -2.0 -4.0
children USE coluna
}
Transform {
translation 0.0 -2.0 -6.0
73
children USE coluna
}
]}

Figura 2-24 - Grupo de Colunas - uso de Inline

2.3.6 Compondo formas como conjunto de Faces


A utilização do nó IndexedFaceSet permite construir conjuntos de faces
interligadas, de forma que tal combinação gere efeitos de formas complexas. Na
descrição de um conjunto de faces, uma lista de pontos coordenados deve ser
explicitada, além das conexões entre estes pontos. Supondo que se deseje a construção
de um cubo seriam necessárias as coordenadas da parte superior do cubo e da parte
inferior, além das descrições de ligações entre estes pontos.
geometry IndexedFaceSet {
coord Coordinate {
point [
# Coordenadas da parte superior do cubo
-1.0 1.0 1.0,
1.0 1.0 1.0,
1.0 1.0 -1.0,
-1.0 1.0 -1.0,
# Coordenadas da parte inferior do cubo
-1.0 -1.0 1.0,
1.0 -1.0 1.0,
1.0 -1.0 -1.0,
-1.0 -1.0 -1.0
]
}
coordIndex [
# face superior
0, 1, 2, 3, -1,
# face de fundo
7, 6, 5, 4, -1,
# face de frente
74
0, 4, 5, 1, -1,
# face da direita
1, 5, 6, 2, -1,
# face de costas
2, 6, 7, 3, -1,
# face da esquerda
3, 7, 4, 0
]
}
}
E o resultado pode ser visto na Figura 2-25, onde um Cubo foi construído a
partir de suas faces.

Figura 2-25 - Cubo - uso de IndexedFaceSet

2.3.7 Fundos e Cenários


O nó Background permite criar fundos para os mundos virtuais usando uma
caixa de textura, elementos de piso e elementos do céu. A sintaxe do nó Background foi
mostrada no grafo de cena:
O trecho de código a seguir, relativo à Figura 2-26, apresenta um cenário com
um céu azulado e o chão em tom marrom:
Background {
skyColor [
0.0 0.2 0.7
0.0 0.5 1.0
1.0 1.0 1.0
]
skyAngle [1.309 1.571]
groundColor[
0.1 0.1 0.1
0.4 0.25 0.2
0.6 0.6 0.6
75
]
groundAngle [1.309 1.571]
}

Figura 2-26 - Background aplicado


A definição de uma textura que é aplicada ao fundo pode ser feita como
apresentado no trecho de código abaixo:
Background {
skyColor [
0.0 0.2 0.7,
0.0 0.5 1.0,
1.0 1.0 1.0
]
skyAngle [ 1.309, 1.571 ]
groundColor [
0.1 0.10 0.0,
0.4 0.25 0.2,
0.6 0.60 0.6,
]
groundAngle [ 1.309, 1.571 ]
frontUrl "montanha.gif"
backUrl "montanha.gif"
leftUrl "montanha.gif"
rightUrl "montanha.gif"
}
E o resultado pode ser visto na Figura 2-27, onde um elemento de imagem
auxilia na definição mais realística de um fundo.
76

Figura 2-27 - Background com elementos de imagem ".gif"

2.3.8 Iluminação
VRML provê diversos nós para uma iluminação adequada de cenário. Todos
estes nós apresentam os seguintes campos: color, ambientIntensity e intensity. As
funções dos nós podem ser:
- iluminação do tipo direcional, com os raios emanando de forma radial em
todas as direções: PointLight;
- iluminação do tipo direcional, com os raios pertencem a um pincel de luz
paralela: DirectionalLight;
- iluminação do tipo 'spot', com os raios em um pincel na forma de cone, com
a fonte de luz no ápice do cone: SpotLight;
Em todos os casos, a contribuição de uma fonte de luz é definida pelo campo
intensityColor, enquanto que a contribuição da luz ambiente é dade em função do valor
do campo ambientIntensity. Objetos com textura não são afetados pela fontes de luz.
Pode-se desligar a luz na cabeça do usuário (navegador) através da definição a headlight
FALSE no nó NavigationInfo.

2.3.8.1 DirectionalLight
O pincel de luz paralelo tem a orientação dada pelo campo direction, a cor
definida no campo color e a intensidade definida em intensity. A Figura 2-28 apresenta
um conjunto de esferas que foi iluminado com uma luz direcional, no sentido do eixo x.
77

Figura 2-28 -uso de DirectionalLight

2.3.8.2 PointLight
A sintaxe do nó PointLight foi apresentada no grafo de cena.
O pincel de luz puntiforme tem a localização no ambiente 3D dada pelo campo
locaion, o raio da esfera de iluminação dado pelo campos radius, a intensidade definida
em intensity. Os campos intensity e color combinam-se para definir o nível de cor
provida pela fonte de luz em definição. Assim, a equação que define a cor da luz é:
lightColor = color X intensity.
A intensidade da luz ambiente é dada por:
lightAmbientColor = color X intensity X ambientIntensity.
As Figura 2-29 e Figura 2-30 apresentam um conjunto de esferas que foi
iluminado com uma luz puntiforme, que está definida no centro do eixo de coordenadas
do sistema. Na figura temos uma fonte de luz com grande intensidade e baixa atenuação
(caso 1) e na figura temos o mesmo conjunto de esferas associado a uma fonte de luz
com baixa intensidade e grande atenuação (caso 2).

Figura 2-29 - uso de PointLight - caso 1


78
2.3.8.3 SpotLight
A sintaxe do nó SpotLight é dada por:
A Figura 2-30 apresenta o mesmo conjunto de esferas iluminado por uma
SpotLight

Figura 2-30 - uso de SpotLight

2.3.9 Controlando Detalhamento de Elementos - nó LOD


A técnica de controlar o detalhamento de elementos aparece na Computação
Gráfica quando simuladores de vôo foram usados para treinamento de pilotos. Em tais
simuladores, ao apresentar o cenário de um terreno, onde uma dada aeronave deveria
pousar, o realismo é muito importante.
Para dar mais realismo à tais cenas, os terrenos necessitavam de grande
detalhamento, associados à presença de edificações, árvores, carros etc. Para melhorar o
desempenho de tais simuladores, observa-se que não é necessária a definição de muitos
detalhes quando o elemento está situado a grande distância do observador e o inverso é
válido para elementos muito próximos.
A técnica de controlar o detalhamento dos elementos está associada à criação de
diferentes versões do mesmo que serão apresentadas ao navegante à partir de sua
distância à forma em questão. O nó LOD ativa a chamada de cada forma em função de
tais distâncias
O valor de center especifica uma posição no espaço 3D para o centro da forma
construída com uso de LOD.
O campo level apresenta as diferentes ativações de formas que serão efetuadas
para diferentes distâncias do usuário à forma, enquanto o campo range especifica as
distâncias que definirão as ativações dos elementos de range. O código abaixo apresenta
79
uma forma de controlar a apresentação de três formas - box, sphere e cone à medida que
o observador aproxima-se ou afasta-se do conjunto.
LOD {
range [15,25]
level [
#primeiro nivel
Group{
children[
Shape { geometry Box{}}
Transform {
translation 3 0 0
children[
Shape { geometry Sphere { }}
Transform{
translation 3 0 0
children Shape {
geometry Cone {}
}}]}]}
# Segundo Nivel
Group {
children[
Shape { geometry Box {}}
Transform{
translation 3 0 0
children Shape { geometry Sphere{}}
}]}
#Terceiro nível
Shape { geometry Box{}}
]
}

2.3.10 Animando as formas

2.3.10.1 Animações básicas


Para tornar o mundo mais dinâmico, podem ser animadas as posições,
orientações e escalas das formas que estão definidas. Uma animação é uma mudança de
algo em função de um intervalo de tempo. Uma animação requer dois elementos:
- Um elemento de tempo (relógio) que controla a animação;
- A descrição de como alguma coisa altera-se ao longo do tempo da animação.
A animação de algum elemento deve ser feita imaginando que o mesmo pode
sofrer alterações de posição, orientação e escala em função de um dado tempo (fração
do tempo em questão). O nó responsável pelo controle de tempos (e frações) é o nó
TimeSensor.
80
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. O nó que
controla a posição de uma forma em função de uma fração de tempo é o nó
O nó PositionInterpolator necessita de receber uma informação de tempo,
enviada por um elemento de tempo (geralmente um TimeSensor). Com tal informação,
compatibiliza a posição da forma (keyValue) com a fração de tempo (key). A associação
é sempre feita por uma rota que combina a saída de tempo do TimeSensor com a entrada
do nó PositionInterpolator.
Como exemplo, uma animação será aplicada à uma esfera que deve mudar de
posição o tempo todo (descrevendo um S), em um loop, de forma que será desnecessária
a intervenção do usuário para disparar a animação. Devem ser definidas as posições
inicial e final do elemento, além das posições intermediárias (uma interpolação define o
percurso do mesmo no cenário 3D). O trecho de código abaixo descreve esta animação:
DEF elemento Transform {
children[
DEF cont_tempo TimeSensor {
startTime 0.0
loop TRUE
cycleInterval 5.0
},
DEF cont_pos PositionInterpolator {
key [ 0.0 0.2 0.4 0.6 0.8 1.0]
keyValue [
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 2.0 0.0
1.0 2.0 0.0
]
}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .46 .37 .14
specularColor .38 .31 .12
emissiveColor .14 .11 .04
ambientIntensity 0
shininess .04
}
}
geometry Sphere {
radius 0.3}
}
81

]
}
ROUTE cont_tempo.fraction_changed TO cont_pos.set_fraction
ROUTE cont_pos.value_changed TO elemento.set_translation

Há necessidade de inserir rotas, de forma que valores obtidos em um nó sejam


mapeados para outro nó, possibilitando a animação. Neste caso, os valores de frações de
tempo produzidos pelo nó cont_tempo são enviados como entrada para o nó cont_pos.
Com a combinação de tais frações com os valores chave de tempo descritos no campo
key do nó cont_pos são associados com posições chave (keyValue), que devem ser
enviadas par o nó de controle das tranformações geométricas (elemento), de forma que a
esfera seja animada.
Se, ao invés de controlar posições, fosse necessário controlar a orientação, o nó
adequado seria o nó OrientationInterpolator, que permite que sejam aplicadas rotações
às formas desejadas.
Onde o campo key define as frações de intervalos de tempo e o campo keyValue
define as frações da animação (na forma de rotação). O trecho de código abaixo
promove a rotação de uma caixa em torno do eixo 'x':
DEF elemento Transform {
children[
DEF cont_tempo TimeSensor {
startTime 0.0
loop TRUE
cycleInterval 5.0
},
DEF cont_or OrientationInterpolator {
key [ 0.0 0.25 0.5 0.75 1.0]
keyValue [
1.0 0.0 0.0 0.0
1.0 0.0 0.0 1.57
1.0 0.0 0.0 3.14159
1.0 0.0 0.0 4.7123
1.0 0.0 0.0 6.28
]
}
DEF forma Shape{
appearance Appearance {
material Material {
diffuseColor .55 .09 .2
specularColor .29 .31 .05
emissiveColor .21 .03 .08
ambientIntensity .03
82
shininess .19
}
}
geometry Box{
size 0.3 0.5 0.8}
}

]
}
ROUTE cont_tempo.fraction_changed TO cont_or.set_fraction
ROUTE cont_or.value_changed TO elemento.set_rotation

A definição da rotação está nos valores de keyValue, onde define-se que será
feita sobre o eixo 'x', que é o único dos três eixos que está com valor diferente de '0.0'
(como pode ser visto na linha 1 do campo keyValue. A rotação será de 0 a 2π e deve ser
definida com ângulos em radianos.
A última forma de animação relativa às transformações geométricas é a mudança
de escala. O nó que permite mudança de escala é o nó PositionInterpolator (o mesmo
que permite a animação de posição). Neste caso, no entanto, devem ser colocados
valores de escala no campo keyValue e a rota de saída de valores deve ser entrada para
valores de escala ao invés de valores de posição. Supondo a esfera apresentada
anteriormente, a modificação do nó de controle e das rotas seria dada por:
DEF cont_esc PositionInterpolator {
key [ 0.0 0.2 0.4 0.6 0.8 1.0]
keyValue [
1.0 1.0 1.0
1.5 1.5 1.5
2.0 2.0 2.0
2.5 2.5 2.5
1.5 1.5 1.5
1.0 1.0 1.0
]
}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .46 .37 .14
specularColor .38 .31 .12
emissiveColor .14 .11 .04
ambientIntensity 0
shininess .04
}
}
geometry Sphere {
radius 0.5}
83
}
]
}
ROUTE cont_tempo.fraction_changed TO cont_esc.set_fraction
ROUTE cont_esc.value_changed TO elemento.set_scale

2.3.10.2 Controlando as animações


De maneira a controlar as animações, podem ser inseridos nós sensores de ações
dos usuários. Há três formas de ações que podem ser percebidas:
 Movimento (Move): sem pressionar o mouse, o usuário move o cursor sobre
um item qualquer;
 Clique: quando o cursor está sobre um elemento, o botão do mouse é
pressionado e liberado, sem movimento do mesmo;
 Arraste (Drag): com o cursor sobre um item, o botão do mouse é
pressionado e, mantido pressionado, o mouse é arrastado.
O nó capaz relativo à captura de toque é o nó TouchSensor.O nó TouchSensor
tem sensibilidade ao toque (campo touchTime), ao cursor estar sobre uma forma
(isOver) e pressionado (isActive). Supondo que se desejasse disparar a animação de uma
esfera como mostrado anteriormente, ao toque na esfera, a sintaxe poderia ser:
DEF elemento Transform {
children[
DEF cont_tempo TimeSensor {
cycleInterval 5.0
},
DEF cont_pos PositionInterpolator {
key [ 0.0 0.2 0.4 0.6 0.8 1.0]
keyValue [
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 2.0 0.0
1.0 2.0 0.0
]
}
DEF toque TouchSensor {}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .46 .37 .14
specularColor .38 .31 .12
emissiveColor .14 .11 .04
ambientIntensity 0
84
shininess .04
}
}
geometry Sphere {
radius 0.3}
}
]
}
ROUTE toque.touchTime TO cont_tempo.startTime
ROUTE cont_tempo.fraction_changed TO cont_pos.set_fraction
ROUTE cont_pos.value_changed TO elemento.set_translation

Neste exemplo, quando o usuário toca na esfera, que está definida no mesmo
grupo do nó 'toque', um evento de disparo de tempo é enviado para o nó de controle de
tempo - 'cont_tempo'. Só então, frações de tempo são recebidas pelo nó 'cont_pos',
disparando a animação (que acontece uma única vez).
De maneira a permitir que um dado elemento gráfico seja manipulado pelos
movimentos do usuário, existem três nós distintos;
 PlaneSensor: converte as ações do usuário em movimentos em um plano 2D;
 SphereSensor: converte as ações do usuário em movimentos ao longo de
uma esfera que envolve a forma;
 CylinderSensor: converte as ações do usuário em movimentos ao longo de
um cilindro definido sobre um dos eixos.
Os campos maxPosition e minPosition definem os limites da translação que será
aplicada à forma. O trecho de código abaixo permite que, com a movimentação do
mouse, uma dada esfera sofra mudança de posição ao longo do plano 'XY':
DEF elemento Transform {
children[
DEF sensor_pos PlaneSensor{
enabled TRUE
autoOffset TRUE
offset 0.0 0.0 0.0
maxPosition -1.0 -1.0
minPosition 0.0 0.0
}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .62 0 .62
specularColor .5 0 .5
emissiveColor .15 0 .15
ambientIntensity 0
shininess .15
85
}
}
geometry Sphere {
radius 0.8}
}
]
}
ROUTE sensor_pos.translation_changed TO elemento.translation

O nó SphereSensor tem sintaxe dada por:


SphereSensor {
autoOffset TRUE
enabled TRUE
offset 0.0 1.0 0.0 0.0
}
O campo offset permite definir o eixo de rotação que será usado. O trecho de
código abaixo apresenta a utilização de SphereSensor para rotacionar uma dada caixa
(box):
DEF elemento Transform {
children[
DEF sensor_esf SphereSensor {
autoOffset TRUE
enabled TRUE
offset 0.0 1.0 0.0 0.0
}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .6 .23 0
specularColor .5 .2 0
emissiveColor .3 .12 0
ambientIntensity 0
shininess .15
}
}
geometry Box {
size 2.0 3.0 5.0}
}

]
}
ROUTE sensor_esf.rotation_changed TO elemento.rotation
86
O trecho de código abaixo apresenta a utilização de CylinderSensor para
movimentar uma dada caixa (box):
DEF elemento Transform {
children[
DEF sensor_esf CylinderSensor {
autoOffset TRUE
enabled TRUE
diskAngle 0.262
offset 0.0
maxAngle -1.0
minAngle 0.0
}
DEF esfera Shape{
appearance Appearance {
material Material {
diffuseColor .6 .23 0
specularColor .5 .2 0
emissiveColor .3 .12 0
ambientIntensity 0
shininess .15
}
}
geometry Box {
size 2.0 3.0 5.0}
}

]
}
ROUTE sensor_esf.rotation_changed TO elemento.rotation

2.3.11 Controlando o Ponto de Vista e a Navegação


A navegação pode ser controlada pelo nó NavigatonInfo.
A velocidade de movimentação do avatar é dada pelo campo speed. Os tipos de
navegação, relativos ao campo type são:
• "WALK": quando o usuário caminha no mundo e é afetado pela gravidade;
• "FLY": quando o usuário pode se mover sem ser afetado pela gravidade;
• "EXAMINE": quando o usuário fica estático, mas pode se mover ao redor do
mundo em diversos ângulos;
• "NONE", quando o usuário não pode controlar os movimentos.
O campo headlight define se o avatar terá ou não uma fonte de luz na sua
cabeça. Se TRUE, uma fonte de luz estará ligada na cabeça do avatar.
87
Um ponto de vista (Viewpoint) é uma posição pré-definida com uma dada
orientação no cenário. Podem ser alteradas as formas de navegação do usuário e suas
posições de visualização.
O campo orientation define um eixo de rotação e um ângulo de rotação. O
campo position define a posição de visualização do avatar em relação ao cenário
apresentado. O trecho de código abaixo mostra como pode ser mudada a forma de
navegação a partir do toque em uma dada forma:
Group {
children [
DEF nav NavigationInfo {
type "NONE"
speed 2.0
headlight FALSE
avatarSize [0.5 1.6 0.5]}
DEF nav2 NavigationInfo {
type "WALK"}
DEF toque TouchSensor {},
Shape{
geometry Cone {}
}
]
}
ROUTE toque.isOver TO nav2.set_bind

2.3.12 Adicionando Sons e Filmes ao Cenário


De maneira a permitir que o cenário seja mais realístico, podem ser adicionados
sons, na forma de sons ambientes ou de sons controlados por animações. Os nós
relativos a adição de sons são:
 AudioClip: nó que suporta alguns tipos de sons digitais (não é permitido o
mp3): MIDI e WAV;
 Sound: nó que cria um emissor de som que pode ser ouvido dentro de uma
região elipsoidal;
 MovieTexture: permite a inserção de filmes (movie).

2.3.13 Sentindo a proximidade do usuário


Como visto, pode se usar o nó TouchSensor para detectar quando o usuário toca
uma forma do cenário. Há, no entanto, três outros nós capazes de identificar ações do
usuário, que podem ser utilizados para controlar animações, da mesma forma que o nó
TouchSensor:
88
 VisibilitySensor: usado para identificar a visibilidade de um observador,
através de uma região que tem o formato de uma caixa (região de
visibilidade);
 ProximitySensor: nó que permite detectar quando o observador entra e/ou se
move em uma região fechada (em formato de uma caixa);
 Collision: permite detectar quando o usuário colide com alguma forma,
sendo também um nó de agrupamento (como Group ou Transform). Este nó
gera o tempo absoluto em que o choque ocorreu ou alerta o navegador o fato;
O trecho de código abaixo apresenta uma animação controlada pelo nó
ProximitySensor. Neste exemplo, quando o usuário se aproxima de uma caixa de texto,
um som intermitente é emitido, como um som de alerta:
DEF SENSOR ProximitySensor {
size 8 8 8
}

Sound {
minFront 10
minBack 10
maxFront 50
maxBack 50
source DEF SOUND AudioClip {
loop TRUE
url "pop.wav"
startTime -1
}
}

Group {
children [
Shape {
appearance Appearance {
material Material {
emissiveColor .1 .1 0
diffuseColor .75 .75 0
specularColor .86 .86 .86
ambientIntensity .127
shininess .38
}
}
geometry Box { size 0.8 0.5 0.1}
}
Transform {
translation 0.0 0.0 0.12
children
Shape {
89
appearance Appearance {
material Material {
diffuseColor .9 .05 .5
specularColor .1 .1 .1
emissiveColor .1 0 .05
ambientIntensity .12
shininess .08
}
}
geometry Text {
string "Alerta"
fontStyle FontStyle{
size 0.27
justify "MIDDLE"
}
}
}
}
]}

ROUTE SENSOR.enterTime TO SOUND.startTime


ROUTE SENSOR.exitTime TO SOUND.stopTime

No exemplo anterior, se ao invés de utilizar o nó ProximitySensor, fosse


utilizado o nó Collision, o som só seria emitido no caso de colisão com a forma.

2.3.14 Unindo Cenários Virtuais - Links


Usando VRML é possível simular que, ao toque em uma porta, um novo cenário
será carregado. Tal ativação pode carregar um novo cenário 3D, uma página Web ou
uma animação. O nó adequado à tais simulações é o nó Anchor.
É importante destacar o campo url que conterá a informação da página com a
qual se deseja ativar ao tocar os elementos descritos em children. O trecho de código
abaixo apresenta um exemplo de utilização de Anchor:
Anchor {
# inserção do link para onde se deseja ir:
url [ "http://www.sbc.org.br/svr"]
description "Página do SVR´04"
# nós que ativarão o link:
children [
Transform {
translation 0.0 0.0 0.0
children [ Shape {
appearance Appearance {
material Material {
diffuseColor .62 .31 .62
90
specularColor .5 .25 .5
emissiveColor .15 .07 .15
ambientIntensity 0
shininess .15
}
}
geometry DEF Door Box {size 2.0 1.0 0.1}
}
Transform {
translation 0.0 0.0 0.2
children Shape {
appearance Appearance {
material Material {
diffuseColor .68 .68 .43
specularColor .5 .5 .31
emissiveColor .3 .3 .19
ambientIntensity 0
shininess .14
}
}
# inserção de um texto para identificar o link:
geometry Text {
string "SVR 03"
fontStyle FontStyle {
size 0.4
justify "MIDDLE"}
}
}
}
]
}, ]}

Anchor {
# inserção do link para onde se deseja ir:
url [ "http://www.compgraf.ufu.br/alexandre"]
description "Homepage do Autor"
# nós que ativarão o link:
children [
Transform {
translation 2.0 0.0 0.0
children [ Shape {
appearance Appearance {
material Material {
diffuseColor .03 .03 .18
specularColor .18 .27 .69
emissiveColor .03 .03 .17
ambientIntensity .0367
shininess .03
}
}
91
geometry USE Door

}
Transform {
translation 0.0 0.0 0.2
children Shape {
appearance Appearance {
material Material {
diffuseColor .6 .55 .24
specularColor .5 .46 .2
emissiveColor .3 .27 .12
ambientIntensity 0
shininess .14
}
}
# inserção de um texto para identificar o link:
geometry Text {
string "Autor"
fontStyle FontStyle {
size 0.4
justify "MIDDLE"}
}
}
}
]
}
]
}

2.3.15 Combinando VRML e JavaScript

2.3.15.1 Introdução
Os nós já apresentados para animação, tais como TouchSensor, TimeSensor,
PlaneSensor etc são muito limitados quando se desejam animações mais complexas ou
controle de elementos de cena a partir de equações (matemáticas, físicas, químicas etc).
Em tais situações é imperativa a necessidade de uso dos nós Script, que associam
VRML com JavaScript ou Java.
Um nó Script pode ser entendido como uma forma particular de controle ou de
sensor. Como qualquer nó de controle ou de sensor, este nó requer uma lista de campos
(field) , eventos de entrada (eventIns) e eventos de saída (eventOuts). A descrição do nó
deve complementar a definição destes campos, dando a eles uma dada finalidade . Um
nó Script deve ser entendido como um nó que recebe informações de outros nós através
dos eventos de entrada, processa-as e envia informações na forma de eventos de saída.
92
Logicamente, não serão encontrados nós Script independentes da descrição de
rotas, que mapeiam a troca de informações entre nós externos e o nó Script. Uma
exigência importante é a necessidade de equivalência de tipos de elementos entre os nós
que trocam informações.
Característica básica de um Script:
Script {
# definição de campos, suas naturezas e valores iniciais:
field SFBool booleano1 TRUE
# definição de eventos de entrada e sua natureza:
eventIn SFBool entrada
# definição de eventos de saída e sua natureza:
eventOut SFBool saida
url "javascript:
function entrada(param){
// processamento e determinação da saída
saida = param;
"
}

2.3.15.2 Exemplos
Como exemplo, a função abaixo representa um Script capaz de inserir um novo
elemento, no caso, uma esfera em uma área de um mundo virtual:

DEF Criador Script {


eventIn SFTime sphere_touchTime
field SFNode nopai USE TOP
field SFFloat x 0.0
eventOut MFNode new_child
url "javascript:

function sphere_touchTime(value,time) {
newVRML = 'Group {';
newVRML += ' children [';
newVRML += ' DEF SENSOR PlaneSensor {';
newVRML += ' maxPosition 0.45 0.45';
newVRML += ' minPosition -0.45 -0.45'
newVRML += ' }';
newVRML += ' DEF OBJECT Transform {';
newVRML += 'translation '
93
newVRML += x;
newVRML += ' 0.0 ';
newVRML += ' 0.0';
newVRML += ' children [';
newVRML += ' Shape {';
newVRML += ' appearance Appearance {';
newVRML += ' material Material {';
newVRML += ' diffuseColor 0 1 1';
newVRML += ' }';
newVRML += ' }';
newVRML += ' geometry Sphere {';
newVRML += ' radius 0.05';
newVRML += ' }';
newVRML += ' }';
newVRML += ' ]';
newVRML += ' }';
newVRML += ' ]';
newVRML += '}';
newVRML+=' ROUTE SENSOR.translation_changed TO
OBJECT.set_translation';
node = Browser.createVrmlFromString(newVRML);
new_child = node;
nopai.addChildren = new_child;
}
"
}
ROUTE SPHERESENSOR.touchTime TO Criador.sphere_touchTime

É possível alterar dinamicamente um texto, que funcione como um contador de


esferas adicionadas (continuação do exemplo anterior), se um dado nó de texto for
atualizado, a partir de um campo que conte quantas esferas foram adicionadas. O trecho
de código abaixo refere-se à função sphere_touchTime atualizada, de tal forma que a
mesma é capaz de modificar o texto, enviando, através de uma rota, o valor atual de
esferas inseridas:
field SFFloat x2 0.0
field MFString str_sphere "0"
eventOut MFString str_sphere_out
function sphere_touchTime(value,time) {
x2 = x2 + 1.0;
str_sphere[0] = String(x2);
str_sphere_out[0] = str_sphere[0];
A rota combinada seria do tipo:
ROUTE Criador.str_sphere_out TO textoS.string
94
Onde textoS é um campo de texto pertencente a um nó Shape.

2.4 Codificação X3D


Os dois padrões VRML97 e X3D são muito semelhantes o X3D aproveita o
trabalho desenvolvido pelo VRML97 solucionando diversos problemas e pontos em
aberto. Dentre as modificações temos a maior precisão com a iluminação e modelo de
eventos e a troca de certos nomes de campos para uma maior consistência.
As maiores mudanças podem ser sumarizadas da seguinte forma:

• Capacidades do grafo de cena expandidas

• Modelo de programação de aplicações revisado e unificado

• Multiplos formatos de codificação, descrevendo o mesmo modelo abstrato,


incluindo XML

• Arquitetura modular permitindo uma faixa de níveis para serem adotados e


suportados por diversos tipos de mercados

• Estrutura da especificação expandida

O grafo de cena X3D - o coração de uma aplicação X3D - é quase idêntico a do


grafo de cena VRML97. O projeto original da estrutura e tipos de nós do grafo de cena
VRML97 foi baseado no OpenInventor. Modificações foram feitas no grafo de cena
X3D, primariamente em função de incorporar os avanços nos dispositivos gráficos
comerciais, via a introdução de novos nós e campos dos dados. Adicionalmente
mudanças menores foram feitas de forma a esclarecer, como as de ser mais preciso no
sistema de iluminação e modelo de eventos, e prover acesso aos valores de
transparência nos campos de cores.
O X3D tem uma única interface de programação de aplicações (API). Esta difere
do VRML97 na qual tem uma API de script interna mais uma API externa. A API
unificada do X3D esclarece e resolve diversos problemas que existiram no VRML97
resultando em uma implementação mais robusta e confiável. Conexões por
ECMAScript e Java são definidas e ECMAScript é um requisito para a conformidade de
uma aplicação. O ECMAScript na verdade é um sistema Java interpretado porém
devido a restrições da Sun o nome Java não pode ser usado livremente.
95
O X3D suporta múltiplas codificações de arquivos, a própria VRML97 e
adicionalmente Extensible Markup Language (XML), além disso esta sendo estudada
uma codificação binária, que seria muito mais comprimida e eficiente para a leitura e
transferência de arquivos, contudo esta ainda não esta consolidada. A codificação XML
possui uma vantagem pois permite uma suave integração com serviços de web (web
services) e arquivos e transferência de dados entre plataformas inter-aplicações ( cross-
platform inter-application). Cada codificação tem suas vantagens para diferentes usos.
Todas as codificações suportam todo o conjunto de características do X3D.
O XML é um padrão definido para a troca de dados em multiplataformas. Existe
uma série de bibliografias que podem ser estudadas [XML][Harold e Means 2002].
Basicamente o XML consistem em uma série de nós que são organizados pelos sinais de
menor e maior ( “<” e “>” ) e também um sinal de barra ( “/” ) para informar o final de
um nós
Vamos apresentar aqui dois exemplos de arquivos, um no formato clássico, que
pode ser facilmente reconhecido pelos sinais de chaves e colchetes. Percebam que ele
tem a mesma estrutura do VRML97, porém com diferenças no cabeçalho. Logo a seguir
é apresentado um na codificação XML, nele é possível verificar a codificação XML,
que é mais comum para usuários em geral, que lidam com formatos de codificação.

• Exemplo de um arquivo em X3D Classico


#X3D V3.0 utf8
Profile Immersive [[[[VERIFICAR ISSO ]]]]]

NavigationInfo {
type [ "ANY" ]
}
Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1.0 1.0 1.0
}
}
geometry Sphere {}
}
]
}

• Exemplo de um arquivo em X3D codificado em XML


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "http://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D profile="Immersive">
<Scene>
<NavigationInfo type="ANY"/>
96
<Transform>
<Shape>
<Appearance>
<Material diffuseColor=”1.0 1.0 1.0”/>
</Appearance>
<Sphere/>
</Shape>
</Transform>
</Scene>
</X3D>

Estes arquivos deve produzir simplesmente uma esfera branca

Figura 2-31 – Imagem visualizada do exemplo


O X3D emprega uma arquitetura modular para prover uma maior estensibilidade
e flexibilidade. A maioria dos domínios de aplicações não necessitam de todos os
recursos do X3D, tão pouco todas as plataforma suportam a gama de funcionalidades
definidas na especificação. Os recursos do X3D são agrupados em componentes
(components) que podem ser suportados pela implementação em uma mistura de
capacidades para atingir as necessidades de um mercado ou plataforma em particular. O
X3D também introduz o conceito de perfis (profiles) - uma pré-definida coleção de
componentes comumente encontrados em certos domínios de aplicações , plataformas,
ou um cenário de uso, por exemplo trocas de geometrias entre ferramentas de
modelagem. Diferente do VRML97, na qual requer um completo suporte de suas
funcionalidades para estar em conformidade, o X3D permite vários graus de suporte do
padrão para atingir uma variedade de necessidades. O mecanismo de componentes do
X3D também permite desenvolvedores a implementar suas próprias extensões de acordo
com um rigoroso conjunto de regras, ajudando a evitar a "torre de babel" das extensões
dos desenvolvedores que surgiram no VRML97 nos últimos anos.
Finalmente, a especificação do X3D por si mesma tem sido reestruturada,
permitindo um ciclo de vida mais flexível para acomodar as evoluções dos padrões. O
padrão X3D é divido em três especificações separadas lidando com conceitos abstratos
de arquitetura, codificação de arquivo e acesso de linguagem de programação. Este
97
enfoque permite à especificação mudar durante o tempo e facilita sua adoção através da
ISO para especificar partes da especificação conforme necessário.

2.5 Transição do VRML para o X3D


A mudança básica que deve ser efetuada caso para a conversão entre VRML97 e
o “X3D clássico” é mudar o cabeçalho de:
#VRML V2.0 utf8
para
#X3D V3.0 utf8
Profile Immersive
Existe agora a necessidade de se definir o profile para que o navegador saiba o
grau de recursos a serem utilizados, uma outra diferença é a forma de se chamar scripts
no X3D. No VRML97 as chamadas eram feitas com 'javascript' ou 'vrmlscript'. O X3D
usar o chamado 'ecmascript'. ECMAScript é a versão padronizada do JavaScript.
Existem diversas ferramentas disponíveis que podem fazer a conversão entre
VRML97 e X3D. Se você tem um arquivo relativamente simples que não contem scripts
ou externprotos então você pode editar manualmente o texto para trocar o cabeçalho e
inserir a nova declaração PROFILE que você estará com o documento pronto. Qualquer
coisa mais complexa vai requerer uma ferramenta e idealmente um razoável trabalho de
conhecimento com a nova especificação (diversas áreas funcionais foram mudadas para
serem mais rigorosas ou apenas são simplesmente diferentes).
Existem algumas ferramentas para a conversão de conteúdo, uma delas é o X3D-
Edit, porém é possível também a utilização de algumas ferramentas por linha de código.
Usualmente basta um programa capaz de converter os nós de um formato de codificação
para outro.
Um cuidado que se deve tomar é que um arquivo VRML97 não é exatamente
um arquivo X3D. Um navegador puramente X3D poderá não será capaz de ler um
arquivo VRML97 logo que existem mudanças na sintaxe que levam os dois a
incompatibilidades. Entretanto, a maioria dos navegadores que suportam o padrão X3D
também suportam o padrão VRML97. Provavelmente no futuro a maioria dos
navegadores ira suportar arquivos X3D, e alguns ainda suportarão o formato VRML97.
Existem mudanças entre o VRML97 e o X3D sutis e não tão sutis. Algumas são:
98
• Os arquivos estão agora estruturados para definir as capacidades necessárias
como parte do cabeçalho. Isto necessita que ao menos seja definido o perfil
(profile) e qualquer componente (component) extra.

• Externprotos agora são usados somente para definir conteúdo externo ao arquivo
X3D. Eles não podem ser usados para prover mecanismos de extensão para o
navegador. A forma de prover extensões específicas para o navegador é através
de componentes (components) adaptados.

• Nomes de acesso para campos mudaram de eventIn, eventOut, field e


exposedField, para inputOnly, outputOnly, initializeOnly e inputOutput,
respectivamente.

• Scripts podem ter campos inputOutput (exposedFields) definidos.

• Um nome DEF não pode ser multi definido mais.

• Todo conteúdo de leitura é desacoplado. Onde no VRML97 necessitaria que


scripts fossem carregados antes da execução começar, X3D remove esta
necessidade e define que o arquivo começa a executar primeiro e depois de certo
tempo, recursos (scripts, texturas, sons, inlines, externprotos) são carregados.

• O modelo de execução entre o conteúdo de um script e o grafo de cena é


rigorosamente definido e precisamente controlado. Onde o VRML97 permite um
script multi-threaded arbitrariamente trocar o grafo de cena em qualquer ponto, o
X3D define somente certos ponto onde estas alterações podem ser feitas.

• A execução e modelo de programação para scripts é consistente entre linguagens


de programação e aonde quer que você esteja, dentro ou fora do navegador -
uma definição da API é regra geral.

• Rigorosa definição de conjunto de definições de tipos abstratos para nós.

Os arquivos X3D devem seguir as seguintes regras:

Extensões
Codificação X3D Extensão de arquivo Tipo MIME
Compactadas

Clássico VRML .x3dv .x3dvz, .x3dv.gz model/x3d+vrml


XML .x3d .x3dz, .x3d.gz model/x3d+xml
99
Binário .x3db .x3dbz, .x3db.gz model/x3d+binary
* os tipos MIME ainda estão sendo aprovados

2.6 Utilização de Ferramentas


Devido ao sistema de grafo de cena, a construção de ambientes em VRML97 ou
X3D pode ser feita diretamente em qualquer editor de texto. Contudo a edição por texto
é de grande complexidade. Assim a utilização de ferramentas pode auxiliar em muito.
No caso do VRML97 temos o VRML-Pad. Já para o X3D uma das possibilidades é o
X3D-Edit. Este aplicativo em Java pode editar arquivos X3D de uma forma muito
simples e também permite a abertura de arquivos no formato VRML97. Existe um
grande número de ferramentas úteis relacionadas com o X3D, incluindo conversões
stylesheet entre VRML97 e pacotes de edição baseados em XML para arquivos X3D.
Se você está trabalhando neste nível, um bom entendimento de conceitos de
computação gráfica é necessário, e para efeitos visuais avançados, como o uso de
multitexturing, environment mapping, programmable shaders e mais, um conhecimento
prático de programação gráfica 3D (p.e. OpenGL Direct3D etc) será uma vantagem.
Também existem uma série de aplicativo gerais, usualmente conhecidos como
modeladores que podem modelar objetos, animar eles, e as vezes até inserir os
comandos específicos do VRML97/X3D. Isto cria uma grande facilidade para o
desenvolvimento dos mundos virtuais, e é algo que o VRML97/X3D se destaca dos
outros formatos de arquivo. É esperado que ferramentas e conteúdo gerado
automaticamente prevalecerá sobre conteúdos editados a mão.
Finalmente abordaremos alguns dos navegadores utilizados para ver o contudo
do arquivos criados e navegar neles. Usualmente eles estão conectados aos navegadores
da Web como o Netscape ou Internet Explorer, contudo outros são mais independentes e
usualmente apresentam mais funcionalidades.

2.6.1 Editando os arquivos VRML97 e X3D


VRML-Pad
Editor simples de ser usado, desenvolvido pela Paralellgraphics
(www.paralellgraphics.com), o VRMLPad apresenta diversos recursos, como a edição
de extrusões, definição de cores e texturas etc.
100
A Figura 2-32 apresenta a tela principal do editor, onde podem ser obervadas as áreas de
janela de edição e auxiliar – que permite que sejam verificados arquivos em uso,
diretórios, grafo de cena e mapa de rotas.

Figura 2-32 Tela principal do VRMLPad


X3D-Edit

Figura 2-33 – Exemplo de janela do X3D-Edit


101

2.6.2 Editando os arquivos VRML97 e X3D de forma mais avançada

Maya
O Maya é uma ferramenta muito utilizada para a criação de filmes no ciname.
Contudo ela possui um sistema avançado de modelagem, e ativando o seu plug-in é
possível salvar o arquivo no formato VRML97. Alguns cuidados devem ser tomados,
pois poderão haver perdas de informação, pois infelizmente o conversor do Maya não é
completo o suficiente.

Figura 2-34 – Exemplo de modelagem com o Maya

3D-Studio
O 3D-Studio assim como o Maya apresenta uma série de vantagens para a
modelagem. E da mesma forma apresenta uma ferramenta para exportar os dados para
arquivos VRML97.

• Visualizando arquivos VRML97 e X3D

Cosmo
O Cosmo foi um dos primeiros navegadores desenvolvidos para visualizar
arquivos VRML, contudo não sofreu grandes avanços desde então. Assim apresenta
alguns limites.
102
Xj3D
Existe uma implementação código aberto (Open Source) escrita em Java
chamada de Xj3D. Uma aplicação funcional está disponível hoje e tem sido testada
sobre Linux, Solaris e Win32. O Xj3D é baseado em Java3D, logo necessita o Java3D
para rodar, como o Java3D necessita o Java 2, uma grande quantidade de dados deve ser
instalado para a utilização do Xj3D. O navegador Xj3Dé uma boas fonte para
implementação.

JINX
O sistema JINX é um navegados estritamente X3D, que pode ser utilizado em
ambientes de aglomerados de computadores e sistemas de projeções mais variados,
desde simples monitores até avançados sistema de projeção cúbica como Cavernas e
Domos. Este projeto ainda esta em desenvolvimento.

Figura 2-35 – Exemplo de aplicação básica rodando na JINX

2.7 Referências deste capítulo

AMES, L. A.; NADEAU, R.D.; MORELAND D. VRML Sourcebook - Second


Edition, John Wisley & Sons, Inc - USA, 1997.

CARDOSO, A.; LAMOUNIER E.; TORI R. Sistema de Criação de Experiências de


Física em Realidade Virtual para Educação a Distância. In: II WORKSHOP
BRASILEIRO DE REALIDADE VIRTUAL, WRV´99, Marília , São Paulo, Brasil,
1999, p. 174-181.

CARDOSO, A. Alexandre Cardoso - Página do Pesquisador. Contém informações sobre


aplicações de Realidade Virtual, pesquisa e publicações do pesquisador, tutoriais
103
sobre VRML e artigos indicados para leitura. Disponível em:
<http://www.compgraf.ufu.br/alexandre/>. Acesso em Set./2003

CHEN, S.; MYERS, R.; PASSETO, R. The Out of Box Experience - Lessons Learned
Creating Compelling VRML 2.0 Content. In: Proceedings of the Second Symposium
on Virtual Reality Modeling Language, p. 83-92, 1997.

EcmaScript Specification (JavaScript), disponível em http://www.ecma.com, Search,


EcmaScript, EC 262

ELLIS R. S. What are Virtual Environments. IEEE Computer Graphics and


Applications, p. 17-22, Jan. 1994.

LEMAY, MURDOCK, COUCH 3D Graphics and VRML 2 Sams.Net, Indiana - USA


– 1996

Introducing X3D by Leonard Daly, Don Brutzman, Nicholas Polys, Joseph D.


Williams, SIGGRAPH 2002. Curso introdutório de X3D, disponível em
http://realism.com/Web3D/x3d/s2002, acessado em Agosto 2004

MATSUBA, N.; STEPHEN; ROEHL, B. Bottom, Thou Art Translated: The Making of
VRML Dream. IEEE Computer Graphics and Applications, v. 19, n. 2, p. 45-51,
Mar./Apr. 1999.

Scenario Authoring and Visualization for Advanced Graphical Environments (Savage)


project at http://web.nps.navy.mil/~brutzman/Savage/contents.html

Vapor Tutorial VRML - Tutorial de VRML com exemplos e fontes. Disponível em


http://web3d.vapourtech.com/. Acesso em Set./2003

VRMLPAD. Parallellgraphis. O sítio disponibiliza diversos programas computacionais


de grande utilidade para desenvolvimento de ambientes virtuais em VRML, inclusive
o programa VRMLPad. Disponível em: <http://www.parallellgraphics.com>. Acesso
em: 02 nov. 2000.

XML. Extensible Markup Language (XML) http://www.w3.org/XML/

Harold, E. R., Means, W. S., XML in a Nutshell, 2nd Edition, O'Reilly; 2nd edition,
2002
104

3 Ambientes Virtuais em Java


Ricardo Nakamura, Romero Tori

INTERLAB - Laboratório de Tecnologias Interativas


Departamento de Engenharia de Computação e Sistemas Digitais
Escola Politécnica da Universidade de São Paulo
Av. Prof. Luciano Gualberto, travessa 3 no. 158 - CEP 05508-900 - São Paulo, SP

{ricardo.nakamura, romero.tori}@poli.usp.br

3.1 Introdução
O desenvolvimento de ambientes virtuais é uma tarefa complexa pois envolve a
integração de diferentes tecnologias e áreas de conhecimento. Hoje em dia, existem
vários sistemas de autoria e bibliotecas de programação para Realidade Virtual que
procuram reduzir essa complexidade. Ferramentas como WorldToolkit, ARToolkit e
VRML apresentam diferentes soluções para atingir este objetivo e trazem consigo
vantagens e desvantagens. O objetivo deste minicurso é apresentar a linguagem Java e
suas bibliotecas de programação como mais uma alternativa para o desenvolvimento de
ambientes virtuais. Não se pretende com isso implicar que esta solução seja melhor ou
pior do que qualquer outra, inclusive pelo fato de que este tipo de julgamento depende
do contexto. Entretanto, espera-se que as informações apresentadas possam contribuir
para os conhecimentos dos participantes em futuros projetos.
Este texto tem como objetivo servir como material complementar e de referência
para o minicurso. Desta forma, foi dada prioridade para a apresentação de exemplos de
código-fonte, figuras e diagramas explicativos.

3.2 A Linguagem Java


Este curso não pretende fazer uma apresentação ou revisão da linguagem Java.
Entretanto, existem alguns pontos de interesse para a construção de ambientes virtuais
que serão expostos.

3.2.1 Carregamento Dinâmico de Classes


A linguagem Java permite facilmente o carregamento de novas classes durante a
execução do programa. Este recurso pode ser explorado para desenvolver mecanismos
105
de plug-ins e extensão através de objetos criados pelo usuário. O código da Listagem
3.1 mostra uma maneira de fazer isso, usando os métodos forName e newInstance. Um
problema desta abordagem é que a classe sendo construída precisa ter um construtor
sem parâmetros. Por exemplo, se a classe “ClasseDinamica” não tiver tal construtor, o
código irá gerar uma exceção.
Uma alternativa é utilizar o mecanismo de reflection, usando as classes do
pacote java.lang.reflect, que permite obter informações sobre os atributos e métodos de
uma classe em tempo de execução. Na Listagem 3.2, por exemplo, uma lista dos
construtores públicos da classe é obtida. Esta lista é percorrida buscando um construtor
que recebe somente um parâmetro do tipo int e este construtor é usado para criar um
novo objeto.
Listagem 3.1 – Carregamento Dinâmico de Classes
public class CarregamentoDinamico {
public static void main(String[] args) {
CarregamentoDinamico cd = new CarregamentoDinamico();
cd.exemplo();
}

public void exemplo() {


Class minhaClasse = getClass();

String nomeClasse = "ClasseDinamica";

try {
Class classeDin = minhaClasse.forName(nomeClasse);
Object objeto = classeDin.newInstance();
System.out.println(objeto);
}
catch(ClassNotFoundException ex) {
System.out.println("A Classe não existe!");
}
catch(IllegalAccessException ex) {
System.out.println("Erro ao criar o objeto dinamicamente");
}
catch(InstantiationException ex) {
System.out.println("Erro ao criar o objeto dinamicamente");
}
}
}
Num sistema real, uma interface pública para plug-ins ou extensões poderia ser
definida, para permitir que usuários criassem seus próprios objetos. Os objetos criados
dinamicamente seriam convertidos para esta interface pública, para utilização dentro do
sistema. Existem também muitos outros detalhes sobre o uso de reflection que não serão
discutidos aqui devido ao escopo deste curso, mas que devem ser estudados no caso de
se usar este recurso da linguagem Java.
Listagem 3.2 - Carregamento Dinâmico com Reflection
106
import java.lang.reflect.*;

public class CarregamentoDinamico2 {


public static void main(String[] args) {
CarregamentoDinamico2 cd2 = new CarregamentoDinamico2();
cd2.exemplo();
}

public void exemplo() {


Class minhaClasse = getClass();

String nomeClasse = "ClasseDinamica";

try {
Class classeDin = minhaClasse.forName(nomeClasse);

Constructor[] construtores = classeDin.getConstructors();


if (construtores.length == 0) {
System.out
.println("Esta classe não tem construtores públicos");
}
else {
int numConstrutor = -1;
for (int i = 0; i < construtores.length; i++) {
Class[] params = construtores[i].getParameterTypes();
if (params.length == 1 &&
Integer.TYPE.equals(params[0])) {
numConstrutor = i;
}
}
if (numConstrutor == -1) {
System.out
.println("Nenhum construtor adequado foi encontrado");
}
else {
Object[] params = new Object[1];
params[0] = new Integer(42);
Object objeto =
construtores[numConstrutor].newInstance(params);
System.out.println(objeto);
}
}
}
catch(ClassNotFoundException ex) {
System.out.println("A Classe não existe!");
}
catch(IllegalAccessException ex) {
System.out.println("Erro ao criar o objeto dinamicamente");
}
catch(InstantiationException ex) {
System.out.println("Erro ao criar o objeto dinamicamente");
}
catch(IllegalArgumentException ex) {
System.out.println("Erro: Parâmetros incorretos");
}
catch(InvocationTargetException ex) {
System.out.println("Erro: construtor gerou uma exceção");
}
}
}
107
3.2.2 Controle de Segurança
A capacidade de aceitar código gerado por usuários pode tornar o sistema
vulnerável a código mal-intencionado. Entretanto, a linguagem Java possui um sistema
de controle de acesso que permite restringir as operações que uma classe pode realizar.
Isso pode ser feito de duas maneiras: através de um arquivo de policy ou criando uma
subclasse de SecurityManager.
O uso de um arquivo de policy é relativamente mais simples, pois pode-se usar a
ferramenta gráfica policytool, mostrada na Figura 3-1, para editar as permissões. Com
essa ferramenta, é possível restringir o acesso a arquivos, conexões de rede, outras
classes etc. fazendo com que classes criadas por usuários não possam causar danos
extensivos ao sistema. Este é essencialmente o mecanismo utilizado para restringir as
ações que applets Java podem realizar.

Figura 3-1 - A ferramenta policytool


Um arquivo de policy pode ser utilizado pela aplicação através da especificação
de duas propriedades quando a máquina virtual Java é executada, como mostrado no
exemplo a seguir. Neste caso, o arquivo “my.policy” está sendo utilizado para definir as
permissões de acesso válidas para a aplicação.
java -Djava.security.manager
-Djava.security.policy=my.policy MinhaAplicacao
108
A alternativa a usar o arquivo de policy é implementar uma subclasse de
SecurityManager, que era a única solução antes do Java 1.2. Atualmente, entretanto,
esta solução é muito mais trabalhosa e sujeita a erros. Portanto ela deveria ser reservada
para casos em que claramente o arquivo de policy não atende às necessidades do sistema
sendo desenvolvido.

3.3 Java 3D

3.3.1 Grafo de Cena


O Java 3D utiliza uma estrutura de Grafo de Cena para descrever o mundo
virtual que será apresentado ao usuário. O grafo de cena do Java 3D é um grafo
direcionado acíclico, que estabelece relações hierárquicas entre dois nós conectados por
um arco. Se dois nós A e B são conectados por um arco (na direção AB), o nó A é dito
“pai” do nó B e o nó B é “filho” do nó A. O Grafo de Cena contém um nó inicial,
chamado de Universo, que não tem pai. As transformações de estado se propagam dos
pais para os filhos no grafo de cena do Java 3D. Desta forma, o conjunto de estados
(transformações geométricas e outros atributos) de uma folha (nó sem filhos) do grafo é
determinado pela acumulação recursiva dos estados dos seus pais, até o universo.

Universe

Locale

Group

Leaf

Figura 3-2 - Grafo de Cena


A Figura 3-2 ilustra um grafo de cena típico. Os nomes indicados na figura são
os nomes das classes correspondentes utilizadas no Java 3D. Da mesma forma, os
símbolos são os convencionalmente utilizados ao representar estes grafos. Pode-se fazer
uma analogia entre a estrutura do grafo de cena do Java 3D e a estrutura de dados em
109
“árvore” – as próprias classes do Java 3D usam a nomenclatura (ramos, folhas)
normalmente aplicada para árvores. Além disso, o comportamento do grafo de cena é
bastante similar ao das estruturas hierárquicas construídas com VRML, o que pode
facilitar a sua compreensão por pessoas familiarizadas com aquela linguagem.
O Java 3D traz uma série de classes utilitárias que podem ajudar a realizar
algumas das tarefas mais comuns. Uma delas é a ConfiguredUniverse que faz toda a
inicialização da biblioteca e cria uma janela de visualização. Esta classe também
permite o uso de arquivos de configuração, como será visto mais adiante. A Listagem
3.3 apresenta um exemplo de uso desta classe. O resultado é uma janela de visualização
do Java 3D (sem nada visível inicialmente).
Listagem 3.3 - Uso da classe Configured Universe
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;

public class Java3DSimples {


public static void main(String[] args) {
Java3DSimples j3s = new Java3DSimples();
j3s.exemplo();
}

private void exemplo() {


ConfiguredUniverse uni = new ConfiguredUniverse();
}
}

3.3.2 NodeComponents
Além dos objetos que compõem a estrutura do grafo de cena, o Java 3D define
um conjunto de objetos acessórios, representados pela classe NodeComponent e suas
subclasses. Estes objetos definem parâmetros para os objetos do grafo. A Figura 3-3
apresenta um grafo de cena contendo um NodeComponent.
110

Universe

Locale

NodeComponent
Leaf

Figura 3-3 - Grafo com NodeComponents


Como se pode observar na Figura 3-3, os arcos de um nó do grafo para um
NodeComponent são indicados por linhas curvas pontilhadas. Um fato mais importante
é que estes componentes podem ser compartilhados por mais de um objeto, como é
ilustrado naquela figura. Isso não viola a estrutura do grafo acíclico pois os
NodeComponents são parâmetros mas não fazem parte do grafo.

3.3.3 Principais Classes do Java 3D


ViirtualUniverse: um objeto desta classe é sempre o nó inicial ou raiz do grafo
de cena. Subclasses como ConfiguredUniverse agregam vários serviços, simplificando
a sua utilização.
Locale: um objeto desta classe sempre é conectado como único filho de uma
instância de VirtualUniverse. O Locale representa o sistema de coordenadas do mundo
virtual, e apresenta alguns métodos utilitários.
BranchGroup: objetos desta classe servem como raízes dos subgrafos ou ramos
do grafo de cena. Somente BranchGroups podem ser adicionados como filhos de um
Locale. Além disso, somente BranchGroups podem ser adicionados ou removidos de
um grafo de cena conectado ao universo.
TransformGroup: objetos desta classe são utilizados para aplicar
transformações geométricas sobre seus filhos. Através da agregação de vários
TransformGroups é possível criar conjuntos hierárquicos de transformações, que
facilitam a composição de cenas complexas.
111
Shape3D: esta classe é utilizada para representar objetos geométricos no mundo
virtual. É relativamente incomum utilizar esta classe diretamente, visto que em geral são
empregadas classes utilitárias que constroem as estruturas geométricas a partir de
arquivos ou outras formas de especificação.
Light: esta é a classe abstrata que define uma fonte de luz no Java 3D. Suas
subclasses correspondem aos tipos de fonte de luz normalmente encontrados em
Computação Gráfica.
Appearance: objetos desta classe (que é um NodeComponent) armazenam os
parâmetros de aparência dos objetos que compõem o mundo virtual. Esta classe utiliza
agregação de forma intensiva; um conjunto de outras classes como Material, Texture,
ColoringAttributes (e outras classes de atributos) descrevem cada parâmetro.
O Java 3D inclui também um pacote chamado javax.vecmath que contém várias
classes para trabalhar com vetores e matrizes. Estas classes têm uso bastante intuitivo e
por este motivo não serão explicadas separadamente no texto, entretanto serão utilizadas
nos exemplos.

3.3.4 Capabilities
Por questões de otimização, o Java 3D apresenta o conceito de capabilities. Em
resumo, quando um nó é conectado ao universo do grafo de cena, suas propriedades não
podem mais ser alteradas – a não ser que o programador tenha indicado anteriormente
que determinadas propriedades precisariam ser alteradas. A maneira de indicar isso é
através do método setCapability que é definido na classe SceneGraphObject e
portanto está presente na maioria das classes do Java 3D. Cada classe possui
capabilities diferentes. A Listagem 3.4 exemplifica o uso de uma capability da classe
BranchGroup, que permite que um ramo do grafo de cena seja desconectado do
universo posteriormente. Executando este programa, veremos uma saída como:
Tentativa 1 não funcionou
Tentativa 2 funcionou
Comparando as duas tentativas, veremos que a diferença está na chamad do
método setCapability. Recomenda-se acessar a documentação das classes do Java 3D,
para saber quais as capabilities existentes.
Listagem 3.4 - Exemplo do uso de capabilities
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;

public class Java3DCapability {


public static void main(String[] args) {
112
Java3DCapability j3c = new Java3DCapability();
j3c.exemplo();
}

private void exemplo() {


ConfiguredUniverse uni = new ConfiguredUniverse();
try {
BranchGroup bg = new BranchGroup();
uni.addBranchGraph(bg);
bg.detach();
System.out.println("Tentativa 1 funcionou");
}
catch(CapabilityNotSetException ex) {
System.out.println("Tentativa 1 não funcionou");
}

try {
BranchGroup bg = new BranchGroup();
bg.setCapability(BranchGroup.ALLOW_DETACH);
uni.addBranchGraph(bg);
bg.detach();
System.out.println("Tentativa 2 funcionou");
}
catch(CapabilityNotSetException ex) {
System.out.println("Tentativa 2 não funcionou");
}
}
}

3.3.5 Loaders
O Java 3D define uma interface comum para carregamento de conteúdo através
das interfaces Loader e Scene. Um loader é uma classe capaz de carregar modelos em
um determinado formato (como por exemplo 3DS, OBJ, WRL) e converter tais modelos
em um grafo do Java 3D. A interface Scene define uma maneira uniforme de ter acesso
aos modelos carregados. A Listagem 3.5 demonstra uma forma simples de utilizar um
loader. Neste exemplo foi utilizado um loader distribuído com o Java 3D, entretanto a
sintaxe seria exatamente a mesma para qualquer classe que implemente a interface
Loader.
Listagem 3.5 - Exemplo de uso de um Loader
import com.sun.j3d.loaders.objectfile.*;
import com.sun.j3d.loaders.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;

public class LoaderSimples {


public static void main(String[] args) {
LoaderSimples ls = new LoaderSimples();
ls.exemplo();
}

private void exemplo() {


ConfiguredUniverse uni = new ConfiguredUniverse();
113

try {
ObjectFile loader = new ObjectFile();
Scene cena = loader.load("conteudo.obj");
BranchGroup bg = cena.getSceneGroup();
uni.addBranchGraph(bg);
}
catch(java.io.FileNotFoundException ex) {
System.out.println("Arquivo não encontrado");
}
catch(IncorrectFormatException ex) {
System.out.println("Formato incorreto para os dados");
}
catch(ParsingErrorException ex) {
System.out.println("Erro na interpretação do arquivo");
}
}
}
Uma dificuldade existente com os loaders, ou mais especificamente com a
interface Loader, é que não existe uma maneira uniforme para obter informações de
animação do modelo carregado. Alguns loaders simplesmente ignoram informações de
animação dos modelos, enquanto outros incluem métodos adicionais para retornar este
tipo de informação. O resultado é que embora o carregamento de modelos estáticos seja
extremamente simples no Java 3D, a implementação de animação destes modelos pode
se tornar bastante complexa.

3.3.6 Behaviors
No Java 3D, Behaviors são os objetos responsáveis por toda a funcionalidade de
interação, navegação e animação. Cada Behavior é uma folha do grafo de cena que
define código que deve ser executado quando um ou mais critérios são satisfeitos.
Alguns dos critérios possíveis são:
• executar o código a cada N segundos;
• executar o código quando o usuário mover o mouse;
• executar o código quando uma região estiver visível.
Adicionalmente, cada Behavior possui um volume de ativação. Os critérios de
execução de um Behavior somente são verificados quando o view frustum intercepta o
seu volume de ativação (ou seja, quando o volume de ativação estaria “visível” para o
usuário). Por exemplo, na Figura 3-4, o Behavior 1 poderia ser executado (dependendo
das suas condições de ativação) enquanto o Behavior 2 não seria executado de forma
alguma.
114

Volume de Ativação
Behavior 1

View Frustum

Câmera

Volume de Ativação
Behavior 2

Figura 3-4 - Volume de Ativação dos Behaviors


A classe Behavior é uma classe abstrata. Usuários criam as suas subclasses
definindo dois métodos, initialize e processStimulus. O primeiro método é executado
quando o Behavior é conectado ao grafo de cena que contém o universo. O segundo é
executado quando a sua região de ativação está “visível” e os seus critérios são
satisfeitos.A Listagem 3.6 apresenta um exemplo simples de definição e uso de uma
subclasse de Behavior. Neste caso, a classe MeuBehavior simplesmente é executada a
cada 100ms e imprime texto para o console.
Listagem 3.6 - Exemplo de Behavior
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;

public class Java3DBehavior {


public static void main(String[] args) {
Java3DBehavior j3c = new Java3DBehavior();
j3c.exemplo();
}

private void exemplo() {


ConfiguredUniverse uni = new ConfiguredUniverse();

MeuBehavior b = new MeuBehavior();

// define uma região de ativação esférica, com


// raio 10, centrada na posição do behavior
BoundingSphere s = new BoundingSphere();
s.setRadius(10);
b.setSchedulingBounds(s);

// o behavior é adicionado como outro nó qualquer


BranchGroup bg = new BranchGroup();
115
bg.addChild(b);

uni.addBranchGraph(bg);
}
}

class MeuBehavior extends Behavior {


WakeupOnElapsedTime wk;

public void initialize() {


// define uma condição de ativação:
// executar a cada 100 ms
wk = new WakeupOnElapsedTime(100);
wakeupOn(wk);
}

public void processStimulus(java.util.Enumeration e) {


System.out.println("100 milissegundos se passaram");

// reativa a condição, caso contrário o


// Behavior não será mais executado.
wakeupOn(wk);
}
}
Um detalhe importante do código apresentado no exemplo é a última linha do
método processStimulus. Se o Behavior deve ser executado novamente, ele deve
chamar outra vez o método wakeupOn para reativar os seus critérios de ativação. Este
mecanismo funciona assim para permitir tanto Behaviors que são executados uma só
vez como outros que executam cada vez que o critério é satisfeito. Da mesma forma, o
Behavior pode alterar a cada execução os seus critérios de ativação para conseguir
alguns comportamentos mais complexos.
Se, por algum motivo, houver a necessidade de desabilitar o uso de volumes de
ativação para um Behavior (por exemplo, se o Behavior deve executar sempre,
independentemente da posição relativa do usuário ou câmera) pode-se criar uma esfera
de raio infinito. Isto é feito através do seguinte código:
BoundingSphere s = new BoundingSphere();
s.setRadius(Double.POSITIVE_INFINITY);

O uso da constante Double.POSITIVE_INFINITY faz com que o Java 3D


automaticamente ignore a checagem de interseção entre o volume de ativação e o view
frustum. Esta solução é mais eficiente e mais robusta do que, por exemplo, usar um
número “grande” para o raio.
Obviamente, aplicações práticas de Behaviors são bem mais interessantes (e
extensas) tais como tratar eventos de teclado e mouse para realizar navegação e
manipulação de objetos e implementar sistemas de animação. Por exemplo, um
Behavior pode receber, em seu construtor, uma referência para outro nó do grafo de
116
cena (como um TransformGroup) e, no método processStimulus, alterar propriedades
deste nó.
É importante entender a motivação para o uso dos Behaviors. A princípio, usar
um KeyListener na janela da aplicação para tratar eventos de teclado, ou ainda um
TimerTask para realizar a execução repetida de código podem parecer soluções mais
simples. Entretanto, existem duas razões para o uso de Behaviors no Java 3D:
• Desempenho: através do uso cuidadoso das condições e volumes de
ativação, é possível ter uma grande quantidade de Behaviors em um
ambiente virtual complexo, sem que isso cause um consumo exagerado
de processamento;
• Sincronização: o Java 3D efetivamente utiliza-se de várias threads de
execução simultânea, responsáveis entre outras coisas pela atualização do
grafo de cena e geração das imagens renderizadas. Os Behaviors são, a
princípio, a única maneira segura de alterar componentes ativos do grafo
de cena (isto é, objetos que estão ligados ao universo).
O Java 3D também conta com vários pacotes de Behaviors utilitários que
podem facilitar a escrita de aplicações:
• com.sun.j3d.utils.behaviors.interpolators: vários Behaviors para
realizar interpolação sobre um TransformGroup, úteis para fazer
animações simples;
• com.sun.j3d.utils.behaviors.keyboard: para tratamento de eventos e
navegação através do teclado;
• com.sun.j3d.utils.behaviors.mouse: para tratamento de eventos,
manipulação e navegação através do mouse;
• com.sun.j3d.utils.behaviors.sensor: para integração com dados
fornecidos por Sensors (que serão tratados mais adiante).
Listagem 3.7 - Exemplo de uso de MouseRotate
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class Java3DRotate {


public static void main(String[] args) {
Java3DRotate j3r = new Java3DRotate();
j3r.exemplo();
}
117
private void exemplo() {
ConfiguredUniverse uni = new ConfiguredUniverse();

Transform3D t3d = new Transform3D();


t3d.set(new Vector3d(0, 0, -10));
TransformGroup tg1 = new TransformGroup(t3d);

TransformGroup tg2 = new TransformGroup();


tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

tg2.addChild(new ColorCube());
tg1.addChild(tg2);

BranchGroup bg = new BranchGroup();


bg.addChild(tg1);

MouseRotate b = new MouseRotate();


b.setTransformGroup(tg2);

BoundingSphere s = new BoundingSphere();


s.setRadius(20);
b.setSchedulingBounds(s);

bg.addChild(b);

uni.addBranchGraph(bg);
}
}
A Listagem 3.7 apresenta um exemplo de uso do Behavior utilitário
MouseRotate. Este programa cria um grafo de cena simples, incluindo um cubo
colorido na frente da câmera. O Behavior é utilizado para permitir que o usuário
rotacione este cubo colorido na tela ao clicar e arrastar o mouse.

3.3.7 Configuração de Ambiente e Visualização


Até o momento, a discussão sobre o Java 3D assumiu um ambiente de aplicação
pré-configurado e se concentrou na geração de conteúdo para o mundo virtual.
Entretanto, uma das características interessantes desta API é a possibilidade de ajustá-la
para configurações de hardware não convencionais.
As próximas seções tratam de detalhes sobre esta configuração, mas antes de
mais nada é preciso estabelecer o modelo geral de visualização do Java 3D. A Listagem
3.8 traz o código para construir uma aplicação Java 3D sem usar classes utilitárias e
mostra as classes envolvidas.
Listagem 3.8 - Configuração Completa do Java 3D
import javax.swing.*;

import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.geometry.ColorCube;
118

import javax.media.j3d.*;
import javax.vecmath.*;

public class Java3DView {


public static void main(String[] args) {
Java3DView j3v = new Java3DView();
j3v.exemplo();
}

private void exemplo() {


VirtualUniverse uni = new VirtualUniverse();
Locale loc = new Locale(uni);

// constrói o ramo de visualização


BranchGroup viewGroup = new BranchGroup();

Transform3D t3d = new Transform3D();


t3d.lookAt(new Point3d(0, 0, 10),
new Point3d(0, 0, 0),
new Vector3d(0, 1, 0));
t3d.invert();
TransformGroup viewTrans = new TransformGroup(t3d);

ViewPlatform camera = new ViewPlatform();

viewTrans.addChild(camera);
viewGroup.addChild(viewTrans);
loc.addBranchGraph(viewGroup);

// cria um Canvas3D, componente para exibição de imagens


GraphicsConfiguration gc =
SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas = new Canvas3D(gc);

// cria uma janela para a aplicação


JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400, 300);
window.getContentPane().add(canvas);

// cria e configura um objeto view, e associa


// à câmera e canvas criados anteriormente
View view = new View();
PhysicalBody pb = new PhysicalBody();
view.setPhysicalBody(pb);
PhysicalEnvironment pe = new PhysicalEnvironment();
view.setPhysicalEnvironment(pe);
view.addCanvas3D(canvas);
view.attachViewPlatform(camera);

// cria um cubo colorido na cena,


// para termos algo para visualizar
ColorCube cc = new ColorCube();
BranchGroup bg = new BranchGroup();
bg.addChild(cc);
loc.addBranchGraph(bg);

// mostra a janela
window.show();
}
119
}
A primeira coisa que se observa é que esta versão parece bem mais complexa do
que a Listagem 3.3, que tem o mesmo resultado (exceto por não desenhar o cubo
colorido, mas isso é resolvido com 4 linhas de código).

View Canvas3D

ViewPlatform

PhysicalBody PhysicalEnvironment

Figura 3-5 - Estrutura de Visualização do Java 3D


Entretanto, a Listagem 3.8 serve para demonstrar a construção da estrutura de
visualização do Java 3D, que é ilustrada na Figura 3-5. Essencialmente, um objeto da
classe View faz a ligação entre um objeto da classe ViewPlatform e outro da classe
Canvas3D. O primeiro atua como uma câmera dentro do mundo virtual, indicando a
posição dos olhos do observador. O segundo é um componente visual que deve ser
inserido dentro de uma janela gráfica para apresentar a renderização do mundo virtual.
Em vez de fazer toda a configuração manualmente através de código, também é
possível usar simplesmente a classe ConfiguredUniverse e especificar um arquivo de
configuração no construtor. Este processo simplifica bastante o código e ainda permite
flexibilidade no uso de diferentes dispositivos. A documentação do Java 3D,
especialmente da classe ConfiguredUniverse, traz a sintaxe e exemplos de arquivos de
configuração.

3.3.8 Views
Como visto acima, a classe View faz a ligação entre uma câmera no mundo
virtual e um componente visual, que mostra a imagem renderizada. Os parâmetros desta
classe, juntamente com objetos das classes PhysicalBody e PhysicalEnvironment,
120
permitem adaptar a visualização para diferentes configurações como: monitor
convencional, monitor com imagens estereoscópicas, caverna virtual etc.
Em primeiro lugar, a classe View contém uma série de métodos que permitem
ajustar parâmetros de visualização como abertura do campo de visão, tipo de projeção,
planos de clipping e outros. Recomenda-se consultar a documentação do Java 3D para
saber todos os detalhes.
A classe PhysicalBody permite estabelecer parâmetros tais como distância
interocular e altura dos olhos, para que o Java 3D ajuste a renderização em
configurações com head tracking. Um objeto da classe PhysicalBody construído sem
parâmetros é inicializado com uma configuração adequada para ambientes visualizados
em computadores desktop sem o recurso de head tracking.
Por fim, a classe PhysicalEnvironment faz a interface com dispositivos não
convencionais, tais como rastreadores de posição. O uso destes dispositivos será visto
na seção seguinte.

3.3.9 InputDevices
O Java 3D possui uma maneira uniforme de representar dispositivos de entrada
diversos, o que é conveniente para aplicações de Realidade Virtual. Através deste
mecanismo, é possível integrar rastreadores diversos, joysticks, head trackers e outros
dispositivos não convencionais.
Um dispositivo de entrada é representado por uma classe que implemente a
interface InputDevice. Tal classe por sua vez produz um ou mais objetos da classe
Sensor, que representam os dados gerados pelo dispositivo de entrada. Cada Sensor
pode conter uma matriz de transformação (correspondendo a até seis graus de liberdade)
e um número qualquer de botões ou controles (cada um dos quais podendo retornar um
valor inteiro). Por exemplo:
• um joystick pode ser implementado como um InputDevice com um
único Sensor;
• um dispositivo com múltiplos rastreadores (como um Polhemus Flock of
Birds por exemplo) pode ser implementado como um InputDevice
com vários Sensors, um para cada rastreador.
A Listagem 3.9 traz um exemplo de implementação de um dispositivo de
entrada. Os comentários nesta listagem indicam o que deve ser implementado em cada
método da interface InputDevice para uma correta integração com o Java 3D.
121
A parte complexa de implementar os dispositivos de entrada, obviamente, é a
interface com o hardware. No caso de dispositivos ligados à porta serial, pode-se
recorrer à API Java Comm. Geralmente, entretanto, será preciso escrever código nativo
integrado via Java Native Interface (JNI). O problema com esta abordagem,
infelizmente, é que esta parte do código torna-se dependente de plataforma.
Listagem 3.9 - Exemplo de Implementação de um InputDevice
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;

public class Java3DInput {


public static void main(String[] args) {
Java3DInput j3s = new Java3DInput();
j3s.exemplo();
}

private void exemplo() {


ConfiguredUniverse uni = new ConfiguredUniverse();
MeuDispositivo md = new MeuDispositivo();
uni.getViewer().getPhysicalEnvironment().addInputDevice(md);
}
}

class MeuDispositivo implements InputDevice {


private Sensor meuSensor;
private Transform3D trans;
private int[] botoes;

public MeuDispositivo() {
// Deve-se fazer o mínimo necessário aqui. O método
// initialize deve ser usado para a inicialização
// real do dispositivo.
}

public boolean initialize() {


// cria um sensor com dois botões
meuSensor = new Sensor(this, 10, 2);
trans = new Transform3D();
botoes = new int[2];
// este método deve retornar true se o dispositivo foi
// inicializado com sucesso ou false caso contrário.
return true;
}

public int getProcessingMode() {


// este método é importante porque diz ao Java 3D como
// funciona a aquisição de dados para o dispositivo.
// Ver a documentação para mais detalhes.
return NON_BLOCKING;
}

public int getSensorCount() {


return 1; // só temos 1 sensor
}

public Sensor getSensor(int sensorIndex) {


return meuSensor; // só temos 1 sensor
122
}

public void pollAndProcessInput() {


// neste método o dispositivo deve atualizar
// os sensores
long t = System.currentTimeMillis();
// normalmente, aqui iríamos acessar o dispositivo
// (possivelmente com código nativo) e atualizar as
// variáveis trans e botoes.
// Em seguida, faríamos a chamada abaixo:
meuSensor.setNextSensorRead(t, trans, botoes);
}

public void close() {


// este método é chamado pelo Java 3D quando o
// dispositivo não será mais usado. Aqui podemos fazer
// operações para liberar recursos usados pelo dispositivo.
}

public void processStreamInput() {


// de acordo com a documentação, este método deve
// ser deixado vazio.
}

public void setNominalPositionAndOrientation() {


// este método é chamado pelo Java 3D para calibração.
}

public void setProcessingMode(int mode) {


// este método pode ser chamado por uma aplicação usuária
// para mudar o modo de operação do dispositivo (ver o
// metodo getProcessingMode).
// Neste caso, simplesmente ignoramos estas tentativas.
}
}
Para que um dispositivo fique ativo na aplicação Java 3D, é preciso executar o
método addInputDevice de PhysicalEnvironment, como é feito na Listagem 3.9. Os
dispositivos também podem ser especificados no arquivo de configuração do
ConfiguredUniverse e neste caso a ativação é feita automaticamente.
O método setHeadIndex da classe PhysicalEnvironment permite associar
definir um Sensor como head tracker. Neste caso, as imagens renderizadas pela câmera
serão atualizadas automaticamente de acordo com o sensor.
Outra maneira de usar os dispositivos é através de Behaviors. Essencialmente, o
Behavior deve armazenar uma referência para o Sensor a ser utilizado e utilizar os
métodos getRead e lastButtons para obter os dados atualizados do dispositivo quando
for necessário.
123
3.4 Transição do VRML

3.4.1 VRML e X3D


O X3D é a proposta de um novo padrão para gráficos 3D na Internet que pode
ser visto como o substituto do VRML. Alguns de seus diferenciais são:
• utilização de XML para especificar a sintaxe e estrutura dos arquivos;
• definição de “perfis” que funcionam como sub-especificações do padrão
completo. Cada perfil tem complexidade maior do que o anterior, e
agrega mais funcionalidades. Isto permite que dispositivos de menor
capacidade sejam compatíveis com perfis mais simples, enquanto
sistemas sofisticados implementem o perfil completo da especificação;
• especificação unificada para interface com linguagens de programação,
ao contrário do VRML 97, que possui uma interface de scripting e outras
para integração com aplicações (como por exemplo o EAI).
Estruturalmente, um arquivo X3D não é radicalmente diferente de um arquivo
VRML 97, como se pode observar na Listagem 3.10. Exceto pelas mudanças de sintaxe
devido à adoção do XML, pode-se dizer que o modelo de grafo de cena do VRML foi
apenas expandido pelo X3D, mas os mesmos tipos básicos de nós permaneceram.
Listagem 3.10 - Exemplo de arquivo X3D
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN"
"http://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D profile='Immersive'
xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance'
xsd:noNamespaceSchemaLocation=
'http://www.web3d.org/specifications/x3d-3.0.xsd'>
<head>
<meta name='filename' content='GeometryExample.x3d'/>
<meta name='description' content='User-modifiable example to
examine the role of the geometry tag. See what nodes can be
replaced: geometry (no) and Cylinder (yes).'/>
<meta name='author' content='Don Brutzman'/>
<meta name='created' content='8 July 2000'/>
<meta name='revised' content='27 December 2003'/>
<meta name='url' content=
'http://www.web3d.org/x3d/content/examples/course/GeometryExample.x3d'
/>
<meta name='generator' content=
'X3D-Edit, http://www.web3d.org/x3d/content/README.X3D-Edit.html'/>
</head>
<Scene>
<Shape>
<Appearance>
<Material diffuseColor='0 .5 1'/>
</Appearance>
<!-- Edit this code, attempt to modify geometry and Cylinder to
124
see how field-wrapper tags work. Only Cylinder can be replaced,
and then only by another geometry node. -->
<Cylinder/>
</Shape>
</Scene>
</X3D>
No momento da elaboração deste texto, as especificações do X3D ainda
estavam sendo analisadas, não havendo ainda um padrão oficial definitivo para esta
tecnologia.

3.4.2 Xj3D
O projeto Xj3D tem como objetivo fornecer ferramentas para visualização de
arquivos no padrão X3D através da linguagem Java. Atualmente, o projeto possui tanto
um visualizador autônomo como um Loader para o Java 3D. Um roteiro para usar o
Loader pode ser encontrado no endereço http://www.xj3d.org/loader.html embora o
processo seja essencialmente o mesmo discutido para outros Loaders anteriormente.
Com a existência de um conjunto de ferramentas em Java para visualização de
arquivos X3D, pode-se imaginar a possibilidade de elaborar sistemas muito mais
integrados e robustos do que era possível utilizando-se VRML e EAI, por exemplo.
Entretanto, a aplicabilidade deste tipo de sistema ainda depende da formalização do
padrão X3D e da sua aceitação pela comunidade.

3.5 Comunicação em Rede

3.5.1 RMI
O recurso de Remote Method Invocation (RMI) da linguagem Java pode ser
utilizado para implementar aplicações distribuídas de forma transparente. A maior
vantagem deste método (assim como CORBA) é que o código-fonte escrito não tem que
tratar explicitamente da comunicação em rede.
A idéia básica do uso do RMI para ambientes distribuídos é criar objetos que
podem ser executados remotamente e usar as chamadas de métodos destes objetos para
fazer a comunicação.
Objetos remotos precisam implementar uma subinterface de java.rmi.Remote,
que deve definir os métodos que podem ser executados remotamente. Eles devem
preferencialmente ser subclasses de java.rmi.server.UnicastRemoteObject, caso
contrário a implementação se torna bem mais complexa.
125
Objetos que podem ser passados como parâmetros para um objeto remoto
precisam implementar a interface java.io.Serializable, que permite que o objeto seja
copiado através da rede. Obviamente, o fato de que o objeto será copiado integralmente
pela rede já indica que deve-se evitar passar objetos grandes como parâmetro.
A Listagem 3.11 demonstra o uso de RMI para criar um simples “chat” de texto
entre dois usuários. As primeiras linhas do método main instalam um gerenciador de
segurança similar ao usado para applets. Este gerenciador evita que código remoto não-
confiável execute na máquina local. Isso é necessário porque o RMI pode fazer
download automático de classes que não existem localmente. Por outro lado, se nenhum
gerenciador for instalado, este comportamento de download automático é desabilitado.
Cada usuário, em um computador diferente, pode usar o exemplo executando
primeiramente a aplicação rmiregistry em uma janela de console. Depois, em outra
janela, pode executar a aplicação com:
java RMIChat <nome> <endereço>

Sendo que <nome> é o nome usado para identificar o usuário e <endereço> é o


endereço IP do computador onde está o usuário com quem ele irá se conectar.
Este exemplo é extremamente simplificado mas mostra uma forma como as
aplicações podem trocar mensagens de forma transparente (neste caso, usando o
método enviarMensagem da interface Chat).
Listagem 3.11 - Exemplo de uso do RMI
import java.rmi.server.*;
import java.rmi.*;

import java.io.*;

public class RMIChat


extends UnicastRemoteObject
implements Chat {

public static void main(String[] args) {


if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}

try {
Chat chatLocal = new RMIChat();
Naming.rebind(args[0], chatLocal);
System.out.print("nome do usuário remoto: ");

BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
String nome = in.readLine();

String nomeRemoto = "//" + args[1] + "/" + nome;


Chat chatRemoto = (Chat) Naming.lookup(nomeRemoto);

String line;
126
do {
line = in.readLine();
chatRemoto.enviarMensagem(line);
} while (line != "FIM");
} catch (Exception e) {
e.printStackTrace();
}
}

public RMIChat() throws RemoteException {


super();
}

public void enviarMensagem(String texto)


throws RemoteException {
System.out.println(texto);
}
}

interface Chat extends Remote {


void enviarMensagem(String texto) throws RemoteException;
}

3.5.2 JSDT
A API Java Shared Data Toolkit (JSDT) pode ser vista como um meio-termo
entre as soluções de alto nível que tornam a comunicação de rede transparente (RMI,
CORBA) e as soluções que expõem todos os detalhes (Sockets). Uma característica
interessante desta API é que ela pode utilizar o protocolo Multicast, que tem o potencial
para um bom desempenho no caso de um grande número de participantes.
O JSDT trabalha com a metáfora de Sessão colaborativa. Um servidor centraliza
informações sobre as sessões existentes, e usuários podem então se conectar a uma ou
mais delas. Cada sessão armazena três tipos de objetos compartilhados: canais, vetores
de bytes e tokens. Canais são usados para enviar mensagens de dados para os outros
usuários. Vetores podem ser usados para representar vários tipos de dados
compartilhados e tokens são usados primariamente como mecanismos de sincronização.
A Listagem 3.12 mostra como criar uma Sessão e cada um dos objetos compartilhados.
Listagem 3.12 - Exemplo de uso do JSDT
import com.sun.media.jsdt.*;

public class JSDTSimples {


public static void main(String[] args) {
try {
if (RegistryFactory.registryExists("socket") == false) {
RegistryFactory.startRegistry("socket");
}

ClienteJSDT cli = new ClienteJSDT("teste");


127
URLString url =
URLString.createSessionURL("127.0.0.1",
4444,
"socket",
"JSDTSimples");
// cria a sessao
Session sessao =
SessionFactory.createSession(cli, url, false);
// cria objetos compartilhados
sessao.createChannel(cli, "canal", true, true, false);
sessao.createByteArray(cli, "vetor", false);
sessao.createToken(cli, "token", false);

System.out.println("Objetos criados com sucesso");


} catch (JSDTException e) {
e.printStackTrace();
}
}
}

class ClienteJSDT implements Client {


private String nome;

public ClienteJSDT(String nome) {


this.nome = nome;
}

public String getName() {


return nome;
}

public Object authenticate(AuthenticationInfo info) {


return null;
}
}
Uma aplicação pode construir diferentes mecanismos de sincronização e
protocolos, usando os objetos compartilhados. Para se acessar um objeto existente, basta
usar o método de criação. Se o objeto já existe, o método retorna uma referência para
ele. Por exemplo, se um cliente A criou um canal chamado “chat”, então uma chamada
a createChannel(cliente, “chat”, true, true, false) feita pelo cliente B irá retornar
uma referência para aquele canal. A partir daí, os dois clientes podem se comunicar
usando os métodos da classe Channel.

3.5.3 Sockets
Trabalhar diretamente com Sockets em Java é relativamente simples. No
entanto, criar uma implementação robusta e eficiente é tão complexo como seria em
qualquer outra linguagem.
Listagem 3.13 - Exemplo de uso de Sockets
import java.net.*;
import java.io.*;
128
public class SocketSimples {
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 4444);
InputStreamReader isr =
new InputStreamReader(s.getInputStream());
BufferedReader br =
new BufferedReader(isr);

PrintStream ps =
new PrintStream(s.getOutputStream());

ps.println("Teste: cliente");
String l = br.readLine();
System.out.println(l);

ps.close();
br.close();
s.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
A Listagem 3.13 mostra como abrir uma conexão TCP/IP no Java. Deve-se notar
que a conexão irá falhar se não houver um servidor no endereço e porta de destino. O
código da Listagem 3.14 contém um servidor que interage com o cliente da listagem
anterior.
Listagem 3.14 - Servidor usando Sockets
import java.net.*;
import java.io.*;

public class SocketServidor {


public static void main(String[] args) {
try {
ServerSocket serv = new ServerSocket(4444);

while(true) {
Socket s = serv.accept();
Thread t = new Thread(new Conexao(s));
t.start();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}

class Conexao implements Runnable {


private Socket s;

public Conexao(Socket s) {
this.s = s;
}
129
public void run() {
try {
InputStreamReader isr =
new InputStreamReader(s.getInputStream());
BufferedReader br =
new BufferedReader(isr);

PrintStream ps =
new PrintStream(s.getOutputStream());

String l = br.readLine();
System.out.println(l);
ps.println("Teste: servidor");

ps.close();
br.close();
s.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Para o servidor, utiliza-se a classe ServerSocket em vez de Socket, e a maneira
mais simples de tratar os clientes que se conectam é criar um novo thread para cada
cliente. Assim, o servidor não fica ocupado enquanto um cliente está se conectando.
A utilização do protocolo UDP é bastante similar ao caso da conexão TCP/IP
mostrada na Listagem 3.13, mas utiliza-se a classe DatagramSocket em vez de Socket.
Em vez de usar streams, os dados são transferidos através dos métodos send e receive,
que recebem um objeto da classe DatagramPacket. Esta classe é essencialmente um
invólucro de dados; no envio, o objeto deve ser configurado com o endereço e porta do
computador destinatário.

3.6 Conclusão
Foram apresentados exemplos de utilização de diferentes APIs da linguagem
Java para uso no desenvolvimento de ambientes virtuais. Este material pode ser útil
como referência para o início de um estudo mais aprofundado destas tecnologias.

3.7 Bibliografia Recomendada


BARRILLEAUX, J. 3D User Interfaces with Java 3D. Greenwich: Manning,
2001. 499p.
DEITEL, H. M. et al. Java How To Program. 5.ed. s.l.: Prentice-Hall, 2002.
1536p.
SELMAN, D. Java 3D Programming. Greenwich: Manning, 2002. 400p.
130
SINGHAL, S., ZYDA, M. Networked Virtual Environments: Design and
Implementation. Nova York: ACM Press, 1999. 331p.

3.8 Sites para Referência


http://www.j3d.org - J3D.ORG. Site de referência sobre Java 3D e outras
tecnologias 3D em Java. Recomendado para obter links para Loaders e InputDevices.
http://java.sun.com/products/java-media/3D/ - Java 3D API. Site oficial da
API Java 3D. Além dos downloads da API e documentação, tem tutoriais e links para
projetos usando esta tecnologia.
https://java3d.dev.java.net/ - Java 3D Parent Project. Site criado para o Java
3D depois que ele se tornou open source. Permite o download do código-fonte completo
do Java 3D.
http://java.sun.com/j2se/1.4.2/docs/guide/security/index.html - Java Security.
Site com informações sobre configurações de segurança para aplicações Java.
https://jsdt.dev.java.net/ - JSDT Home. Site oficial da API JSDT (Java Shared
Data Toolkit).
http://java.sun.com/products/javacomm/index.jsp – Java Communications
API. Site oficial da API Java Comm (para acesso às portas serial e paralela).
http://www.web3d.org/ - Web3D Consortium. Site que contém a especificação
do novo padrão X3D, além de muitos links para outros recursos relacionados.
http://www.web3d.org/x3d/specifications/vrml/ISO_IEC_14772-All/ -
VRML97 – ISO IEC 14772. Especificação da linguagem VRML 97.
131

4 Desenvolvimento de Aplicações de Realidade Virtual


Mauro Charão (FACIN-PUCRS), Régis Kopper (FACIN-PUCRS)
Márcio Pinho (FACIN-PUCRS)
pinho@inf.pucrs.br

4.1 Introdução
Este documento aborda alguns aspectos envolvidos no desenvolvimento de
aplicações de realidade virtual imersiva.
O texto baseia-se na utilização da biblioteca gráfica OpenGL e na experiência do
Grupo de Realidade Virtual da PUCRS no desenvolvimento de aplicações imersivas de
Realidade Virtual.
São apresentadas técnicas para os seguintes problemas:
• Modelagem de cenários;
• Transformações geométricas;
• Navegação em ambientes virtuais;
• Geração de imagens estereoscópicas;
• Interação em ambientes virtuais;
• Transformações geométricas hierárquicas;
• Ambientes Virtuais Colaborativos;
• Exibição de Cenas em Múltiplas Telas;
• Geração de tato.
Diversos dos exemplos aqui apresentados são fruto da experiência acumulada no
desenvolvimento da biblioteca gráfica SmallVR [PIN2002] (que pode ser encontrada
em http://www.smallvr.org) e nas aulas da disciplina de Tópicos Especiais em
Computação Gráfica (http://www.inf.pucrs.br/~pinho/TCG) do curso de Bacharelado
em Ciência da Computação da PUCRS, nos últimos dois anos.

4.2 Introdução à Realidade Virtual


Um dos recentes adventos do desenvolvimento tecnológico, que vem
firmando-se, como uma nova área da Computação é o que chamamos realidade virtual.
132
A realidade virtual vem trazer ao uso do computador um novo paradigma de
interface com o usuário. Neste paradigma, o usuário não estará mais em frente ao
monitor, mas sim, sentir-se-á “dentro da aplicação” ou do ambiente onde se está
desenvolvendo esta aplicação.
Com dispositivos especiais, a realidade virtual busca captar os movimentos do
corpo do usuário (em geral braços, pernas, cabeça e olhos) e, a partir destes dados,
realizar a interação com a aplicação, sem utilizar os elementos tradicionais das
interfaces WIMP (“Window, Icon, Menu, Pointer”) [SCH98].
A realidade virtual pode ser vista como um salto qualitativo em relação às
interfaces gráficas, atualmente em utilização. Com a realidade virtual o usuário percebe
a aplicação como um ambiente virtual tridimensional. Esta percepção (ou ilusão) torna-
se possível através de dados captados e gerados em dispositivos especiais, como luvas
eletrônicas e óculos de imagens estereoscópicas. A interface dentro deste ambiente
virtual procura imitar a realidade de um determinado contexto, buscando produzir a
sensação de presença neste ambiente, através de uma ilusão gerada por computador.
Esta sensação de presença [DUR2003] ou imersão , constitui-se na principal
característica da realidade virtual. A qualidade desta imersão, ou grau de ilusão, ou quão
real esta ilusão parece ser, depende da interatividade e do grau de realismo que o
sistema é capaz de proporcionar.
No aspecto interativo, um sistema de realidade virtual deve responder de
maneira instantânea, gerando no usuário o sentimento de que a interface é capaz de
interpretar e responder a seus comandos rapidamente. O grau de realismo, por sua vez,
é dado pela qualidade destas respostas. Quanto mais parecida com uma cena real for
uma imagem apresentada ou um som emitido ao usuário, mais envolvido pelo sistema
este usuário ficará.
Em outras palavras, a realidade virtual é uma área que busca criar uma nova
forma de interação com o computador. Trata-se de uma nova filosofia de interface com
o usuário.
Nesta nova filosofia, conhecida como “Post-WIMP” ou “Non-WIMP”
[VAN97], a interface atua com objetivos semelhantes àqueles das interfaces tradicionais
já que segue analisando as ações do usuário e gerando respostas em face destas ações. A
diferença nas interfaces Non-WIMP está na forma e nos meios usados para captar as
ações e gerar as respostas.
133
Considerando a análise das ações do usuário, uma interface baseada em
realidade virtual é semelhante à uma interface tradicional no aspecto de que ambas lêem
dados que o usuário produz. Entretanto, numa interface de realidade virtual os
periféricos usados para captar as informações procuram expandir o processo de
interação libertando-o do plano bidimensional. Exemplificando, suponhamos uma
aplicação onde o usuário deva mover um objeto de um local para outro. Em uma
interface tradicional (com mouse) o usuário deverá pegar o objeto, clicando sobre ele, e,
movendo o mouse sobre a mesa, poderá colocá-lo em sua nova posição, no plano XY.
Para uma movimentação que altere a posição do objeto relativamente ao eixo Z, uma
nova forma de entrada de dados deve ser acrescentada. Por outro lado, em uma interface
de realidade virtual, na qual o usuário vista uma luva eletrônica que possua sensores de
posição e sensores de flexão nos dedos, ele poderá pegar o objeto, curvando seus dedos
(ou apontando o objeto) e, movendo a mão no espaço, reposicioná-lo onde desejar
(Figura 4-1).

Figura 4-1 - Usuário movendo objeto


No que diz respeito à geração de respostas, as interfaces de realidade virtual,
assim com as interfaces tradicionais, procuram gerar sensações no usuário. A diferença
reside no fato de que as interfaces de realidade virtual buscam, através destas sensações,
fazer o usuário acreditar que está interagindo em um ambiente real. Para tanto, os
usuários podem ser vestidos com capacetes com visores (Figura 4-2), também
conhecidos como HMDs (“Head Mounted Displays”).
Estes visores, em geral um para cada olho, criam para o usuário a sensação de
que ele está dentro de um ambiente virtual. Isto é conseguido pela combinação de duas
técnicas: (a) exibição de imagens tridimensionais estereoscópicas e (b) monitoramento
da posição da cabeça do usuário no espaço. A primeira permite, que sejam produzidas
imagens com alto grau de realismo na sensação de profundidade que o usuário tem de
um cenário. A segunda permite atualizar continuamente a imagem apresentada, pois se
134
pode saber para onde o usuário está olhando a cada momento. Por exemplo, se estiver
em uma sala virtual e olhar para baixo verá o piso, se olhar para cima, verá o teto.
Para melhorar ainda mais ilusão do usuário, podem ser usadas técnicas de som
tridimensional [BAL98] e geração de tato [BUR96; MAC02; LEC2002; BAS2001].

Figura 4-2 - Usuário com um capacete de realidade virtual

4.3 Cenários para Ambientes de Realidade Virtual


Para modelagem de cenários, há duas alternativas básicas, quando se usa uma
biblioteca gráficas como OpenGL. Na primeira, modela-se “à mão” os objetos gráficos
através de primitivas OpenGL, e na segunda utilizam-se modeladores gráficos capazes
de exportar arquivos de objetos tridimensionais que posteriormente são lidos e exibidos
com comandos OpenGL.
Na figura Figura 4-3 pode-se observar um retângulo modelado em OpenGL.

glBegin(GL_POLYGON); // desenha um polígono


glVertex3f(-10.0, -10.0, -10.0); // define os vértices da face
glVertex3f(10.0, -10.0, -10.0);
glVertex3f(10.0, -10.0, 10.0);
glVertex3f(-10.0, -10.0, 10.0);
glEnd; // fim do desenho
Figura 4-3 – Exemplo de Objeto modelado em OpenGL
Para a leitura de modelos tridimensionais uma alternativa é a biblioteca
SmallVR, disponível em http://www.smallvr.org .
135
4.4 Transformações Geométricas
A biblioteca gráfica OpenGL é capaz de executar transformações de translação,
rotação e escala.
A idéia central das transformações em OpenGL é que elas são cumulativas, ou
seja, podem ser aplicadas umas sobre as outras.
Uma transformação geométrica de OpenGL é armazenada internamente em uma
matriz. A cada transformação, esta matriz é alterada e usada para desenhar os objeto a
partir daquele momento, até que seja novamente alterada.

4.4.1 Translação

Para efetuar uma translação há o comando glTranslatef(tx, ty, tz) que move
todas as coordenadas dos objetos ao longo dos eixos coordenados. Na Figura 4-4 pode-
se observar do uso do comando de translação.

DesenhaObjeto();// Desenha o objeto na posição


// correspondente às suas coordenadas originais

glTranslatef(10,10,10);
DesenhaObjeto(); // Desenha o objeto descolado de 10
// unidades em cada eixo
glTranslatef(10,10,10);
DesenhaObjeto(); // Desenha o objeto descolado de 20
// unidades em cada eixo
// LEMBRE-SE, AS TRANSFORMAÇÕES SÃO
// CUMULATIVAS
Figura 4-4 - Exemplos de Translação

4.4.2 Rotação

Para efetuar uma rotação há o comando glRotatef(Angulo, x, y, z) que gira o


objeto ao redor do vetor (x,y,z). O giro é de Angulo graus, no sentido anti-horário. Na
Figura 4-5 pode-se observar do uso do comando de rotação.

DesenhaObjeto();// Desenha o objeto na posição


// correspondente às suas coordenadas originais

glRotatef(20,1,0,0);
DesenhaObjeto(); // Desenha outro objeto rotacionado 20
// graus ao redor do eixo X
glRotatef(30,1,0,0);
DesenhaObjeto(); // Desenha mais um objeto, rotacionado
// 30 graus ao redor do eixo X
// LEMBRE-SE, AS TRANSFORMAÇÕES SÃO
// CUMULATIVAS. Neste caso o giro total será de 50
136
// graus
Figura 4-5 - Exemplos de Rotação

4.4.3 Escala

Para efetuar uma escala há o comando glScalef(ex, ey, ez) que altera a escala
do objeto ao logo dos eixos coordenados (Figura 4-6).

DesenhaObjeto();// Desenha o objeto na posição


// correspondente às suas coordenadas originais

glScalef(0,0.5,0);
DesenhaObjeto(); // Desenha outro objeto com a altura
// diminuída pela metade
glScalef(0,2.0,0);
DesenhaObjeto(); // Desenha mais um objeto no tamanho original
// LEMBRE-SE, AS TRANSFORMAÇÕES SÃO
// CUMULATIVAS.
Figura 4-6 - Exemplos de Escala

4.4.4 Reinicializando as Transformações


Para permitir que a transformação atual seja reinicializada há o comando
glLoadIdentity(). Este comando anula todas as transformações geométricas
setadas anteriormente (Figura 4-7).

DesenhaObjeto();// Desenha o objeto na posição


// correspondente às suas coordenadas originais

glScalef(0,0.5,0);
DesenhaObjeto(); // Desenha outro objeto com a altura
// diminuída pela metade
glLoadIdentity(); // reinicializa as transformações
glScalef(0,2.0,0);
DesenhaObjeto(); // Desenha o outro objeto com o dobro do tamanho
original
// LEMBRE-SE, AS TRANSFORMAÇÕES SÃO
// CUMULATIVAS.
Figura 4-7 - Exemplos de Re-inicialização de Transformações

4.4.5 Limitando o Escopo das Transformações


Para permitir que uma transformação valha somente em um certo trecho de
programa e assim não altere o que está sendo desenhado depois, há os comados
glPushMatrix() e glPopMatrix().
137
A idéia é que o glPushMatrix() armazene as transformações atuais em
um pilha interna do OpenGL e que estas transformações possam ser retiradas depois por
um glPopMatrix().

DesenhaObjeto();// Desenha o objeto na posição


// correspondente às suas coordenadas originais

glPushMatrix(); // salva as transformações atuais na pilha


// Diminui a altura do objeto à metade do origianl
glScalef(0,0.5,0);
DesenhaObjeto();
glPopMatrix(); // restaura as transformações anteriores

glPushMatrix(); // salva as transformações atuais na pilha


// Desenha o outro objeto com o dobro do tamanho original
glScalef(0,2.0,0);
DesenhaObjeto();
glPopMatrix(); // restaura as transformações anteriores
Figura 4-8 - Exemplos de Limitação das Transformações Geométricas

4.5 Navegação em ambientes de Realidade Virtual


A navegação em OpenGL ou, em outras palavras, o posicionamento do
observador, é feito normalmente com a função gluLookAt. Nesta função define-se a
posição do observador e o seu ponto de interesse, além do vetor que aponta para o "lado
de cima" do cenário 3D.

4.5.1 Andando "para frente" com a gluLookAt


Para permitir que um observador ande na direção em que ele está olhando é
necessário somar à posição atual do observador um vetor que tenha a mesma direção
que vetor que vai do observador até o alvo. A mesma soma deve ser feita ao ponto alvo.
É interessante que este vetor seja unitário pois assim se pode controlar a
velocidade do deslocamento. A fórmula da Figura 4-9 demonstra como pode ser feito o
deslocamento descrito acima.

PosicaoNova = PosicaoAtual + VetorAlvoUnitario * TamanhoDoPasso


AlvoNovo = AlvoAtual + VetorAlvoUnitario * TamanhoDoPasso
Figura 4-9 – Movimento do observador “pra frente”
138
4.5.2 Olhando "para os lados" com a gluLookAt
Para permitir que um observador "olhe para os lados" é preciso recalcular o
ponto Alvo, aplicando sobre ele uma rotação ao redor do eixo Y.
Para rotacionar um ponto ao redor deste eixo usa-se a fórmula da Figura 4-10.

AlvoNovo.X = AlvoAtual.X*cos(alfa) + AlvoAtual.Z*sen(alfa)


AlvoNovo.Y = AlvoAtual.Y
AlvoNovo.Z = -AlvoAtual.X*sen(alfa) + AlvoAtual.Z*cos(alfa)
Figura 4-10 – Rotação do observador na Origem

Note, entretanto que esta fórmula rotaciona o ponto ao redor do ponto (0,0,0).
Como fazer para rotacioná-lo corretamente ? Uma alternativa é executar os passos da
Figura 4-11.

Posição inicial Move-se o conjunto “OBS-ALVO” para a origem


139
Aplica-se a rotação no alvo Move-se o conjunto “OBS-ALVO” para a posição
original
Figura 4-11 – Rotação do Genérica do Observador

4.6 Geração de Visão Estereoscópica

4.6.1 Posicionamento do Observador


A idéia básica de criação de imagens estereoscópicas em OpenGL é geração de
imagem diferente para cada olho a partir da mudança da posição do observador.
Uma forma simples de efetuar esta mudança de posição é apresentada na Figura
4-12 onde o observador é movido para a esquerda ou para a direita, conforme o olho
para o qual se deseja gerar a cena.

// *************************************************************
// void PosicUser()
// esta função define a posicão de cada um dos olhos do
// observador
//
// Variáveis usadas:
// DistOlhos: distância entre os olhos do usuário
//
// *************************************************************
void PosicUser(int Olho)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80,ratio,0.01,200);
switch (Olho)
{
case ESQUERDO: // seta posição para o olho esquerdo
gluLookAt(-DistOlhos/2, 0, 5, 0, 0, 0, 0.0f,1.0f,0.0f);
break;
case DIREITO: // seta posição para o olho direito
gluLookAt(DistOlhos/2, 0, 5, 0, 0, 0, 0.0f,1.0f,0.0f);
break;
}
glMatrixMode(GL_MODELVIEW);
}

Figura 4-12 – Posicionamento do Observador para geração de Imagens Estereoscópicas


Uma abordagem mais detalhada sobre o posicionamento do observador para a
geração de imagens estereoscópicas pode ser encontrado em
http://astronomy.swin.edu.au/~pbourke/opengl/stereogl.
Além de gerar duas imagens diferentes, é preciso exibi-las uma para cada olho.
A forma de fazer esta exibição depende do tipo de dispositivo que está sendo usado. Nas
140
seções a seguir são apresentadas duas formas de realizar esta tarefa, cada uma vinculada
a um tipo de dispositivo.

4.6.2 Imagens Entrelaçadas: técnicas e dispositivos


No caso do uso de Óculos do tipo I-Glasses, a separação entre a imagem do olho
esquerdo e do olho direito é feita pelo hardware do óculos que põe no visor do olho
direito as imagens das linhas pares da tela, e no visor do olho esquerdo a imagem das
linhas ímpares.
Maiores informações sobre este tipo de óculos podem ser obtidas no
site http://www.i-glassesstore.com. Atente para o fato de que nem todos os modelos
disponíveis nesta página têm capacidade de exibir imagens estereoscópicas.
Para fazer a separação das imagens na tela, usa-se o stencil buffer, com o
seguinte algoritmo:

• Bloqueia-se, através do stencil buffer, a exibição das imagens nas linhas


impares;

• Exibe-se a imagem referente ao olho direito;

• Libera-se, através do stencil buffer, a exibição das imagens nas linhas


impares;

• Bloqueia-se, através do stencil buffer, a exibição das imagens nas linhas


pares;

• Exibe-se a imagem referente ao olho esquerdo

O bloqueio (ou desbloqueio) das linhas pares e ímpares neste caso é feito
através da montagem de uma “máscara” no stencil, conforme a Figura 4-13. Esta
máscara é, na verdade, um conjunto de linhas horizontais desenhadas no stencil,
somente nas linhas pares da tela.
// ****************************************************************
// void DesenhaFundo()
// Inicializa o stencil com 1 nas linhas pares
//
// ****************************************************************
void DesenhaFundo(int Largura, int Altura )
{

// Habilita o uso do Stencil


glEnable(GL_STENCIL_TEST);
141
// Define que "0" será usado para limpar o Stencil
glClearStencil(0);
// limpa o Stencil
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);

// desenha a máscara nas linhas pares


glMatrixMode(GL_PROJECTION); //
glLoadIdentity ();
gluOrtho2D(0, Largura, 0, Altura);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
// inicializa apenas as linhas pares no stencil
for (int y= 0; y < Altura; y += 2)
{
DrawLine(0,y, Largura, y);
}
glEnd();
// volta à matriz de objetos
//glMatrixMode(GL_MODELVIEW);
}
Figura 4-13 - Marcação das linhas pares no stencil buffer
No momento da exibição dos objetos do cenário, o programador deve habilitar e
desabilitar o desenho sobre as linhas marcadas no stencil. A Figura 4-14 demonstra este
procedimento.

// *****************************************************************
// void HabilitaOlhoEsquerdo()
//
//
// *****************************************************************
void HabilitaOlhoEsquerdo()
{
glStencilFunc(GL_NOTEQUAL, 1, 1);
glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);
}
// *****************************************************************
// void HabilitaOlhoDireito()
//
//
// *****************************************************************
void HabilitaOlhoDireito()
{
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP,GL_KEEP, GL_KEEP);
}
// *****************************************************************
//
//
// *****************************************************************
void display( void )
{
// Limpa a tela
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DefineLuz();
142
PosicUser(ESQUERDO); // posiciona o observador no olho esquerdo
HabilitaOlhoEsquerdo();
DesenhaCena();
PosicUser(DIREITO); // posiciona o observador no olho direito
HabilitaOlhoDireito();
DesenhaCena();
glutSwapBuffers();
}
Figura 4-14 – Exibição de Cenas Estereoscópicas com Stencil Buffer

4.6.3 Imagens Alternadas: técnicas e dispositivos


O uso de imagens alternadas depende do uso de um óculos do tipo shutter-
glasses e de um placa de vídeo que suporte a geração de estéreo. O processo de
posicionamento do observador continua sendo o mesmo descrito na seção 4.6.1.
Primeiramente o programador deve inicializar a biblioteca GLUT com a opção
de estereoscopia. Caso a placa de vídeo não suporte esta característica, ocorrerá um erro
neste momento. O comando para esta inicialização é:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STEREO);
No momento de exibir o cenário, o programador deverá definir para que olho
está gerando a imagem, através da escolha do buffer de desenho. Na Figura 4-15
apresenta-se um trecho de código que faz esta tarefa.

void display( void )


{
// Limpa a tela
DefineLuz();
PosicUser(ESQUERDO); // posiciona o observador no olho esquerdo
glDrawBuffer(GL_BACK_LEFT); // ativa BUFFER ESQUERDO
glClearColor(1.0, 0.0, 0.0, 1.0); /* red */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DesenhaCena();

PosicUser(DIREITO); // posiciona o observador no olho direito


glDrawBuffer(GL_BACK_RIGHT); // ativa BUFFER DIREITO
glClearColor(0.0, 0.0, 1.0, 1.0); /* blue */
glClear(GL_COLOR_BUFFER_BIT);
DesenhaCena();
glutSwapBuffers();
}
Figura 4-15 – Exibição de Cenas Estereoscópicas para shutter-glasses
143
4.7 Interação em Ambientes de Realidade Virtual

4.7.1 Técnicas de Interação


A manipulação de um objeto em um ambiente virtual imersivo consiste na
mudança de algum parâmetro ou estado de um objeto previamente selecionado. Esta
mudança de estado inclui orientação, posição, tamanho ou outro parâmetro qualquer,
seja geométrico (forma ou posição), visual (cor ou textura) ou comportamental (iniciar
movimento ou parar, por exemplo).
Na Tabela 4.1 pode-se observar uma comparação entre tarefas do mundo real e
as implicações de realizá-las num ambiente virtual. Pela análise desta tabela, nota-se
claramente que a utilização de sistemas de realidade virtual de forma ampla, ainda
depende de um grande desenvolvimento na área das técnicas de manipulação.
As técnicas de manipulação mais comuns em ambientes virtuais são aquelas
classificadas como de interação direta. Estas técnicas permitem ao usuário tocar
virtualmente o objeto e utilizar os movimentos de seu corpo (mãos, braços, cabeça, etc)
para provocar mudanças na posição e/ou orientação deste objeto. Neste trabalho, estas
técnicas são classificadas como técnicas individuais, pois se referem à manipulação que
um único usuário realiza sobre um objeto.
Embasando uma técnica de manipulação há sempre a chamada metáfora de
interação. Esta metáfora define como os movimentos do usuário são mapeados para
movimentos do objeto. O toque virtual, mencionado acima, pode ser feito tanto com a
mão do usuário, que atinge um objeto próximo de seu corpo, quanto através de um raio
de apontamento ou de uma técnica que estenda o braço de forma a alcançar um objeto
distante. Para efetivar estas técnicas se faz necessário que o sistema de realidade virtual
possua funções de suporte ao rastreamento das mãos e da cabeça do usuário, o
reconhecimento de gestos e detecção do apontamento de um objeto. O sucesso das
técnicas de interação direta depende da capacidade do sistema de realizar um
mapeamento natural e intuitivo entre a ação do usuário no mundo real e a ação
resultante no mundo virtual.
Tabela 4.1 – Características de Tarefas do Mundo Real em Ambientes Virtuais

4.7.1.1.1.1.1 Tarefa 4.7.1.1.1.1.2 Mundo Real 4.7.1.1.1.1.3 Ambientes


virtuais
Manipulação de objetos A manipulação de objetos é A seleção de ferramentas é
144
usualmente feita com ferramentas ou complicada
com a mão
Comunicação e comandos A possibilidade de comunicação com A tecnologia de reconhecimento
outros usuários através de voz é de
através de voz de voz ainda é precária
fundamental importância no processo
interativo entre usuários
Medição de objetos A possibilidade de medir objetos do Ainda é difícil e pouco precisa a
ambiente é bastante natural para possibilidade de medir objetos em
aplicações reais ambientes virtuais
Anotação de informações A anotação de informações textuais e A entrada de textos e números é
sobre os objetos do ambiente
gráficas sobre papel ou quadros de pouco desenvolvida em ambientes
aviso é extremamente simples e útil virtuais
no processo de interação em
ambientes reais

Nas seções a seguir são apresentadas algumas técnicas classificadas como de


interação direta, divididas em três categorias, de acordo com a metáfora que define seu
funcionamento. Estas metáforas são: mapeamento direto, extensão de braço e
apontamento por raio.

4.7.1.2 Metáfora de Mapeamento Direto


A forma mais simples de interação direta é o mapeamento direto entre os
movimentos da mão e os movimentos do objeto no ambiente virtual [MIN95].
Nesta técnica o usuário pega o objeto virtual com a mão, move-o no ambiente
virtual com o movimento do braço, e larga-o quando julgar que a tarefa está concluída,
exatamente como faria com um objeto real (Figura 4-16).
A implementação desta técnica pressupõe o rastreamento da posição da mão (e
dos dedos) do usuário a fim de capturar seus movimentos (rotação e translação) e
transferi-los ao objeto selecionado.
A grande potencialidade desta técnica é a possibilidade de aproveitar-se o
conhecimento intuitivo do usuário sobre este tipo de manipulação. O principal problema
é que ela limita a manipulação a objetos que se encontram posicionados ao alcance da
mão do usuário.
145

Figura 4-16 – Manipulação com as mãos

4.7.1.3 Metáforas de extensão de braço


Nesta categoria o braço do usuário é estendido de forma a atingir qualquer
objeto dentro do ambiente virtual. A grande vantagem desta metáfora é a possibilidade
de continuar-se a usar os movimentos das mãos para realizar a tarefa, o que representa
uma forma bastante natural e intuitiva de interação e, mesmo assim, poder-se atingir
objetos que estão além de seu campo de ação.
As implementações desta metáfora diferem na forma como o braço é estendido e
como o movimento da mão real é mapeado para o movimento da mão virtual.
Por exemplo, a técnica Go-Go [POU96] cria uma função não-linear que mapeia
o movimento da mão real para mão virtual. Nesta metodologia, o espaço ao redor do
usuário é dividido em duas esferas concêntricas. Enquanto a mão estiver dentro da
esfera mais interna, isto é, mais próxima do corpo do usuário, é feito um mapeamento
linear entre os movimentos da mão real e da mão virtual. Quando a mão estiver além
dos limites desta esfera, o mapeamento passa a ser exponencial, permitindo um maior
alcance do braço.
Existem trabalhos, por outro lado, em que é aplicado um fator de escala,
diminuindo o tamanho do ambiente virtual e, com isto, aumenta-se o alcance da mão do
usuário. Um exemplo desta abordagem é o sistema “WIM - World in Miniature”
[STO95]. Neste, o ambiente virtual é reduzido de tal forma a ficar sobre uma das mãos
do usuário, que pode manipular os objetos com outra mão. A colocação do ambiente
virtual sobre uma das mãos do usuário permite ainda que se possa efetuar rotações e
146
transações neste ambiente com bastante facilidade. O outro exemplo desta categoria de
técnica de interação é a Scaled World Grab [MIN97]. No método, ao selecionar-se um
objeto, o ambiente virtual é automaticamente escalado de forma que o objeto fique ao
alcance da mão do usuário. Feita a manipulação, uma escala inversa devolve os objetos
a seu tamanho original, respeitando as transformações realizadas durante o processo de
manipulação (Figura 4-17).

Figura 4-17 - Técnica scaled world grab (imagem adaptada de [MIN97])

4.7.1.4 Metáforas de apontamento por raio


Nas metáforas de apontamento por raio (ou “ray casting”) o conceito de apontar
o objeto em uma imagem bidimensional é estendido para um ambiente tridimensional
[BOL80]. Nelas, um raio controlado pelo usuário atinge o objeto a ser manipulado
(Figura 4-18).
147
Figura 4-18 – Manipulação através de apontamento por raio
As várias formas de implementar esta metáfora [JAC94, MIN95] diferem na
maneira como o usuário especifica a direção do raio. As alternativas mais comuns são:
a) Com um dispositivo físico como uma caneta;
b) Com o dedo;
c) Com as duas mãos (criando um raio que tem origem em uma das mãos e a
direção é controlada pela outra);
d) Com a direção da cabeça.

Existem algumas variantes desta técnica. Liang [LIA94], por exemplo, propôs a
técnica de spotlight, na qual o raio apontador é substituído por um cone de
apontamento (Figura 4-19) facilitando o uso em objetos pequenos e/ou distantes.
Forsberg [FOR96], por sua vez, aprimora este último método possibilitando a alteração
interativa do raio da base do cone, garantindo um maior controle em regiões com muitos
objetos próximos. Este controle é feito baseado na distância entre as mãos do usuário
(Figura 4-20).

Figura 4-19 - Apontamento por cone

Figura 4-20 – Seleção por cone variável (imagem adaptada de [FOR96])


A utilização da técnica de “ray casting” tem algumas limitações características.
Para rotação, torna-se bastante natural a aplicação de giros ao redor do eixo definido
pelo raio. Entretanto, a rotação em outros eixos é difícil e pouco natural de ser
especificada pelo usuário. No caso da translação, o deslocamento do raio pode, fácil e
intuitivamente, alterar a posição do objeto. Porém este deslocamento fica restrito aos
pontos que estão sobre a circunferência cujo centro é a mão do usuário, e cujo raio é a
148
distância entre ele e o objeto que está sendo apontado. Na Figura 4-21 pode-se observar
as possibilidades de translação do apontamento por raio.

Figura 4-21 – Possibilidades de translação com raio de apontamento


Uma forma de ampliar estas possibilidades é dar ao usuário algum tipo de
controle que aproxime ou afaste o objeto do ponto de origem do raio (Figura 4-22).
Neste caso há a necessidade de prover algum tipo de controle adicional para que este
comando de afastar ou aproximar seja indicado pelo usuário. Isto pode ser feito, por
exemplo, através de botões ou comandos de voz.

Figura 4-22 - Movimento de aproximação e afastamento do objeto sobre o raio de


apontamento
Para solucionar os problemas de rotação do objeto ao redor de seu próprio eixo
uma técnica interessante é a HOMER (Hand-centered Object Manipulation Extending
“ray casting”) [BOW97] na qual, após a seleção do objeto com um raio, a mão do
usuário transfere-se para o local onde se encontra o objeto e, a partir deste momento,
seu giro passa a controlar o giro do objeto como se este estivesse preso à mão usada
para controlar o raio. Em outras palavras, para selecionar um objeto o usuário utiliza um
raio de apontamento, depois de selecionado o objeto passa a ter sua rotação controlada
149
por mapeamento direto. Em conseqüência disto, a rotação do raio deixa de transladar o
objeto. Para permitir o deslocamento, a técnica cria um raio imaginário entre o peito do
usuário e sua mão, e mantém o objeto preso a este raio (Figura 4-23). Com o
movimento da mão do usuário, o raio é recalculado, reposicionando o objeto. Também é
possível agregar à HOMER o afastamento de aproximação do objeto ao longo do raio
de apontamento, como se faz com “ray casting”.

Figura 4-23 – Translação de utilizando HOMER

4.8 Apontamento de Objetos


Todas as técnicas de interação apresentadas no capítulo anterior exigem a
existência de rotinas de cálculo de interseção entre o apontador do usuário e o objeto a
ser selecionado. Para tanto, existem diversas bibliotecas e técnicas disponíveis.
Exemplos destas bibliotecas podem ser encontrados em:
http://www.gamasutra.com/features/20000330/bobic_01.htm
• Gamasutra
• QuickCD http://www.ams.sunysb.edu/~jklosow/quickcd/
http://www.win.tue.nl/~gino/solid/
• FreeSOLID
http://www.ams.sunysb.edu/~jklosow/quickcd/QCD_resources.html
• Várias bibliotecas
http://www.stanford.edu/~jgao/collision-detection.html
http://www.cs.unc.edu/~geom/collide/index.shtml

Em todas é necessário obter as coordenadas dos vértices do objeto aplicando a


estes pontos todas as transformações geométricas que afetam o objeto.
Em OpenGL, para obter estas coordenadas, e deve-se multiplicar a matriz de
transformação atual pelas coordenadas dos vértices do objeto. No exemplo da Figura
4-24, apresenta-se uma das formas de realizar esta multiplicação.
No caso de apontamento de objetos esta função é útil pois permite calcular as
coordenadas dos vértices dos triângulos que formam este apontador e a partir destas
determinar se há ou não intersecção entre os objetos e o apontador.
150

#include <windows.h>
#include <gl\gl.h>
typedef struct
{
GLfloat x,y,z;
} Ponto3D;
// ***********************************************
// void calcula_ponto(Ponto3D *p, Ponto3D *out)
//
// Esta função calcula as coordenadas de um ponto no sistema de
// referência do universo (SRU), ou seja, aplica as rotações,
// escalas e translações a um ponto no sistema de referência
// do objeto (SRO).
// ***********************************************
void calcula_ponto(Ponto3D *p, Ponto3D *out)
{
GLfloat ponto_novo[4];
GLfloat matriz_gl[4][4];
int i;
glGetFloatv(GL_MODELVIEW_MATRIX,&matriz_gl[0][0]);
for(i=0;i<4;i++)
{
ponto_novo[i]= matriz_gl[0][i] * p->x+
matriz_gl[1][i] * p->y+
matriz_gl[2][i] * p->z+
matriz_gl[3][i];
}
out->x=ponto_novo[0];
out->y=ponto_novo[1];
out->z=ponto_novo[2];
}

Ponto3D p1, p2;


// ***********************************************
// void Desenha ()
//
//
// ***********************************************
void Desenha ()
{
Ponto3D p1_new, p2_new;
p1.x = 10; p1.y = 10; p1.z = 20;
p2.x = 20; p2.y = 10; p2.z = 20;
glRotate3f(10,0,0,1);
glBegin(GL_LINES);
//desenha a linha
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
// aplica as transformações geométricas
// aos pontos da linha
calcula_ponto(&p1, &p1_new);
calcula_ponto(&p2, &p2_new);
//imprime p1_new e p2_new
// .......
glEnd();
}
Figura 4-24 – Aplicação das Transformações geométricas a um ponto
151
4.9 Movimentação de objetos – Transformações hierárquicas
Outro aspecto importante na manipulação de um objeto é a necessidade de fazê-
lo mover-se junto com o apontador que o selecionou. Para tanto, usa-se a idéia de
montar uma hierarquia de objetos em que tem-se “objetos-filhos” que acompanham
todas as transformações de seus “pais”.
As seções a seguir apresentam os conceitos necessários para trabalhar com
hierarquias diretamente em OpenGL.

4.9.1 Representando Transformações Geométricas por Matrizes


As transformações geométricas aplicadas usando comandos OpenGL do tipo
glTranslate, glRotate ou glScale, são sempre armazenadas em uma matriz
chamada MODELVIEW.
A cada chamada de uma destas funções, OpenGL cria uma matriz de
transformação específica para a função e a seguir multiplica esta matriz pela matriz
MODELVIEW atual.
Por exemplo, na chamada da função glTranslatef(-3, 2, -8) é criada
a seguinte matriz:
1.00 0.00 0.00 0.00
0.00 1.00 0.00 0.00
0.00 0.00 1.00 0.00
-3.00 2.00 -8.00 1.00
Note que na última linha da matriz são colocados os valores passados como
parâmetros para a função.
No momento de exibir um objeto o que OpenGL faz é a multiplicação desta
matriz pelos vértices do objeto, obtendo assim a posição final do objeto. Por exemplo,
no caso de exibir o ponto (10, 15, 20) seria obtido o ponto (7,17, 12) conforme a Figura
4-25.

1 0 0
0
0 1 0
0
[10 15 20 1] ∗  = [7 17 12 1]
0 0 1 0
 
− 3 2 − 8 1
Figura 4-25 – Aplicação de uma Translação a um ponto
152
Caso seja desejável ou necessário, é possível setar "à mão" esta matriz de
transformação. Esta operação manual pode ser feita de três formas:
• usando a função glLoadIdentity(): com esta função a matriz de
transformação converte-se na matriz identidade;
• usando a função glLoadMatrixf(matrix): com esta função é possível
definir uma nova matriz de transformação destruindo-se a matrix anterior;
• usando a função glMultMatrixf(matrix): com esta função é possível
multiplicar a matriz de transformação atual por uma segunda matriz.

4.9.2 Aplicando novas Matrizes de Transformação


Caso se tenha uma nova transformação (também representada em forma de
matriz) é possível aplicá-la a matriz atual, bastando multiplicar a matriz atual pela nova
matriz.
Por exemplo, caso tenhamos a matriz de transformação para uma translação (5,
7, 2) a equação a seguir calcula a nova matriz.

Figura 4-26 – Aplicação de uma Nova Translação a um Ponto

4.9.3 Armazenando as Transformações de um objeto em uma matriz


Para armazenar as transformações geométricas de um objeto em uma matriz
deve-se chamar a função glGetFloatv imediatamente após terem sido setadas todas estas
transformações do objeto (Figura 4-27).
GLfloat MatObj [4][4]; // matriz de transformações do objeto
//****************************************************************
// void RecalculaMatrizObjeto()
//****************************************************************
void RecalculaMatrizObjeto()
{
glPushMatrix();
glLoadIdentity();
glTranslatef (PosObj.X, PosObj.Y, PosObj.Z);
// guarda a matriz de transformação do objeto para um futuro uso
glGetFloatv(GL_MODELVIEW_MATRIX, &MatObj[0][0]);
glPopMatrix();
153
}

Figura 4-27 – Obtenção da matriz de Transformação após uma translação

4.9.4 Alterando a Matriz de Transformação antes de desenhar um


objeto
Uma vez que se tem a matriz de transformações de um objeto é possível aplicar
estas transformações multiplicando-se esta matriz pela matriz atual. Isto é feito
conforme a Figura 4-28.
GLfloat MatObj [4][4]; // matriz de transformações do objeto
// **************************************************************
// void DesenhaObjeto()
// **************************************************************
void DesenhaObjeto()
{
glColor3f(0.0f,0.0f,0.6f);
glPushMatrix();
// multiplica a matriz de transformação atual pela
// transformação do objeto-filho a ser desenhado
glMultMatrixf(&MatObj[0][0]);
DesenhaCubo();
glPopMatrix();
}
Figura 4-28 – Aplicação de uma matriz de Transformações a um Objeto

4.9.5 Montando Transformações Hierárquicas


A montagem de uma hierarquia de transformações serve para que se possa
definir um objeto como filho de outro.
Neste caso, o objeto filho sofrerá todas as transformações geométricas aplicadas
a seu pai e mais as suas próprias transformações. Para tanto, deve-se apenas desenhar o
objeto logo após o desenho de seu pai. O exemplo da Figura 4-29 ilustra este
procedimento.
// **************************************************************
// void DesenhaPAI()
//***************************************************************
void DesenhaPAI()
{
glColor3f(0.7f,0.7f,0.0f);
glPushMatrix();
glMultMatrixf(&Mat_Pai[0][0]); //aplica as transformações do pai
DesenhaCubo();
if (TemFilho)
DesenhaObjeto(); // desenha Filho aplicando suas
// transformações
glPopMatrix();
}
Figura 4-29 – Aplicação de uma Transformação Hierárquica
154
Neste caso, entretanto, no instante em um objeto torna-se filho de outro, este
filho irá sofrer as transformações geométricas de seu pai adicionadas às suas. Por
exemplo, se o pai tem uma translação em X igual a 40 e o filho outra igual a 30, então o
objeto-filho irá ser transladado de 70 unidades. Isto irá ocorrer no exato momento em
que o objeto filho for desenhado pela primeira vez após o pai, causando uma translação
indesejada.

4.9.5.1 Montando o vínculo de hierarquia


Para contornar este efeito colateral é necessário que no momento do
estabelecimento da relação pai-filho, a matriz do filho desfaça as transformações
existentes no pai.
Para tanto deve-se multiplicar a matriz do filho pela inversa da matriz do pai,
conforme ilustra o exemplo da Figura 4-30.
Note que isto deve ser feito somente no instante em que se estabelece o vínculo
entre pai e filho. Isto porque só deve-se desfazer as transformações do pai que existem
no momento do estabelecimento do vínculo. A partir deste momento, se uma nova
transformação for aplicada ao pai, ela deverá ser também aplicada ao filho.

// ***************************************************************
// void CriaVinculoPai_Filho()
// ***************************************************************
void CriaVinculoPai_Filho()
{
GLfloat MatInv[4][4];
TemFilho = TRUE;
// calcula a inversa da matriz do Pai
CopyMatrix(MatInv_Pai, Mat_Pai);
M_invert(MatInv_Pai);
// Multiplica a Matriz do filho pela inversa da matriz do pai
M_mult(MatObj, MatInv_Pai); // MatObj = MatObj * MatInv_Pai
}
Figura 4-30 – Cálculo da Transformação do Objeto-Filho

4.9.5.2 Desfazendo o vínculo de hierarquia


Para desfazer o vínculo de hierarquia e deixar o objeto no mesmo lugar, deve-se
multiplicar sua matriz pela matriz atual de seu pai. Se isto não for feito ocorrerá uma
translação indesejada no objeto filho pois este deixará de sofrer as translações do pai
após o término do vínculo.
155
// ****************************************************************
// void DesfazVinculoPai_Filho()
//
// ****************************************************************
void DesfazVinculoPai_Filho()
{
TemFilho = FALSE;
M_mult(MatObj, MatPai); // MatObj = MatObj * Mat_Pai
}
Figura 4-31 – Novo cálculo da Transformação do Objeto-Filho
A partir deste momento o objeto filho não mais deverá ser desenhado após o pai.

4.10 . Ambientes Virtuais Colaborativos


Ambientes Virtuais Colaborativos (AVCs) são ambientes virtuais imersivos
onde dois ou mais usuários podem estar imersos, por meio de dispositivos especiais,
como óculos e rastreadores de posição, no qual podem comunicar-se e/ou trabalhar
conjuntamente em uma ou mais tarefas. Nestes ambientes o computador passa a prover
um espaço digital no qual se pode construir e utilizar espaços compartilhados onde são
realizadas tarefas colaborativas ou individuais [CHU98].
Embora na literatura existam exemplos em que o termo AVC é usado para
designar ambientes como os chats ou as interfaces bidimensionais, em que mais de um
usuário pode interagir, estes sistemas estão fora do escopo deste trabalho. Como no
trabalho de Fraser et al. [FRA2000], aqui, o termo AVC é usado para descrever
especificamente sistemas que possuem uma interface gráfica tridimensional para
múltiplos usuários. Em outras palavras, pode-se nomear os AVCs de que trata este
trabalho como ambientes tridimensionais em rede (“networked virtual environments”).
Nestes sistemas um mesmo ambiente gráfico tridimensional é exibido por dois ou mais
computadores, cada um deles representando a visão de um usuário imerso no ambiente
virtual. Dentro deste ambiente cada usuário é personificado para seus parceiros na
forma de um avatar* e pode navegar e interagir com objetos do ambiente além de
comunicar-se com seus parceiros. Os objetos do ambiente gráfico, em geral,
representam dados da aplicação.

*
Avatar é uma palavra em sânscrito que tem origem na Índia, com o significado de encarnação.
Parece ter sido trazida para o campo da tecnologia pela série de TV Snowcrash, escrita por Neal
Stephenson.
156
O uso de ambientes virtuais colaborativos tem crescido nos últimos anos,
principalmente em face da melhoria das condições providas pelos computadores
pessoais e do aumento dos recursos de rede, cada vez mais baratos, rápidos e confiáveis.

4.10.1 Memória distribuída


Para permitir o uso de Ambientes Virtuais Colaborativos é necessário que se
utiliza algum tipo de ferramenta de comunicação entre os nodos. Um das possibilidades
existente é usar a biblioteca RemoteMemory, descrita a seguir. O download desta
biblioteca pode ser feito em http://grv.inf.pucrs.br/Pagina/RemoteMemory. Esta
biblioteca foi originalmente com o apoio de Rafael S. Garcia
(rafael_sgarcia@terra.com.br).

4.10.2 Remote Memory


O principal objetivo da biblioteca “Remote Memory” é permitir que o
usuário tenha a sua disposição uma memória de dados que pode ser compartilhada entre
programas que rodam em máquinas diferentes. A partir de uma aplicação servidora,
rodando em uma máquina remota, o usuário pode criar aplicações clientes que se
conectem a esse servidor e pode compartilhar dados entre as aplicações.
O diagrama da Figura 4-32 mostra o funcionamento básico da biblioteca.

Figura 4-32 – Arquitetura da RemoteMemory


Para a comunicação entre os nodos, pode-se usar tanto TCP/IP quanto UDP,
dependendo das necessidades da aplicação.

4.10.2.1 Compilando a RemoteMemory


Para explicar como deve ser compilada a biblioteca, assumiremos que o usuário
esteja utilizando o software “Visual C++”. Isto entretanto não é essencial, visto que o
código fonte da biblioteca também comipila com o GNU C++.
Em um primeiro momento, deve-se criar um novo projeto do tipo
“Win32 Console Application”. Em seguida, deve-se adicionar nas configurações do
157
projeto a biblioteca que contém as funções de rede. Para se fazer isso, deve-se clicar
com o botão direito do mouse em cima do nome do projeto e selecionar a opção
“Settings...” no menu que irá se abrir. Pode-se também selecionar o projeto e usar as
teclas de atalho “ATL + F7”. Na janela que irá se abrir, deve-se selecionar a guia
“Link” e no ítem “Category” deve-se selecionar a opção “General”. Na área
denominada “Object/Library modules” deve-se adicionar a biblioteca “wsock32.lib”,
exatamente como esta demonstrado na figura abaixo.

Figura 4-33 – Configuração do Compilador para a RemoteMemory


Com a Remote Memory Library é possível crair dois tipos de aplicação:
servidora, que armazena os dados, e cliente, que lê e altera esses dados.
Para uma aplicação servidora deve-se adicionar os seguintes arquivos:
“MemoryServer.cpp” e “RemoteMemory.h”. Para adicionar esses arquivos no projetos,
deve-se clicar com o botão direito do mouse em cima do nome do projeto e selecionar
“Add Files to Project...” no menu que apareceu. Na janela que irá se abrir, deve-se
selecionar os dois arquivos já mencionados (e que, de preferência, estejam no mesmo
diretório do projeto) e clicar em “Ok”.
Para uma aplicação cliente, os arquivos que devem ser adicionados ao projeto
são: “MemoryClient.cpp” e “RemoteMemory.h”. O processo para adicionar os arquivos
é o mesmo descrito acima.
158
4.10.2.2 Montando uma Aplicação Cliente
Para descrever o processo de criação de uma aplicação cliente, vamos
assumir que o usuário esteja utilizando a aplicação servidora padrão, distribuída
juntatente com a biblioteca.
Para a criação de uma aplicação cliente, o primeiro passo é adicionar os
cabeçalhos da biblioteca “Remote Memory Library” ao novo arquivo fonte. Após isso,
a primeira etapa da aplicação deve ser conectar o novo cliente no servidor da memória
remota compartilhada. O trecho de código da Figura 4-34 exemplifica como ficaria uma
conexão com o servidor de memória compartilhada.
#include "RemoteMemory.h"

void main ( int argc, char** argv )


{
char serverIP[30];
if (argc < 2) {
printf ( "Command line parameters: ServerIP\n" );
exit(1);
}
strcpy ( serverIP, argv[1] );
int result = ConnectToRemoteMemory ( serverIP );
if ( !result ) {
printf ( "Unable to connect to Memory Server at %s.\n\n",
serverIP );
exit (0);
}
Figura 4-34 – Inicialização da RemoteMemory

O valor retornado pela função é 1 quando a consegue estabelecer a conexão e 0


quando da erro. O parâmetro serverIP da função é uma “string” que indica o
endereço ou o número IP da máquina onde a aplicação servidora deve estar rodando.
Por exemplo, se a aplicação servidora está sendo executada na mesma máquina que a
aplicação cliente, esse parâmetro será 127.0.0.1 ou localhost. Essa função abre
dois tipos de conexão com o servidor: uma conexão via TCP/IP e a outra via UDP. O
usuário poderá usar funções dos dois tipos de conexão no mesmo programa sem
problemas.
A partir desse ponto, o usuário poderá desenvolver a aplicação da maneira que
achar mais adequada para as suas necessidades.
Para gravar dados na memória remota compartilhada de dados, o usuário poderá
usar uma das duas funções abaixo:
void WriteOnRemoteMemoryIP (void *message, WORD address, int size)
void WriteOnRemoteMemoryUDP (void *message, WORD address, int size)
159
A primeira função grava o dado na memória remota compartilhada através da
conexão via TCP/IP enquanto que a segunda função grava o dado via UDP. Os
parâmetros para as duas funções são os seguintes:
• message: o dado que será enviado para o servidor e gravado na
memória remota compartilhada.
• address: o endereço da memória remota compartilhada onde esse
dado deve ser gravado.
• size: o tamanho (em bytes) do dado que será gravado.

É importante que o usuário entenda como se constitui a memória remota


compartilhada para trabalhar corretamente com ela. Cada posição da memória remota
compartilhada equivale a 1 byte. Logo, para se gravar 3 valores inteiros em sequência
não se pode utilizar, por exemplo, os endereços 3, 4 e 5. Se o usuário fizer isso, não
terá os dados corretos quando for feita uma leitura desses valores. O mais indicado a
fazer, nesse caso, seria gravar os dados nos endereços 3 * sizeof(int), 4 *
sizeof(int) e 5 * sizeof(int). Com isso, o usuário garante que terá seus três
valores gravados em sequência e os dados esterão corretos.
Para ler dados da memória remota compartilhada, as funções são as seguintes:

void ReadFromRemoteMemoryIP (void *message, WORD address, int size)


void ReadFromRemoteMemoryUDP(void *message, WORD address, int size)

Novamente, a primeira função lê o dado da memória remota compartilhada


através ad conexão TCP/IP enquanto que a segunda lê o dado via UDP. Os parâmetros
são os seguintes:
• message: onde o dado será armazenado quando for lido.
• address: o endereço da memória remota compartilhada onde
esse dado deve ser gravado.
• size: o tamanho (em bytes) do dado que será gravado.

Outro exemplos de utilização da RemoteMemory podem ser encontrados na


página http://grv.inf.pucrs.br/Pagina/RemoteMemory.
160

4.11 Exibição de Cenários em Múltiplas Telas


Diversas aplicações de realidade virtual necessitam exibir cenários em um
conjunto de telas colocadas lado a lado. Este é o caso das CAVEs e dos Workbenches.
Um exemplo de uma cena exibida em várias telas é apresentada na Figura 4-35.

Figura 4-35 – Cena em Múltiplas telas


Em OpenGL, para gerar este tipo de imagem usa-se a função glFrustum que
define o View Frustum ou “volume de visualização” a ser usado para projetar uma cena
da tela. Na Figura 4-36 pode-se observar o “volume de visualização” e sua relação com
a posição do observador e do alvo.

Figura 4-36 – Volume de Visualização


Na Figura 4-37 este mesmo “volume de visualização” é apresentado com suas
respectivas dimensões.
161

Figura 4-37 – Volume de Visualização (com dimensões)


Na figura, os valores DF e DN são, respectivamente as distâncias máximas e
mínimas do volume visível pelo observador e L (de Left) e R (de Right) definem o
quanto o observador vê à esquerda e à direita de seu ponto central de visão, exatamente
na distância do plano NEAR. Para definir um volume de visualização é necessário ainda
definir os limites verticais (inferior e superior) da visão do observador na distância do
plano NEAR. Para efeito de exemplo estas medidas serão chamadas B (de Bottom) e T
(de Top), respectivamente.
Os valores de NEAR e FAR são fornecidos, em geral, pela aplicação. Os valores
de L e R podem ser calculados a partir do ângulo de visão pelas fórmulas:
L = -Near * tan(ViewAngleRad/2)
R = Near * tan(ViewAngleRad/2)
Se considerarmos o Plano NEAR como um quadrado, teremos B igual a L e T
igual a R.
A partir destes valores é possível definir o volume de visualização, através da
função glFrustum. O código da Figura 4-38 apresenta um exemplo deste
procedimento.
162
4.11.1 Dividindo o View Frustum em Múltiplas Telas
Para exibir uma cena em múltiplas telas, deve-se dividir o “volume de
visualização” de forma que cada janela exiba uma parte dele. Na Figura 4-39 pode-se
observar 3 volumes de visualização distintos.

// ****************************************************************
// void SetViewFrustum()
//
//
// ****************************************************************
void SetViewFrustum()
{
float Near, Left, Right, Bottom, Top;
float ViewAngleRad;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

ViewAngleRad = ViewAngle * 3.14f/180;

Near = 1; // definido na aplicação


Far = 100; // definido na aplicação

// Calcula os limites horizontais do View Frustum


Left = -Near * tan(ViewAngleRad/2);
Right = Near * tan(ViewAngleRad/2);

// Calcula os limites verticais do View Frustum


Bottom = -Near * tan(ViewAngleRad/2);
Top = Near * tan(ViewAngleRad/2);

// Seta o Frustum
glFrustum(Left, Right, Bottom, Top, Near, Far);

glMatrixMode(GL_MODELVIEW);
SetObs(); // posiciona o observador
}
Figura 4-38 – Setando o Volume de Visualização

Figura 4-39 – Dividindo o Volume de Visualização


163
Em OpenGL, para recalcular o View Frustum, toma-se o ângulo de visão e
divide-se pelo número de janelas nas quais se deseja exibir a imagem. Note que se deve
dividir separadamente o volume na horizontal e na vertical pois o número de telas nestas
duas direções pode ser diferente.
No código apresentado na Figura 4-40 pode-se observar um exemplo que um
“volume de visualização” é dividido horizontalmente em 3 janelas e verticalmente em
duas. A Figura 4-41 apresenta o resultado visual deste programa.

// **************************************************************
// void SetViewFrustum()
// **************************************************************
void SetViewFrustum()
{
float Near, Left, Bottom, Top, Right, TileWidth, TileHeight;
float ViewAngleRad;

glMatrixMode(GL_PROJECTION); glLoadIdentity();

Near = 1; // definido na aplicação


Far = 100; // definido na aplicação

// Calcula os limites horizontais do View Frustum


Left = -Near * tan(ViewAngleRad/2);
Right = Near * tan(ViewAngleRad/2);

// Calcula os limites verticais do View Frustum


Bottom = -Near * tan(ViewAngleRad/2);
Top = Near * tan(ViewAngleRad/2);

// Calcula a largura e a altura de cada janela


TileWidth = (Right - Left)/3;
TileHeight = (Top - Bottom)/2;

// Seta o Frustum de cada janela


if (glutGetWindow() == jan1) // Inferior Esquerda
glFrustum(Left, Left+TileWidth,
Bottom, Bottom+TileHeight, Near, Far);

if (glutGetWindow() == jan2) // Inferior Central


glFrustum(Left+TileWidth, Left+TileWidth*2,
Bottom, Bottom+TileHeight, Near, Far);

if (glutGetWindow() == jan3) // Inferior Direita


glFrustum(Left+TileWidth*2, Left+TileWidth*3,
Bottom, Bottom+TileHeight, Near, Far);

if (glutGetWindow() == jan4) // Superior Esquerda


glFrustum(Left, Left+TileWidth,
Bottom+TileHeight, Top, Near, Far);

if (glutGetWindow() == jan5) // Superior Central


glFrustum(Left+TileWidth, Left+TileWidth*2,
Bottom+TileHeight, Top, Near, Far);
164
if (glutGetWindow() == jan6) // Superior Direita
glFrustum(Left+TileWidth*2, Left+TileWidth*3,
Bottom+TileHeight, Top, Near, 100);

glMatrixMode(GL_MODELVIEW);

SetObs();
}
Figura 4-40 – Código de Divisão do View Frustum

Figura 4-41 – “Telão 3 x 2”

4.12 Geração de Tato em Ambientes Virtuais


Dispositivos de geração de tato são normalmente utilizados para indicar quando
o usuário está em contato com algum objeto virtual. Existem ainda outros aparatos de
touch feedback que são utilizados para simular texturas e outras sensações táteis.
Aqui abordaremos a estimulação vibratória, por gerar uma boa sensação de tato,
ser de fácil implementação e possuir baixo custo.
Na estimulação vibratória são utilizados motores vibratórios semelhantes aos
encontrados nos celulares. Para gerar vários tipos de sensações deve-se ligar o motor e
deixar a tensão aplicada sobre ele apenas em fatias de tempo, fazendo assim com que a
165
intensidade do estímulo aumente ou diminua de acordo com o tempo que o motor fica
energizado.
Dessa forma, podemos variar a intensidade do tato variando a porcentagem de
tempo ligado/desligado ou variando-se o período utilizado como base para a variação.
Para utilizar esses motores foi desenvolvida uma placa controladora que pode
controlar até quatro motores(Figura 4-42). Essa placa é conectada na porta serial e roda
um driver que obedece aos comandos para mudar a fatia de tempo em que os motores
ficam ligados/desligados. Para maiores informações sobre esta placa faça contato com
os autores, pelo email pinho@inf.pucrs.br.

Figura 4-42 – Placa Controladora para Dispositivos de Geração de Tato

Para utilizar a placa deve-se conectá-la na porta serial e pressionar seu botão de
reset, para reiniciar o driver. O driver ficará parado até receber os dois primeiros bytes,
que indicarão o período base que a placa utilizará, sendo FFFF o maior período e 0000 o
menor. Depois disso o driver passa a monitorar o funcionamento dos motores. Então,
para cada alteração no comportamento de algum motor deve ser enviado um byte para a
serial. Nesse byte os dois bits mais significativos indicam o motor 00, 01, 10 ou 11, e os
outros indicam a proporção de tempo que o motor deve ficar ligado, sendo que 000000
deixa desligado e 111111 deixa sempre ligado.
Uma vez alterada a freqüência de algum motor, a mesma ficará inalterada até
que o valor seja atualizado novamente.

4.13 Referências

[BAL98] BALDIS, J. Effects of Spatial Audio on Communication During Desktop


166
Conferencing. Unpublished masters thesis, University of
Washington.1998. Documento disponível no endereço eletrônico
http://www.hitl.washington.edu/publications/r-98-23/
[BAS2001] BASDOGAN, C., Srinivasan, M.A., 2001, “Haptic Rendering In Virtual
Environments (PDF)” ,“Virtual Environments HandBook”, pp. 117-134.
http://network.ku.edu.tr/~Ecbasdogan/Papers/VRbookChapter.pdf
[BOL80] BOLT, R., Put-that-there: voice and gesture at the graphics interface.
In:ACM SIGGRAPH CONFERENCE. SIGGRAPH’80 Los Angeles,
1980, Proceedings... Los Angeles: ACM Press, 1980. p. 262-270.
[BOW99] BOWMAN, D., & HODGES, L. Formalizing the design, evaluation, and
application of interaction techniques for immersive virtual environments.
The Journal of Visual Languages and Computing, New York, v. 10,
n.1, p. 37–53. Jun. 1999.
[BUR96] BURDEA, Grigore;. Force and Touch Feedback for Virtual Reality.
Prentice Hall, 2002.
[CHU98] CHURCHILL, E.F.; SNOWDOWN, D. Collaboratorative Virtual
Environments: An Introductory Review of Issues and Systems. Virtual
Reality, Londres, v. 3, n. 1, p 5-9, Jan. 1998.
[DUR2002] DURLACH, N., SLATER M. Presence in Shared Virtual Environments
and Virtual Togetherness.. Disponível em
<http://www.cs.ucl.ac.uk/staff/m.slater/BTWorkshop/durlach.html>
Acesso em: 20 de mar. 2002).
[FOR96] FORSBERG, A., HERNDON, K., ZELEZNIK, R. Aperture based
selection for immersive virtual environment. In:ACM USER
INTERFACE SOFTWARE AND TECHNOLOGY, UIST’96, 1996,
Seattle. Proceedings…, Los Angeles:ACM Press, 1996. pp. 95-96.
[FRA2000] FRASER, M., GLOVER, T., VAGHI, I., BENFORD, S.,
GREENHALGH, C., HINDMARSH, J., HEATH, C. Revealing the
realities of collaborative virtual reality. In: ACM Collaborative Virtual
Enviroment’2000. ACM CVE, 2000, San Francisco, CA. Proceedings…
Los Angeles: ACM Press, 2000. p. 29-37.
[JAC94] JACOBY, R., FERNEAU, M., HUMPHRIES, J. Gestural Interaction in a
Virtual Environment. In:STEREOSCOPIC DISPLAYS AND VIRTUAL
167
REALITY SYSTEMS CONFERENCE, 1994, [s.l.]
[LEC2002] LECUYER, A.; MEGARD, Christine; BUCKHARDT, Jean-Marie; LIM,
Taegi; COQUILLART, Sabine; COIFFET, Phillipe, GRAUX, Ludovic.
The Effect of Haptic, Visual and Auditory Feedback on an Insertion
Task on a 2-Screen Workbench. Extraído em agosto de 2002. Online.
Disponível na Internet:
http://www-rocq.inria.fr/i3d/i3d/publications/lecuyeript.pdf
[LIA94] LIANG, J., GREEN, M., JDCAD: A highly interactive 3Dmodeling
system. Computer and Graphics, New York, v. 4, n. 18, p. 499-506.
Apr. 1994.
[MAC2002] MACLEAN, K. Design of Haptic Interfaces. Extraído em agosto de
2002. Online. Disponível na Internet:
http://www.cs.ubc.ca/~maclean/publics/uist01-hapticsSurv.pdf
[MIN95] MINE, M. Virtual environment interaction techniques. Chapel Hill:
UNC CS Dept., 1995. (Technical Report TR95-018)
[MIN97] MINE, M., ISAAC: A Meta-CAD System for Virtual Environments.
Computer-Aided Design, [s.l.]
[PIN2003] PINHO, M. S. SmallVR Uma Ferramenta Orientada a Objetos para o
Desenvolvimento de Aplicações de Realidade Virtual. Proceedings of
the 5th SVR – Symposium on Virtual Reality, Fortaleza, Brasil, Outubro
2003, p. 329-340.
[POU96] POUPYREV, I., M. BILLINGHURST, S. WEGHORST AND T.
ICHIKAWA. The Go-Go Interaction Technique: Non-Linear Mapping for
Direct Manipulation in VR. In: ACM SYMPOSIUM ON USER
INTERFACE SOFTWARE AND TECHNOLOGY, 1996, Seattle, WA.
Proceedings…, New York, NY: ACM Press, 1996, p.79-80.
[SCH98] SCHNEIDERMAN, B. Design the user Interface: strategies for effective
human-computer Interaction. Addison-Wesley. 3rd ed., 1998.
[STO95] STOAKLEY, R., CONWAY, M., PAUSCH, R., Virtual reality on a
WIM: interactive worlds in miniature. In:ACM CONFERENCE ON
HUMAN FACTORS IN COMPUTING SYSTEMS., CHI’95, 1995,
Denver, Colorado. Proceedings… New York, NY: ACM Press, 1995. p.
265-272.
168
[VAN97] VAN DAM, A. Post-WIMP User Interfaces. Communications of the
ACM. Vol 40. No. 2, Feb 1997. P 63-67.

5 Realidade Aumentada: Conceitos e Ambientes de


Hardware
Claudio Kirner1, Celso Providelo2

1
Universidade Metodista de Piracicaba (UNIMEP)
2
Escola de Engenharia de São Carlos – Universidade de São Paulo (USP)

ckirner@unimep.com.br, cprov@gwyddion.com

Resumo. Este capítulo tem como objetivo apresentar os conceitos


relacionados com realidade aumentada e mostrar as características de
hardware de plataformas apropriadas para execução do software de
desenvolvimento de realidade aumentada ARToolKit. O Projeto DRAI
(Dispositivo de Realidade Aumentada Interativo) é apresentado como forma
de ilustrar o processo de concepção e desenvolvimento de um ambiente de
hardware para aplicações de realidade aumentada.

5.1 Introdução
Quando se trabalha com aplicações gráficas relacionadas com cenas imaginárias
ou representativas do mundo real, surgem vários conceitos que podem, à primeira vista,
gerar alguma confusão, envolvendo: multimídia, realidade virtual, realidade aumentada,
realidade misturada, virtualidade aumentada e hiper-realidade.
Além desses conceitos, o ambiente de hardware apropriado para cada
caso pode sofrer variações, impondo requisitos diferentes.
Nas seções seguintes, esses conceitos serão apresentados e os ambientes
de hardware serão discutidos, dando-se uma ênfase especial ao ambiente de hardware
para realidade aumentada, em função de sua importância e do relacionamento desse
assunto com outros capítulos deste livro, particularmente aqueles que abordam o uso do
software de realidade aumentada ARToolKit [ARToolkit, 2004].
169
5.2 Conceitos

5.2.1 Mutimídia
Existem várias definições de multimídia, sendo algumas citadas a seguir:
a) Multimídia é a combinação de várias tecnologias e formas de arte, incluindo texto,
áudio, música, fotografia e vídeo, gerando aplicações novas e maravilhosas [Olsen,
1997].
b) Multimídia é o uso simultâneo de dados em diferentes formas, envolvendo voz,
vídeo, texto, animações, etc [Buford, 1994].
c) Multimídia é a integração, controlada por computador, de textos, gráficos, imagens,
vídeo, animações, áudio e outras mídias que possam representar, armazenar,
transmitir e processar informações de forma digital [Mashall, 2001].
A multimídia pode ainda ser interativa, na medida em que a aplicação
possa responder às ações do usuário.
Normalmente, a multimídia trabalha com imagens pré-gravadas ou
capturadas, atuando no espaço bidimensional e usando grande volume de dados, que,
em geral, costumam ser comprimidos. A grande preocupação da multimídia situa-se na
qualidade da imagem.
Os ambientes computacionais multimídia precisam de processamentos
específicos executados em placas de vídeo e de som, além de canais internos e externos
com alta capacidade de transmissão.

5.2.2 Realidade Virtual


Existem também muitas definições de realidade virtual, envolvendo questões
gerais ou tecnológicas [Burdea, 1994], [Vince, 1995, 2004], [Kirner, 1996], [Sherman,
2003], que podem ser sintetizadas da seguinte forma:
- Realidade Virtual é uma interface avançada para aplicações computacionais, onde o
usuário pode navegar e interagir, em tempo real, em um ambiente tridimensional
gerado por computador, usando dispositivos multisensoriais.
Apesar da realidade virtual também usar múltiplas mídias, seu maior
compromisso do sistema é a interação e a geração das imagens do ambiente
tridimensional em tempo real, sob controle do usuário. Para isto, a principal
característica do ambiente computacional é a capacidade de processamento gráfico
170
voltada para a geração das imagens em tempo real, complementada com dispositivos
não convencionais para interação no ambiente tridimensional.

5.2.3 Realidade Misturada


A realidade misturada é um conceito que envolve a sobreposição de objetos
virtuais tridimensionais gerados por computador com o ambiente físico, mostrada ao
usuário, com o apoio de algum dispositivo tecnológico, em tempo real.
O dispositivo tecnológico, que pode ser um capacete misturador de visão
direta ou um capacete de visualização com uma câmera de vídeo acoplada apontada
para a frente do usuário, permite misturar a cena real com objetos virtuais, com o apoio
do computador. Em outros casos, o dispositivo tecnológico pode ser um conjunto de
câmeras que capturam imagens de pessoas ou objetos reais para serem usadas em
processos de reconstrução e inserção desses elementos no ambiente virtual, em tempo
real. A maneira mais simples de obter-se realidade misturada, é usar uma webcam para
capturar uma cena real, na qual são adicionados objetos virtuais, sendo o conjunto
mostrado no monitor de um computador.
A realidade misturada pode ser desdobrada em duas categorias: realidade
aumentada, quando o ambiente principal é real ou há predominãncia do real no
ambiente misturado, e virtualidade aumentada, quando o ambiente principal é virtual
ou há predominância do virtual, conforme o diagrama de realidade e virtualidade
contínuas [Milgran, 1994], [Sherman, 2003], mostrado na Figura 5-1 - Realidade e
Virtualidade contínuas .
O ambiente computacional para aplicações de realidade misturada deve
ser apropriado para realidade virtual, com placas gráficas de alto desempenho e
incorporar recursos para captura de vídeo, rastreamento e mistura de imagens. Alguns
dispositivos de interação, como a luva, pode ser eliminada, na medida em que o usuário
usa as mãos rastreadas por técnicas ópticas e visão computacional.
171

Figura 5-1 - Realidade e Virtualidade contínuas

5.2.4 Realidade Aumentada


O termo realidade aumentada foi muito difundido, sendo muitas vezes usado no
lugar de realidade misturada.
A realidade aumentada é o enriquecimento do ambiente real com elementos virtuais,
usando algum dispositivo tecnológico, funcionado em tempo real. Os elementos virtuais
podem ser textos, imagens e objetos virtuais, gerados por computador
Uma definição mais elaborada feita por Azuma [Azuma, 2001] diz que realidade
aumentada é um sistema que suplementa o mundo real com objetos virtuais gerados por
computador, parecendo coexistir no mesmo espaço e apresentando as seguintes
propriedades: combina objetos reais e virtuais no ambiente real; executa interativamente
em tempo real; alinha objetos reais e virtuais entre si; e aplica-se a todos os sentidos,
incluindo audição, tato e força e cheiro.
Pode-se, assim, colocar um vaso e um carro, ambos virtuais, sobre uma mesa real,
conforme a Figura 5-2.
172
Figura 5-2 - Realidade aumentada com vaso e carros virtuais sobre uma

Também é possível manipular objetos virtuais colocados no ambiente


real, usando as mãos ou algum dispositivo como uma pá. A Figura 5-3 mostra uma
sequência de passos que transferiru o objeto de um local para outro, permitindo a
organização ou reorganização do ambiente misturado [Kawashima, 2001], [Kirner,
2004], [Galana, 2004], [Santin, 2004].

Figura 5-3 - Transporte de um objeto virtual com uso de uma pá

Com esse potencial, a realidade aumentada deverá ter grande impacto no


relacionamento das pessoas, facilitando o trabalho e o desenvolvimento cognitivo das
pessoas, através de novas maneiras de visualizar, comunicar e interagir com pessoas e
informação.

5.2.5 Virtualidade Aumentada


A virtualidade aumentada é uma particularização da realidade misturada, quando
o ambiente principal é virtual ou há predominância do virtual. Pode ainda ser definida
como o enriquecimento do ambiente virtual com elementos reais pré-capturados ou
capturados em tempo real.
Além de objetos estáticos, pode-se também levar objetos reais dinâmicos,
como mãos e pessoas, para o ambiente virtual. Nesse caso, os objetos são capturados
por câmeras de vídeo, reconstruídos em tempo real, mantendo a animação, e levados ao
mundo virtual, onde podem interagir.
Trabalhos como 3D Live [Prince, 2002], Mãos Colaborativas [Kirner,
2004] e Teleconferência com Virtualidade Aumentada [Sicoutto, 2004] permitem a
inserção de avatares (pessoas ou mãos) dentro do ambiente virtual para visitarem e
interagirem com o ambiente. Usando-se o software ARToolKit [ARToolKit, 2004],
pode-se capturar a imagem de uma mão com um marcador preso a ela, mostrando-a em
um monitor, ao mesmo tempo em que se faz a captura de sua posição. Com isto, pode-
173
se colocar uma mão virtual sobreposta com a mão real, de forma que as duas se
movimentem juntas. A mão real, conduzindo a mão virtual, pode assim tocar os objetos
virtuais, analisando-se a colisão da mão virtual com os objetos virtuais. A eliminação
das imagens reais vindas da câmera de vídeo, através do controle de parâmetros no
ARToolKit [Providelo, 2004], permite mostrar somente os elementos virtuais e mão
virtual "reconstruída", fazendo com que o ambiente funcione como virtualidade
aumentada.
A virtualidade aumentada tem um potencial de uso bastante grande, na
medida em que permite a inserção de avatares humanóides realistas no mundo virtual.
Isto melhora as condições de infraestrutura computacional para as pessoas se
encontrarem para: trocar idéias, trabalhar em conjunto, fazer compras, estudar e
interagir de muitas outras formas.

5.2.6 Hiper-realidade
Depois da combinação do real com o virtual, o próximo passo é incrementar esse
ambiente, adicionando novos elementos para facilitar e potencializar a interação do
usuário com os recursos necessários na sua vida diária.
Nessa linha de pensamento, surge o conceito de hiper-realidade [Tiffin,
2001], cuja definição é a seguinte: hiper-realidade é a capacidade tecnológica de
combinar realidade virtual, realidade física, inteligência artificial e inteligência humana,
integrando-as de forma natural para acesso do usuário.
Ambientes de hiper-realidade permitirão que habitantes reais interajam
com habitantes remotamente localizados, bem como com formas de vida imaginárias ou
artificiais, geradas por computador, em um mundo misturado. Esse mundo será
formado por pessoas, animais, insetos, plantas, terrenos, construções e objetos virtuais
inteligentes, todos integrados. Com a visão do mundo misturado, cada usuário poderá
enxergar o que lhe interessa, de acordo com seu perfil ou sua necessidade, e interagir
com os objetos, de forma a ter suas necessidades satisfeitas. Como exemplo, o usuário,
ao caminhar ou dirigir seu automóvel por uma cidade (usando um capacete de visão
direta), poderá fazer solicitações por comandos de voz e ver legendas virtuais nos
prédios e ruas orientando-o ou mostrando opções como: o melhor caminho para chegar
a um destino; restaurantes de determinados tipos ou padrões; entretenimentos
específicos; lojas; supermercados; hospitais; e assim por diante.
174
5.3 Ambiente de Hardware para Realidade Aumentada
Um dos recursos de software, muito usado no desenvolvimento de aplicações de
realidade aumentada, é o ARToolKit. Além de ter seu código aberto e ser gratuito, esse
software está disponível para uso em diversas plataformas de sistemas operacionais,
incluindo o Linux, também aberto e gratuito.
No entanto, para ser utilizado, o ARToolKit precisa ser configurado,
calibrado e ajustado para o ambiente computacional, incluindo as câmeras de vídeo
utilizadas.
Uma alternativa para eliminar a configuração e os ajustes está no
desenvolvimento de uma plataforma de hardware dedicada ao ARToolKit. Essa
plataforma compõe-se de: processador, webcam e monitor ou televisão. Ao ligar-se a
plataforma, ela passa automaticamente a executar a aplicação residente. O uso de uma
memória externa permitirá a troca de aplicações.
Assim, é apresentado em seguida o projeto de uma plataforma de
hardware dedicado, denominada DRAI (Dispositivo de Realidade Aumentada
Interativo) [Providelo, 2004].

5.3.1 Concepção da Plataforma


O projeto DRAI foi concebido, a priori, para possibilitar a execução de
aplicações de Realidade Aumentada [Azuma, 2001] na área de Educação ou
Entretenimento, por usuários sem conhecimento prévio de informática e/ou manutenção
de software.
As aplicações são baseadas no ambiente ARToolKit [ARToolKit, 2004]
e no Sistema Operacional GNU/Linux [GNU/Linux, 2004], assuntos estes que
receberão a devida atenção mais adiante.
As estratégias adotadas no DRAI podem ser adaptadas de acordo com o
contexto de cada projeto e utilizadas como forma de facilitar o processo de
desenvolvimento e criar novas perspectivas para o paradigma de "Interface com o
Usuário" em equipamentos industriais e domésticos.
Nesta primeira fase, o projeto DRAI já apresenta resultados animadores,
que apontam a viabilidade, tanto técnica quanto financeira, do desenvolvimento de
ambientes dedicados para aplicações utilizando Realidade Aumentada, além de
resultados satisfatórios de desempenho e escalabilidade. A próxima fase será constituída
de desenvolvimento de ferramentas Desktop para o processo de autoria de conteúdo e
175
integração com Rede e infraestrutura da Internet : Stream player, Interação P2P e E-
commerce.
A fase II do projeto vai de encontro com os interesses eminentes da
comunidade, relacionados ao conceito de “Console para Aplicações Interativas", os
quais, em uma visão simplista, proporcionarão uma plataforma aberta para o
desenvolvimento de inúmeras aplicações em várias áreas de conhecimento, tais como
educacional, entretenimento, etc.
Para atender plenamente às novas necessidades de interação homem-
máquina e usufruir os recursos oferecidos pelo conceito de “Aplicação Interativa”, o
usuário deve contar com uma ferramenta de interface muito mais abrangente e intuitiva
do que o controle remoto, mouse ou joystick e as "telas de menu" utilizadas nos dias
atuais. Exatamente neste ponto é que o desenvolvimento de plataformas dedicadas para
controlar estes processos interativos e o uso de técnicas de Realidade Aumentada
contribuem para a rápida implantação e adaptação dos recursos oferecidos e para o
aumento contínuo da usabilidade.
O "Console para Aplicações Interativas" (Figura 5-4) é somente um dos
vários exemplos de aplicação onde há a necessidade de sistemas dedicados com a
utilização da Realidade Aumentada presentes no cotidiano. Ainda é possível vislumbrar
uma grande variedade de aplicações em que, utilizando-se dos mesmos conceitos,
técnicas e recursos, pode-se usufruir os mesmos benefícios.
Mais adiante serão exibidos conceitos nos quais todo o processo de
desenvolvimento do DRAI foi baseado, os resultados obtidos comparados aos
resultados esperados (idéias), bem como alternativas de implementação dependentes do
contexto no qual serão aplicadas.

Figura 5-4 - DRAI: "Console para aplicações interativas"


176
Há ainda pesquisas aliadas aos conceitos de Ubiquitous Computing
[Weiser, 1991], onde toda a funcionalidade garantida pelo DRAI seria oferecida por
meio da infra-estrutura instalada, como por exemplo: processamento distribuído de
imagens em um Desktop compartilhado, câmera de vídeo compartilhada com o Sistema
de Segurança, entre outras possibilidades fascinantes introduzidas por este novo
conceito.

5.3.2 Ambiente Dedicado


O ambiente dedicado DRAI utiliza um SBC (Single Board Computer), que
apresenta as seguintes características:
• Alta disponibilidade;
• Alta compatibilidade com a arquitetura PC;
• Baixo consumo;
• Dimensões reduzidas;
• Disponibilidade de Periféricos;
• Capacidade de Expansão e Customização.
Atualmente, a compatibilidade com a plataforma PC e a existência de
ferramentas de desenvolvimento CROSS-PLATFORM eliminam o tempo e o custo de
projeto, desenvolvimento e certificação de uma plataforma específica para cada
finalidade ou aplicação, estimulando a utilização de desenvolvimento paralelo de novas
SBCs, cada vez mais confiáveis e com custos mais acessível.
Outro fator que contribui muito para a utilização destes equipamentos é a
padronização de barramentos de periféricos e sua grande abrangência, como, por
exemplo, o barramento USB, proporcionando alta velocidade de transferência de dados
(~ 480 Mbit), facilidades PLUG-AND-PLAY, possibilidade de expansão do barramento
e imensa variedade de equipamentos compatíveis, dentre eles: câmeras com definição e
velocidade adequadas (640x480 e 30 fps).
Há ainda a disponibilidade de utilização de Unidade de Processamento
Gráfico (GPU) de alto desempenho, provenientes do grande avanço ocorrido nesta área,
que foi impulsionado pelos consoles destinados ao entretenimento (videogames). Estas
unidades alcançam altos índices de interação de polígonos por unidade de tempo, da
ordem de 150 millhões de polígonos por segundo na unidade desenvolvida pela Nvidia
[Nvidia, 2004] para o console Microsoft XBox [Microsoft, 2004].
177
5.3.2.1 Classificação de Plataformas Disponíveis
O tipo de plataforma SBC pode ser encontrado com facilidade no mercado, a
custos acessíveis e em diferentes faixas de performance:
• Low performance: destinados a aplicações restritas com IHM (Interface
Homem-Máquina) e pouco elaboradas (< 50 MIPS);
• Mid-Low e Mid performance: usados em aplicações interativas e expansíveis,
IHM com recursos gráficos ( ~ 150 MIPS);
• High-performance: destinados às aplicações High-End, aplicações multimídia de
alta confiabilidade (> 300 MIPS), estes já apresentando um custo mais elevado.
Intuitivamente, há uma predisposição que aponta para a simples escolha
de plataformas de alta performance para aplicações que utilizam Realidade Aumentada
e operações gráficas de modo geral.
No desenvolvimento do projeto DRAI houve uma preocupação no
sentido da "desmistificação" deste processo de escolha, ou seja, tenta-se comprovar a
viabilidade da utilização de plataformas de médio desempenho em equipamentos com
IHM elaboradas e recursos de Realidade Aumentada (RA), obtendo-se equipamentos de
custo e consumo reduzidos e sensível aumento de usabilidade e mobilidade.
Objetiva-se ainda, a criação de um roteiro para a orientação do processo
de concepção e desenvolvimento de novos equipamentos ou planejamento de inclusão
de IHM de RA em equipamentos já existentes.

5.3.2.2 A Plataforma DRAI


No caso específico do projeto DRAI(Figura 5-5), optou-se pela utilização de
uma plataforma de performance média, primando pela otimização de recursos,
disponibilidade no mercado e custo reduzido. Dessa forma, foi utilizada a plataforma
GENE-4310:
• CPU NS GEODE GXLV 300 MHz;
• Chipset NS CS5530;
• GPU Cyrix Media GX (4MB memória compartilhada);
• Controlador de Memória SDRAM (133 MHz);
• Controlador EIDE (UDMA 33);
• Controlador USB (2 portas);
• Watchdog Timer.
178
A plataforma GENE-4310 possui uma CPU (NS Geode) e uma GPU
(CS5530 Cyrix Media GX), que apresentam fatores positivos em: consumo,
performance, compatibilidade e custo melhores que outros da mesma classe. Além
disso, a plataforma já conta com suporte multimídia e saída de vídeo (PAL-M e NTSC).

Figura 5-5 - Exemplos do DRAI em funcionamento

5.3.2.3 Opção por Software Livre


O Sistema Operacional escolhido para o desenvolvimento da aplicação foi o
GNU/Linux, que apresenta os seguintes benefícios:
• Aperfeiçoamento e adequação de aplicativos utilizados no desenvolvimento,
devido ao acesso a seu respectivo código fonte;
• Colaboração de diversas comunidades para a implantação de modificações nos
aplicativos utilizados;
• Troca irrestrita de Informações entre pesquisadores e outras equipes de pesquisa
envolvidas em trabalhos semelhantes;
• Custo de Licenças ou Royalties de Software nulos.

A distribuição do Sistema Operacional utilizada no desenvolvimento foi


a Gwynnix [GwynniX, 2004], também resultado de um processo de customização de um
conjunto de aplicações já existentes. A Gwynnix foi desenvolvida a partir de uma
distribuição Debian GNU/Linux Sarge [Sarge, 2004] e utiliza recursos de ROMFS e
compactação para preservar a integridade do sistema em aplicações dedicadas, além de
reduzir a quantidade de memória necessária para o seu armazenamento.
179
Às vantagens técnicas imediatas, obtidas com a utilização de Software
Livre, somam-se ainda resultados mais consistentes a médio e longo prazo, tanto para a
comunidade Científica quanto para os usuários, o público em geral, que usufruem os
reflexos da tecnologia em equipamentos presentes no cotidiano.

5.3.3 Arquitetura
A arquitetura proposta para o DRAI (Figura 5-6) foi projetada para suportar alta
interatividade para usuários leigos, da mesma forma como é feito com os consoles de
videogames, suportando a inserção de novos aplicativos e a interação com novos
periféricos, que expandem não só a interface com o próprio usuário, mas também a
forma de aplicação para a qual ele foi concebido, atingindo o grau de portabilidade
encontrado hoje nos computadores pessoais.

Figura 5-6. Características da arquitetura DRAI

Expande-se assim a sua gama de finalidades, indo desde console


interativo para execução de cenas 3D até uma base para a implantação de uma rede
Pública de Serviços Interativos em redes de banda larga, incluindo: seleção de conteúdo,
E-commerce, interação entre usuários, entre outros.

Sistema Residente e suas Características


O sistema residente do DRAI possui uma configuração semelhante àquela
encontrada em Desktops, sendo constituído pela associação de software aplicativos,
bibliotecas, Device Drivers e o Kernel.
Para otimizar a utilização de memória não-volátil (File System), utilizou-
se um recurso interno do kernel Linux denominado CLOOP, constituído por um
180
componente de descompactação "on the fly" e uma imagem binária compactada do
sistema customizado.
Isto possibilita a redução de memória destinada para o sistema residente
em aproximadamente 70 % e ainda garante a integridade de todos os componentes, uma
vez que o Sistema de Arquivos tem somente propriedade de leitura ("Read Only
FIleSystem") [Gwyddion, 2004].
Ao ser ligado, o equipamento recupera todas as configurações de
periféricos inseridas no momento de sua concepção, de maneira semelhante aos
consoles de videogames. Esta característica facilita a sua utilização, uma vez que
elimina grandes fontes de perda de funcionalidade ou incompatibilidade de periféricos.
A Arquitetura apresenta os seguintes componentes:
• USB Camera ov518 OmniVision:
o Linux Device Driver ov511+ versão 2.27 (http://alpha.dyndns.org/ov511/);
o Interface de Captura de Video Padrão para Sistemas GNU/Linux, Video for
Linux (http://www.exploits.org/v4l/);
o Formato Imagem YUV420P.
• Interface de Saída de Vídeo Composto Cyrix Media GX:
o XFREE86-4.3.0 distribuído em Debian GNU/Linux Sarge
(http://www.xfree86.org/);
o Driver de Vídeo "nsc" específico para National Semiconductor Cyrix Media
GX;
o Resolução de 640x480 pixels e Definição de cor de 16 bits.
• Interface de Áudio SoundBlaster Compatível:
o Linux Device Driver específico;
• Codec 16 bits de alta definição.
• Aplicativo Gerenciador “DRAI-MGR”:
o Componente de software que identifica e gerencia a inclusão e execução de
novas mídias contendo novos aplicativos;
o A mídia adotada para inclusão de novos aplicativos é a plataforma
SD/MMC, caracterizada pela utilização de cartões portáteis e robustos
baseados em memória Flash, com capacidade variando de 16 Mbytes até 1
Gbytes;
o Os aplicativos serão transferidos já em formato binário específico para a
arquitetura, juntamente com versão específica do ARToolKit;
181
o Ferramentas Desktop serão aprimoradas especificamente para o
desenvolvimento de aplicações DRAI.

5.3.4 Análise de Desempenho


Na documentação da ferramenta ARToolKit, a única recomendação feita com
relação à performance é:
“The computer should have at least a 500 Mhz processor and some form
of graphics accelerator card.” [Kato, 2003]
Entre as plataformas dedicadas, SBCs ou PDA, geralmente não se
encontram equipamentos com tais requisitos recomendados, uma vez que a performance
passa e ser fator limitante quando relacionada às dimensões e consumo do equipamento.
Assim, para adaptar o ARToolKit a equipamentos dedicados encontrados
no mercado, fez-se uma avaliação de cada componente da ferramenta, em busca de
otimizações representativas no desempenho da aplicação. O diagrama de funcionamento
da ferramenta ARTooKit, representado pela Figura 5-7, mostra o bloco responsável pela
inserção da imagem real (capturada pela câmera) ao ambiente virtual, onde foram
identificadas as seguintes etapas:
1. Quadro atual é visualizado como textura de fundo em janela OpenGL [OpenGL,
2004];
2. O marcador é identificado por Threshold [Kato, 2003];
3. Executa-se a transformação de coordenadas para definir posição 3D do marcador
[Kato, 2003];
4. Objeto Virtual 3D correspondente é inserido na posição do marcador via
OpenGL Solid.
Sabendo que a GPU Cyrix Media GX não conta com "set" dedicado para
operações OpenGL e a CPU Geode não apresenta bom desempenho em operações com
ponto flutuante, concluímos que os etapas 1 e 4 são os maiores responsáveis pela queda
de desempenho de aplicações ARToolKit nesta plataforma.
Baseando-se na suposição anterior, serão então identificados todos os
fatores limitantes de desempenho no Hardware utilizado no sistema, objetivando
encontrar também soluções de otimização para estes itens.
182

Figura 5-7 - Componentes funcionais do ARToolKit

O desempenho de uma aplicação simples, utilizada como testbed do


trabalho, reconhecendo apenas um padrão de imagem e construindo o objeto virtual
tridimensional via OpenGL, apresenta uma taxa de aproximadamente 15 quadros por
segundo em equipamentos Desktop comuns e não sofre variações sensíveis, mesmo
com relativa diferença de desempenho local.
Os resultados apresentados no Gráfico da Figura 5-8 sugerem a
existência de um limite superior de performance, imposto por outras características que
não o desempenho da própria CPU, mas, como no caso, o desempenho da câmera.
Aprofundando-se mais no Gráfico 1, percebe-se que a diferença clara de
desempenho existente entre a CPU Celeron 1600 e a XP2000 não implica em uma
diferença sensível no desempenho da aplicação ARToolKit, evidenciando um
excedente de recursos que pode, e deve, ser interpretado seguindo a metodologia de
aperfeiçoamento de ambientes dedicados, como "desperdício" de capacidade.
Observa-se que o fato anterior aponta para a existência de um coeficiente
de desempenho da CPU necessário para sustentar determinada taxa de visualização
(quadros por segundo). Este coeficiente pode ser estimado, e assim orientar todo o
processo de otimização, sugerindo limites superiores de desempenho para a aplicação
final. No caso das duas plataformas utilizadas, o desempenho da CPU necessário para
sustentar o desempenho máximo possível da Aplicação (limitado pela câmera) é muito
menor que o oferecido.
183
Testou-se ainda a variação de desempenho utilizando os dois possíveis
métodos de visualização de imagem no ARToolKit: "Rasterização" e "Texturização".
A Rasterização consiste basicamente da amostragem dos pixels
proveniente da imagem real adquirida pela câmera, já o processo de Texturização
consiste da projeção da imagem em um plano determinado, envolvendo cálculos de
projeção tridimensional.

Figura 5-8 - Desempenho em Desktops


A Rasterização é um processo originalmente mais rápido se comparado à
Texturização, principalmente quando não há "set" OpenGL disponível na GPU; assim o
desempenho da aplicação acaba dependendo unicamente do desempenho da Unidade de
Ponto-Flutuante (FPU) da CPU, que no caso do Geode é bem reduzido devido a
limitações de quantidade de memória Cache e consumo.
Ainda baseando-se na proposta inicial de buscar as otimizações mais
relevantes quanto ao desempenho do software ARToolKit, verificou-se a possibilidade
de substituir o processo de "Texturização" da imagem real no fundo do ambiente por um
processo mais simples, como a "Rasterização" da imagem, ou mesmo a eliminação
deste recurso, resultando em uma espécie de filtro das imagens reais. Os resultados são
apresentados a seguir, na Figura 5-9 –Grático: Resultados das Otimizações.
184

Figura 5-9 –Grático: Resultados das Otimizações

Em aplicações simples de Realidade Aumentada, praticamente não se


percebe os efeitos da troca do processo de "texturização" pelo de "rasterização": pelo
contrário, quando isto é realizado, a imagem se mostra mais definida, além de um
acréscimo de praticamente 100 % no desempenho final; já a ausência de imagem pode
ser utilizada somente em alguns tipos de aplicação, como nas quais o propósito é
somente a utilização da interface para manipular objetos no mundo virtual, ou ainda
onde é usada como ferramenta de rastreamento de movimento ou padrões (símbolos),
quando a correlação natural dos padrões com o mundo real não é importante ou muitas
vezes até indesejada.
Nas aplicações See-Through, por exemplo, a mistura do mundo virtual e
do mundo real é feita “mecanicamente”, por meio de espelhos, ou automaticamente,
através de equipamentos HMD (Head Monted Devices). Desta forma, não há a
necessidade de apresentar, nem um fundo virtual nem a imagem real. Neste tipo de
aplicação, o DRAI ou outros equipamentos dedicados de desempenho aquém do
exigido, podem ser utilizados com sucesso, além de apresentar outras vantagens
relacionadas à mobilidade, tais como: pequenas dimensões, baixo peso e baixo
consumo.
Há o intercâmbio de informações entre outras frentes de pesquisa na
mesma linha do DRAI, tais como: plataformas de celulares, plataforma de PDAs
185
associadas a outras funcionalidades, tais como posicionamento por GPS e rastreamento
indoor por TAGs RFID.

5.4 Conclusões
O conceito de realidade aumentada foi discutido num contexto mais amplo,
incluindo multimídia, realidade virtual e realidade misturada, analisando-se rapidamente
alguns requisitos de hardware para suportar essas aplicações. O Projeto DRAI foi usado
como ambiente para a análise do hardware de aplicações de realidade aumentada.
Para melhorar o desempenho e flexibilidade do Sistema DRAI, algumas
otimizações e ajustes foram sugeridos, além de terem sido mostrados testes de várias
possibilidades de renderização, incluindo técnicas de "raster", textura e fundos virtuais
para representar o ambiente real (espaço de trabalho).
A técnica de fundos virtuais, apesar de eliminar o sinal de vídeo,
continuou propiciando a mesma sensação de presença, com a vantagem de eliminar
situações indesejáveis em alguns casos, como flutuação de iluminação e poluição visual,
ressaltando somente o foco de interesse do trabalho.
A avaliação de desempenho mostrou novas alternativas para otimizar o
processo de visualização, bem como novos caminhos no sentido de viabilizar o uso
deste tipo de recurso em aplicações presentes no cotidiano, com o uso de equipamentos
comumente encontrados no mercado.
A partir dos dados provenientes deste trabalho, será desenvolvida uma
pesquisa mais detalhada, seguida por experimentos mais profundos, com o objetivo de
implementar estas soluções em situações reais. Além disso, está-se produzindo material
consistente, somado ao de outros grupos de pesquisa no contexto mundial, como o
OpenTrack [OpenTrack, 2001], usufruindo das possibilidades oferecidas pela adoção de
Software Livre como base do desenvolvimento.

5.5 Referências deste capítulo


ARToolKit (2004) Software disponível para download em:
http://www.hitl.washington.edu/research/shared_space, 2004.
Azuma, R. et al. (2001) “Recent Advances in Augmented Reality.” IEEE Computer
Graphics and Applications, v .21, n.6, p. 34-47.
Buford, J.F.K. (1994) Multimedia Systems, Addison-Wesley, 1994.
186
Burdea, G., Coiffet,P. (1994) Virtual RealityTechnology", John Wiley & Sons, 1994.
Galana, S.C., Silva, R.R.P.C.L., Kirner, C. (2004) “Autoria Colaborativa de Mundos
Virtuais Educacionais com Realidade Misturada” Anais do 1o Workshop de
Realidade Aumentada, Piracicaba, SP, maio de 2004, p. 17-20.
GNU/Linux (2004) Sistema Operacional Livre com ampla comunidade de usuários e
desenvolvedores, http://www.linux.org, 2004.
Gwyddion (2004) http://www.gwyddion.com. 2004.
Gwynnix (2004) Distribuição GNU/Linux modificada para ambientes dedicados,
http://gwynnix.gwyddion.com, 2004.
Kato, H.; Billinghurst M.; Poupyrev, I. (2003) ARToolKit version 2.33 Manual, Nov.
2003.
Kirner, C., Pinho, M.S. (1996) “Introdução a Realidade Virtual”. Mini-Curso, JAI/SBC,
Recife, PE, 1996.
Kirner, C. (2004) “Mãos Colaborativas em Ambientes de Realidade Misturada” Anais
do 1o Workshop de Realidade Aumentada, Piracicaba, SP, maio de 2004, p. 1-4.
Marshall, D. (2001) Disponível em:
http://www.cs.cf.ac.uk/Dave/multimedia/node10.html, 2001.
Microsoft (2004) Xbox: Console de alto desempenho para aplicações multimídia, 2004.
Milgram, P. et. al. (1994) “Augmented Reality: A Class of Displays on the Reality-
Virtuality Continuum. “ Telemanipulator and Telepresence Technologies, SPIE,
V.2351, 1994, p. 282-292.
Nvidia (2004) Fabricante de equipamentos de vídeo para PCs, http://www.nvidia.com,
2004.
Prince, S. et. al. (2002) "3D Live: Real Time Captured Content for Mixed Reality"
Proc. of the IEEE/ACM International Symposium on Mixed and Augmented
Reality, ISMAR'02, IEEE/ACM, p. 7-13.
Olsen, G. (1997) Getting Started in Multimedia Design, North Light Books, 1997.
OpenGL (2004) Biblioteca para manuseio de elementos gráficos 2D e 3D, 2004.
OpenTrack (2001) OpenTracker is a free flexible XML based tracking
framework, http://studierstube.org/opentracker/, 2001.
Providelo, C. et al. (2004) “Ambiente Dedicado para AplicaçõesEducacionais com
Realidade Misturada” Proc. of VII Symposium on Virtual Reality, SP, outubro de
2004.
187
Sarge (2004) Debian GNU/Linux Sarge, versão atual da Distribuição de GNU/Linux
Debian, http://www.debian.org, 2004.
Weiser, M. (1991) The computer for the twenty-first century. Scientific American, p.
94-104, September 1991.
Santin, R. et al. (2004) “Ações interativas em Ambientes de Realidade Aumentada com
ARToolKit” Proc. of VII Symposium on Virtual Reality, SP, outubro de 2004.
Sherman, W.R., Craig, A.B. (2003) Understanding Virtual Reality, Morgan kaufmann,
2003.
Siscoutto, R. et al. (2004) “Augmented Virtuality Tele-conferencing", Proc. of VII
Symposium on Virtual Reality, SP, outubro de 2004.
Tiffin, J., Terashima, N. ed. (2001) Hyper-reality: Paradigm for the Third Millennium,
Routledge, 2001.
Vince, J. (1995) Virtual Reality Systems, Addison-Wesley, 1995.
Vince, J. (2004) Introduction to Virtual Reality, Springer-Verlag, 2nd edition,
2004.
188

6 ARToolKit – Aspectos Técnicos e Aplicações


Educacionais

1
Luís Augusto Consularo, 1Nivaldi Calonego Júnior Carlos A. Dainese1, Tania R.
Garbin1, Claudio Kirner1, Jorge Trindade2 , Carlos Fiolhais2

1
Programa de Pós Graduação em Ciência da Computação
Faculdade de Ciências Matemáticas da Natureza e Tecnologia da Informação
Universidade Metodista de Piracicaba (UNIMEP)
Rodovia do Açucar, Km 156 – 13.400-911 - Piracicaba – SP
2
Centro de Física Computacional - CFC, Universidade de Coimbra - UC, Portugal
{cdainese, ckirner, trgarbin}@unimep.br,
{alberto, tcarlos}@teor.fis.uc.pt

6.1 Introdução
Este documento apresenta o pacote ARToolKit, enfatizando a instalação e o uso.
O ARToolKit é uma biblioteca em linguagem C que permite aos programadores
desenvolver aplicações de Realidade Aumentada. Realidade Aumentada (RA) é a
sobreposição de imagens virtuais de computação gráfica sobre cenas do mundo real.
Esse modelo de interface tem mostrado potencial para muitas aplicações em pesquisa
industrial e acadêmica.
Nos tutoriais do ARToolKit [KATO 2002], os autores encorajam os leitores a
enviar comentários e questões sobre o ARToolKit e relatos de erros e falhas para
Hirokazu Kato (kato@sys.im.hiroshima-cu.ac.jp) ou para Mark Billinghurst
(grof@hitl.washington.edu). Há também uma lista de discussões que é usada para
difundir notícias sobre novas versões do ARToolKit, correções e aplicações que a
comunidade que trabalha com ARToolKit está desenvolvendo. Para assinar esta lista,
envie uma mensagem para majordomo@hitl.washington.edu com as palavras "subscribe
artoolkit" no corpo da mensagem. Depois disso, qualquer mensagem que você enviar
para artoolkit@hitl.washington.edu será enviada a todos os membros desta lista de
discussões. As listas são muito úteis para encontrar dicas sobre o uso das funções, sobre
189
equipamentos que estão sendo utilizados pelos desenvolvedores †,‡ e ainda sobre novas
versões e revisões do pacote.
Atualmente, o ARToolKit executa nas plataformas SGI Irix§, PC Linux**, PC
Windows 95/98/NT/2000/XP†† e Mac OS X‡‡. Há versões separadas para cada uma
destas plataformas. A funcionalidade de cada versão do kit é a mesma, mas o
desempenho pode variar conforme as diferentes configurações de hardware. Na
plataforma SGI, por exemplo, o ARToolkit foi testado apenas para computadores SGI
O2, contudo deve também executar nos computadores SGI atuais que contém com
entradas de vídeo.
A versão atual do ARToolKit oferece suporte para realidade aumentada com
visão direta por vídeo ou visão direta óptica. A RA por visão direta por vídeo é aquela
cujas imagens virtuais são sobrepostas às imagens de vídeo ao vivo adquiridas do
mundo real. A outra opção é a RA por visão direta óptica, na qual modelos de
computação gráfica (os objetos virtuais) são sobrepostos diretamente às imagens do
mundo real percebidas pelo sujeito. A RA por visão direta requer um dispositivo HMD
(Head Mounted Display) e exige também um procedimento de calibração da câmera que
adquire imagens do mundo real [KATO 2002; KATO & BILLINGHURST 1999].
Estes procedimentos podem variar entre algo mais simples (que será mostrado na seção
6.3), quando a visão direta é por vídeo, ou mais complexo quando por visão direta
óptica.
Uma das partes mais trabalhosas no desenvolvimento de uma aplicação em RA é
calcular precisamente o ponto de vista do usuário em tempo-real para que imagens
virtuais sejam alinhadas com precisão às imagens dos objetos do mundo real
[HARTLEY & ZISSERMAN 2003]. O ARToolKit usa técnicas de visão computacional
para calcular a posição no espaço real da câmera e sua orientação em relação aos cartões
marcadores, permitindo ao programador sobrepor objetos virtuais aos cartões. O pacote
inclui bibliotecas de rastreamento e disponibiliza o código fonte completo, tornando
possível o transporte do código para diversas plataformas ou adaptá-los para resolver as


http://onyx.sys.im.hiroshima-cu.ac.jp/people/kato/

http://www.hitl.washington.edu/people/grof/
§
http://www.sgi.com/products/software/irix/
**
http://www.linux.org/
††
http://www.microsoft.com/windows
‡‡
http://www.apple.com/macosx/
190
especificidades de suas aplicações. Várias aplicações simples são fornecidas com o
ARToolKit para que programadores comecem rapidamente a desenvolver suas
aplicações. Além disso, o ARToolKit é livre para uso em aplicações não-comerciais e é
distribuído com código aberto sob licença GPL. Os interessados no uso do ARToolKit
para o desenvolvimento de aplicações comerciais devem entrar em contato com
Hirokazu Kato† ou com Mark Billinghurst‡.
O ARToolKit é uma novidade em termos de modelo e programação de
interfaces, em que alguns tutoriais apresentados pelos autores do ARToolKit e outros
interessados [BERRE et al. 2002; KATO, BILLINGHURST & POUPYREV 2000; KE
2000] são as principais fontes de informação. Assim, a elaboração de um texto que trata
de mostrar os elementos necessários ao desenvolvimento desse tipo de aplicação exige
uma organização de texto que é o resultado da compilação desses tutoriais e de
experimentações dos próprios autores deste texto, e está distribuído em cinco sessões.
A primeira apresenta a instalação do ARToolKit. A segunda trata da
programação de aplicações com o ARToolKit, explorando os exemplos mais simples de
execução, que são distribuídos com o Kit, e detalhando os passos do desenvolvimento
de uma aplicação típica. A terceira sessão apresenta o procedimento necessário à
calibração de câmeras, usando os utilitários disponíveis no ARToolKit. Os utilitários
podem ser usados isoladamente, pois seus resultados são armazenados em arquivos que
podem ser lidos por outras aplicações. A quarta sessão descreve as bibliotecas,
enfocando as funções mais importantes utilizadas para implementar aplicações com o
ARToolKit em computadores PC-compatíveis com Windows. A quinta e última sessão
discute algumas limitações deste tipo de implementação de RA e mostra também
algumas perspectivas para esta biblioteca.

6.2 Versões e Instalação


Há diversas versões do ARToolKit disponíveis para desenvolvimento. De uma
certa forma, estas versões acompanharam a evolução do tratamento que os sistemas
operacionais davam aos dispositivos de vídeo. Atualmente, há versões para o Windows,
Linux, SGI e até para o MacOS X. A versão 1.0 disponibilizou uma versão para o
Windows e outra para SGI. Para arquiteturas de 16 bits do Windows, o driver de vídeo
era o VFW (Video for Windows) [NOMAD ELECTRONICS.COM 2004]. A versão
para SGI foi a original do desenvolvimento, principalmente pelo desempenho oferecido.
191
A versão 2.11 foi a primeira a incluir uma distribuição para Linux. Já as revisões
2.33 e 2.40 aperfeiçoaram as versões Linux e SGI, mas não incluíram estes
aperfeiçoamentos para Windows.
A revisão 2.43 foi a primeira a se aproveitar da nova arquitetura de drivers do
Windows, a WDM (Windows Driver Model) [MICROSOFT 2002; NOMAD
ELECTRONICS.COM 2004], que utiliza efetivamente a arquitetura 32 bits dos
sistemas baseados no Windows NT, tal como a versão XP do Windows. Nesta revisão,
este suporte WDM era oferecido por um SDK (Software Development Kit) da Microsoft
que disponibilizava funções de visão computacional, o Vision SDK [MICROSOFT
2000]. Esta distribuição inovou ainda por adicionar um suporte à adição de modelos 3D
por meio de um grafo de cena VRML [CAREY & BELL 1997]. Embora bastante
limitado, o grafo de cena viabilizou a implementação de aplicações simples de
Realidade Aumentada.
A versão 2.52 é exclusiva para o Windows. Inclui suporte ao VRML com
melhorias na iluminação dos objetos do mundo virtual. Há também o suporte para o
Vision SDK e ao DirectShow [MICROSOFT 2004], que é a inovação do software para
uso de uma biblioteca gráfica que usa mais efetivamente os recursos gráficos no
Windows.
A versão 2.60 é um aperfeiçoamento das versões para Linux que incluem o
suporte às interfaces de câmeras Firewire§§ (IEEE 1394) [APPLE 2004]. Este tipo de
interface oferece largura de banda muito maior (próximo a 500 Mbps) que câmeras com
E/S USB (entre 40 Mbps – 400 Mbps). Além disso, alguns modelos de câmeras
Firewire tratam o sincronismo de aquisições de quadros de vídeo para aplicações com
rastreamento.
A revisão 2.61 estende o ARToolKit ao Mac OS X. Esta revisão permite usar
também a Firewire no próprio Mac, máquina a qual esta interface é nativa.
A revisão 2.65 é a que Thomas Pintaric*** denominou "não-oficial". É um
desenvolvimento que está buscando oferecer o suporte VRML ao DirectShow, já que
até agora este suporte só está disponível para OpenGL [SGI 2003], usando a biblioteca
LibVRML97 [MORLEY 2000] (atualmente OpenVRML [OPENVRML.ORG 2003]).
A iniciativa deve permitir ainda que se conecte câmeras Firewire no Windows para que

§§
http://www.ptgrey.com/
***
http://www.ims.tuwien.ac.at/~thomas/artoolkit.php
192
a aquisição das imagens seja mais rápida, possibilitando o aumento da taxa de
processamento dos quadros. O autor alega que o suporte ao DirectShow tem um
desempenho em torno de 3 vezes superior ao desempenho das versões com OpenGL.
A versão 2.68 é a mais recente e tem versões disponíveis para Windows e para
Linux/SGI/MacOSX. Ainda não oferece suporte ao VRML e está disponível em
http://www.eden.net.nz/phil/develop/artoolkit/. Esta versão corrige alguns problemas da
versão 2.65, que invertia as coordenadas de altura nas imagens adquiridas das câmeras.
Ainda há implementações independentes do ARToolKit para Matlab
(http://mixedreality.nus.edu.sg/ software.htm), uma outra que conecta as bibliotecas do
ARToolKit com Java, o JARToolKit††† [GEIGER et al. 2002], e também uma iniciativa
de software para aplicações de RA para PDAs da linha iPaq‡‡‡ [WAGNER &
SCHMALSTIEG 2003].
A Erro! A origem da referência não foi encontrada. ilustra um diagrama
resumindo as versões convencionais disponíveis do ARToolKit. As versões PC, SGI e
Linux do ARToolKit estão disponíveis gratuitamente em
http://www.hitl.washington.edu/research/shared_space/download/.
Este tutorial descreve a instalação da versão 2.65 com VRML, que está
disponível em http://www.hitl.washington.edu/artoolkit/download.htm.

6.2.1 Instalação no PC-Windows


O ARToolKit para o PC-Windows é distribuído em um único arquivo
comprimido, no caso da versão 2.65 como ARToolKit2.65.zip ou como
ARToolKit2.65VRML.zip. Uma vez que esta cópia de arquivo esteja no diretório no
qual você queira que o ARToolkit fique, descomprima-o usando o utilitário de
descompressão de sua preferência (WinZip, Rar, PKZip, etc..).
O utilitário de descompressão deve criar a estrutura de diretórios ilustrada na
Figura 6-2. O diretório bin contém alguns programas que podem ser executados
conforme descreve a próxima seção. Os códigos-fonte destes programas ficam no
diretório examples. As bibliotecas do ARToolKit ficam no diretório lib e o código-
fonte completo para as bibliotecas, no diretório lib/SRC.

†††
http://www.c-lab.de/jartoolkit
‡‡‡
http://studierstube.org/handheld_ar
193
Esta versão do ARToolKit foi compilada e testada em PCs executando Windows
XP com instalação das câmeras QuickCam Express da Logitech§§§ e Webcam 3 modelo
da Creative Labs**** conectadas a portas USB†††† versão 1.1 (40 Mbps). O ARToolKit
usa ou o Vision SDK (existe uma distribuição do ARToolKit específica para o Vision
SDK) ou o DirectX 9‡‡‡‡ da Microsoft (segundo a página do ARToolKit, da versão 8 em
diante) para que não haja motivo de incompatibilidade entre câmeras e placas de
aquisição de vídeo que sejam suportados pelo Vision SDK, Video for Windows ou pelo
WDM (Windows Driver Model) da Microsoft. Os códigos-fonte foram compilados com
o MS Visual C++ 6.0 e o MS Visual C++ 7.0 (ambos com instalação do Visual
Studio§§§§).

§§§

http://www.logitech.com/index.cfm/support/products/details/US/EN,CRID=1795,CONTENTID=6041
****
http://www.creative.com/products/product.asp?prodid=15
††††
http://www.usb.org/home
‡‡‡‡
http://www.microsoft.com/directx
§§§§
http://msdn.microsoft.com/vstudio
194
Figura 6-1 - Versões do ARToolKit.
Os programas de exemplo incluídos com o ARToolKit, todos, utilizam a
biblioteca GLUT de interface com o OpenGL. Portanto, para compilar estes programas,
deve estar instalada a versão 3.6 ou alguma versão mais atualizada. As bibliotecas
GLUT estão disponíveis em http://opengl.org/resources/libraries/glut.html. Para
economizar tempo, copie os diretórios do OpenGL nos diretórios do ARToolKit. O
diretório GL com os protótipos (arquivos com extensão .h) do OpenGL no diretório
include do ARToolKit, o arquivo de biblioteca glut32.lib no diretório lib e o
glut32.dll no diretório bin. Se existe uma instalação das bibliotecas em outro
diretório, com os caminhos todos definidos na configuração de projetos do Visual C,
então isto não é necessário. Para definir estes caminhos do Visual C, é necessário abrir o
arquivo do workspace de sua aplicação, selecionar no projeto de sua aplicação o item
Project e, então, a opção Settings. Surgirá uma caixa de diálogo com várias
configurações. Você precisará das opções C/C++ e Link. Na opção C/C++ você poderá
adicionar novos diretórios de protótipos selecionando a opção Preprocessor em
Category. Na caixa de texto Additional include directories, inclua o diretório de sua
preferência. Na opção Link, selecione Input em Category. Na caixa de texto Additional
library path, inclua os diretórios de bibliotecas de sua preferência, isto é, aqueles nos
quais você incluiu os arquivos com extensão .lib.
195

Figura 6-2 – Estrutura de diretórios depois de instalado o


ARToolKit 2.65 com VRML

6.2.2 Programação de Aplicações


A programação de aplicações no ARToolKit, em sua distribuição original, não
disponibiliza qualquer ferramenta de autoria. Portanto, é necessário conhecer aspectos
de configuração do hardware no qual a aplicação executará, bem como o fluxo de
controle de uma aplicação típica. O fluxo de controle disponibilizado pelo ARToolKit é
bastante simples e inclui funções para leitura de eventos de teclado e de mouse,
inicializações e finalizações de dispositivos de vídeo além, é claro, do próprio laço
principal.
Uma vez instalado corretamente, o ARToolKit inclui um programa-exemplo
denominado simple.exe, que pode ser localizado no diretório bin, e executado
para testar se o ARToolKit está funcionando. É necessário imprimir os marcadores de
referência, que estão contidos no diretório patterns, para testar o programa. Estes
marcadores estão nos arquivos pattSample1.pdf, pattSample2.pdf,
pattKanji.pdf e pattHiro.pdf. O desempenho será melhor desempenho se os
marcadores forem fixados (com cola, por exemplo) em uma superfície plana e rígida.
196
As próximas seções descrevem o hardware necessário para executar o
ARToolKit e depois mostram como executar os exemplos do ARToolKit em um PC-
Windows. Em qualquer uma das instalações das versões anteriores, a saída do programa
simple.exe deve ter o mesmo comportamento.

6.2.3 Hardware necessário


Os requisitos básicos de hardware para desenvolver e executar aplicações do
ARToolKit são: uma câmera de vídeo e uma interface ou um dispositivo de aquisição de
vídeo com seus respectivos drivers. Em um PC-Windows (95/98/2000/XP) a captura de
vídeo pode se dar por uma câmera USB, por um dispositivo de aquisição de vídeo ou
por placas gráficas com alguma entrada de vídeo. O dispositivo escolhido exige que se
instale drivers VfW ou WDM fornecidos pelo próprio fabricante do dispositivo.

6.2.4 A saída do simple.exe


Depois de invocar o simple.exe, aparecerá na tela uma janela de vídeo.
Quando apontar a câmera para cada um dos marcadores aparecerá uma cena. Por
exemplo, quando a câmera captura a imagem do marcador “Hiro” (Figura 6a), é
apresentada na tela do computador a imagem de um cubo azul sobre esse marcador,
conforme ilustra a Figura 5. Conforme os marcadores reais se moverem, os objetos
virtuais devem se mover e aparecer exatamente alinhados com os marcadores reais. As
figuras a seguir mostram os passos da execução do programa, antes que possam ser
vistas a imagem do vídeo e o objeto virtual sobre ela.
A primeira ação que pode ser requisitada ao usuário é uma caixa de diálogo
(veja Figura 6-3) para configurar a câmera (se foi configurado para que isso aconteça).
197

Figura 6-3 – Janela de propriedades da câmera. Os elementos configuráveis


desta
caixa de diálogo depende da câmera que foi instalada.
Clicando OK nesta caixa de diálogo, você verá uma janela para entrada de
comandos mostrando as saídas textuais do programa (veja Figura 6-4).

Figura 6-4 – Saída em janela de texto do programa simple.exe, mostrando os


parâmetros de exibição e de calibração da câmera.
Finalmente, aparecerá a janela de visualização da cena com um cubo sobre um
marcador (veja a Figura 6-5) .
198

Figura 6-5 – Resultado da execução do arquivo simple.exe, mostrando um cubo


virtual sobre o marcador real.
Para que o objeto virtual apareça, toda a borda preta do quadrado que envolve o
desenho padrão deve estar enquadrada pela imagem da câmera, assim como o próprio
desenho padrão. Se as imagens virtuais não aparecerem ou piscarem aparecendo e
desaparecendo da imagem, é por causa das condições de iluminação do ambiente. Isto
pode ser corrigido alterando o valor do limiar usado pelas rotinas de processamento de
imagens. Se você pressionar a tecla <t> no teclado, será pedido a você que entre com o
valor de um novo limiar. Este novo limiar pode estar entre 0 e 255; o normal é 100.
Pressionando a tecla <esc> sai do programa e mostra a informação da taxa de
atualização em quadros por segundo (frame rate). Esta informação é útil par testar o
desempenho de sua configuração. Uma taxa pequena (em torno de 10 quadros/segundo)
pode ser inviável para sua aplicação. OBS: Se o programa sair anormalmente ou por
alguma outra maneira que não seja pressionando <esc>, recomenda-se que você
reinicie seu computador antes de usar novamente alguma aplicação de vídeo.
O programa simple mostra como uma aplicação baseada no software
ARToolKit é capaz de calcular o ponto de vista da câmera em tempo real e usar esta
informação para sobrepor precisamente o objeto do mundo real com imagens de objetos
virtuais.

6.2.5 A saída do simpleVRML.exe


Além do simple.exe, há outro programa para testar sua configuração, o
simpleVRML.exe. Este programa permite testar se a biblioteca VRML está
funcionando e também se os parâmetros de câmera, marcadores e objetos virtuais estão
199
de acordo com suas necessidades. Este programa só está disponível nas distribuições
que integram a biblioteca LibVRML97 ao ARToolKit.
O programa simpleVRML usa arquivos de configuração como o arquivo
camara_para.dat, que contém os parâmetros da câmera; bem como o
vrml_data.dat que associa os objetos virtuais com os padrões dos marcadores.
Estes arquivos devem estar no diretório bin/Data. O arquivo vrml_data.dat,
no localizado no diretório bin/Wrl, armazena referências para arquivos VRML e
para os mapas de bits (bitmaps), que ficam no diretório bin/Data. Os conteúdos
desses arquivos pode ser verificados abrindo-se o arquivo vrml_data.dat em um
editor de texto qualquer. O arquivo que vem com a distribuição 2.65 do ARToolKit e
que acompanha este tutorial tem o conteúdo mostrado no Código 1.

#the number of patterns to be recognized


2

#pattern 1
VRML Wrl/bud_B.dat
Data/patt.hiro
80.0
0.0 0.0

#pattern 2
VRML Wrl/snoman.dat
Data/patt.kanji
80.0
0.0 0.0

Código 1 – Código contido no arquivo vrml_data.dat, que descreve uma


aplicação.
Neste caso, são dois padrões: um com a palavra “Hiro” (que são as iniciais do
autor Hirokazu, que está no arquivo Data/patt.hiro) escrita no quadrado e outra
com um ideograma kanji (Data/patt.kanji). O padrão “patt.hiro” é uma
referência ao objeto VRML que está descrito no arquivo Wrl/bud_B.dat, que é uma
animação de uma abelha sobrevoando uma flor. O padrão kanji referencia o arquivo
Wrl/snoman.dat, que associa código VRML para o desenho de um boneco de neve.
Portanto, os arquivos “.dat” associam as marcas aos arquivos de cena. As duas últimas
linhas de cada padrão são parâmetros que especificam o tamanho com que o objeto deve
aparecer na imagem e o local do centro deste objeto em relação ao centro da placa.
A execução deste programa, assim como no simple.exe, mostrará uma tela
de configuração da câmera e depois uma tela de comandos. Na janela de visualização da
200
cena poderão ser vistos os padrões (veja Figura 6-6a) e seus respectivos objetos (veja
Figura 6-6b).
(a) (b)

Figura 6-6 – Resultado da execução do programa simplevrml.exe: (a)


mostrando apenas a aquisição de vídeo e (b) mostrando um objeto virtual e
animado sobre o marcador.

6.2.6 O funcionamento do ARToolKit


O ARToolKit usa técnicas de visão computacional para calcular o ponto de vista
real da câmera em relação a um marcador no mundo real. Há vários passos ilustrados
nas figuras para mostrar o funcionamento do ARToolKit. O primeiro passo mostra que a
imagem de vídeo capturada, veja Figura 6-7a, é transformada em uma imagem binária
(em P&B) baseada no valor do limiar de intensidade, veja Figura 6-7b. Depois, o
ARToolKit encontra todos os quadrados na imagem binária, muitos dos quais não
correspondem a marcadores de referência. Para cada quadrado, o desenho padrão dentro
dele é capturado e comparado com alguns gabaritos pré-treinados. Se houver alguma
similaridade, então o ARToolKit considera que encontrou um dos marcadores de
referência. O ARToolKit usa então o tamanho conhecido do quadrado e a orientação do
padrão encontrado para calcular a posição real da câmera em relação a posição real do
marcador. Uma matriz 3x4 conterá as coordenadas reais da câmera em relação ao
marcador. Esta matriz é usada para calcular a posição das coordenadas da câmera
virtual. Se as coordenadas virtuais e reais da câmera forem iguais, o modelo de
computação gráfica pode ser desenhado precisamente sobre o marcador real (veja
Figura 6-7c). A API OpenGL é usada para calcular as coordenadas virtuais da câmera e
desenhar as imagens virtuais.
(a) (b)
201

(c)

Figura 6-7 – Resultado da execução do programa simple.exe mostrando (a) a


imagem da cena com um marcador; (b) a imagem limiarizada e (c) o cubo
virtual sobreposto ao marcador.
O diagrama da Figura 6-8 ilustra os passos do processamento de imagens usado
para detectar a geometria do marcador e depois o posicionamento de um objeto virtual
sobre este marcador detectado.

6.2.7 Escrevendo a aplicação


O desenvolvimento de aplicações de RA com o ARToolKit requer duas etapas:
escrever a aplicação e treinar as rotinas de processamento de imagens sobre os
marcadores do mundo real que serão usadas na aplicação.
Para escrever aplicações com o ARToolKit, deve-se seguir os seguintes passos:
Passo 1:
• Inicializar o caminho dos parâmetros de vídeo;
• Ler os arquivos de padrões de marcadores;
• Ler os parâmetros de câmera;
Passo 2:
• Capturar uma quadro da entrada de vídeo;
202
Passo 3:
• Detectar os marcadores e reconhecer os padrões no
quadro capturado da entrada de vídeo;
Passo 4:
• Calcular a transformação da câmera em relação aos
padrões detectados;
Passo 5:
• Desenhar os objetos virtuais nos padrões detectados;
Passo 6:
• Fechar a entrada de vídeo.
Os passos 2 até 5 são repetidos continuamente até que a aplicação termine, já os
passos 1 e 6 são executados, respectivamente, apenas na inicialização e na finalização
da aplicação. Além destes passos, a aplicação pode precisar responder ao mouse, ao
teclado ou a outros eventos específicos da aplicação.
Para mostrar em detalhes como desenvolver uma aplicação, seguiremos cada
passo no código fonte do programa simpleVRML. Este exemplo é encontrado no
diretório examples.

Figura 6-8 – Diagrama descrevendo os passos da detecção dos marcadores e o


posicionamento de objetos virtuais sobre os marcadores detectados na cena.
Traduzido do tutorial dos autores [KATO, BILLINGHURST & POUPYREV 2000].
203
O arquivo que estaremos visualizando é o simpleVRML.c. Este programa
consiste de uma função main e várias funções gráficas. A função principal (main) é
mostrada no Código 2.

main(int argc, char **argv)


{
init();
arVideoCapStart();
argMainLoop(NULL, keyEvent, mainLoop);
}
Código 2 - Função principal de uma aplicação de RA no ARToolKit.
Esta função chama uma outra função de inicialização (init()) que contém o
código para definição do caminho dos parâmetros do dispositivo de vídeo, da leitura dos
parâmetros dos marcadores e da câmera e da janela gráfica. Isto corresponde ao Passo 1.
Depois, a função arVideoCapStart() inicia a captura de imagens de vídeo.
Finalmente, a função argMainLoop é chamada para iniciar o laço do programa
principal, associar a função keyEvent aos eventos do teclado e a função MainLoop
com o laço principal da renderização gráfica. A definição de argMainLoop está
contida no arquivo gsub.c, que pode ser encontrado no diretório lib/SRC/Gl/.
O arquivo simpleVRML.c contém as funções que correspondem aos seis
passos de aplicação acima são mostradas na tabela abaixo. As funções correspondentes
aos passos 2, 3, 4 e 5 são chamadas dentro da função mainLoop. Estas chamadas de
função serão explicadas com mais detalhes no restante da seção.

Passo do ARToolKit Função


1.Inicializa a aplicação init
2.Captura um quadro de vídeo arVideoGetImage
3.Detecta os marcadores arDetectMarker
4.Calcula a transformação da arGetTransMat
câmera
5.Desenha os objetos virtuais draw
6.Fecha o dispositivo de vídeo cleanup
204
6.2.7.1 init()
A função init() é chamada a partir da função principal e é usada para definir
o caminho dos parâmetros para o dispositivo de vídeo e para ler os parâmetros iniciais
da aplicação ARToolKit. Os parâmetros principais para uma aplicação ARToolKit são:
1. os padrões que serão usados para comparar os padrões e encontrar a
correspondência entre o desenho no padrão e um objeto virtual.
2. as características da câmera de vídeo que está sendo usada.
Estes dois parâmetros principais podem ser lidos de arquivos de configuração,
ou fornecidos na linha de comando da aplicação ou ainda definidos em constantes
diretamente no código. O parâmetro default da rotina init para o nome do arquivo de
parâmetros da câmera é Data/camera_para.dat, enquanto o nome default para o
arquivo de objetos é Data/vrml_data. O arquivo que contém os nomes dos padrões
e dos objetos virtuais é lido com a chamada de função do Código 3.

/* carrega os dados do objeto -


marcadores treinados e arquivos de mapas de bits */
if ((object = read_VRMLdata(modelname, &objectnum)) == NULL)
exit(0);
Código 3 – Chamada da função que carrega os padrões a serem reconhecidos.
A função read_VRMLdata obtém todos os padrões treinados, que
correspondem aos nomes dos padrões lidos na biblioteca AR. Antes destes nomes serem
lidos, o dispositivo de vídeo é aberto e é encontrado o tamanho configurado da imagem
de vídeo (veja o Código 4)

/* abre o dispositivo de vídeo */


if (arVideoOpen(vconf) < 0)
exit(0);

/* encontra o tamanho da janela */


if (arVideoInqSize(&xsize, &ysize) < 0)
exit(0);
printf("Image size (x, y) = (%d, %d)\n", xsize, ysize);
Código 4 – Abertura do dispositivo de vídeo e recuperação da imagem de
vídeo.
A variável vconf contém a configuração inicial do vídeo e é definida no topo
do simpleVRML.c. Esta variável é uma cadeia de caracteres e sua configuração deve
seguir uma sintaxe de configuração de vídeo definida pelo ARToolKit. Há um
comentário explicando esta sintaxe e mostrando alguns exemplos. Agora, os parâmetros
da câmera são lidos, como mostra o Código 5.
205

/* configura os parâmetros iniciais da câmera */


if (arParamLoad(cparaname, 1, &wparam) < 0) {
printf("Camera parameter load error!\n");
exit(0);
}
Código 5 – Leitura dos parâmetros da câmera.
Depois, os parâmetros são transformados para o tamanho real da imagem, pois
os parâmetros da câmera mudam de acordo com o tamanho da imagem, mesmo que seja
utilizada a mesma câmera (veja o Código 6).

arParamChangeSize(&wparam, xsize, ysize, &cparam);


Código 6 – Configuração dos parâmetros da câmera.
Os parâmetros da câmera são configurados de acordo com a leitura anterior e
então são mostrados na tela (veja o Código 7). Logo após a janela gráfica é aberta:

arInitCparam( &cparam );
printf("*** Camera Parameter ***\n");
arParamDisp( &cparam );
/* abre a janela grafica */
argInit( &cparam, 1.0, 0, 0, 0, 0 );
/* cparam, zoom, fullflag, xwin, ywin, hmd */
Código 7 – Inicialização dos parâmetros e sua exibição na tela.
Cabem alguns comentários relativos aos parâmetros de argInit. O primeiro
parâmetro é na verdade a estrutura que contém os parâmetros da câmera. O segundo
parâmetro é o zoom, isto é, o quanto se quer aumentar a imagem de aquisição para ser
exibida na tela. Lembre-se que o zoom aumenta o tamanho do pixel. O terceiro
parâmetro é um sinal indicando se a janela gráfica deve cobrir toda a tela (1, neste caso)
ou se deve abrir uma janela sobre a área de trabalho (zero, neste caso). Os outros dois
parâmetros são os tamanhos de eventuais extensões da tela contendo a imagem da
câmera e, finalmente, o último parâmetro indica se a inicialização deve considerar que o
display é um HMD, isto é, um capacete.
A atribuição ao parâmetro arImageProcMode =
AR_IMAGE_PROC_IN_FULL indica ao ARToolKit para processar as imagens com o
tamanho completo e original adquirido da câmera (veja o Código 8). Isto pode tornar o
processamento muito lento, dependendo do resultado desejado. Por isso, é possível
reduzir a resolução da imagem a ser processada fazendo arImageProcMode =
AR_IMAGE_PROC_IN_HALF. Esta configuração deixa o processamento mais rápido,
porém menos preciso.
206

arImageProcMode = AR_IMAGE_PROC_IN_FULL;
// arImageProcMode = AR_IMAGE_PROC_IN_HALF;

argDrawMode = AR_DRAW_BY_TEXTURE_MAPPING;
// argDrawMode = AR_DRAW_BY_GL_DRAW_PIXELS;
Código 8 – Configurações dos parâmetros arImageProcMode e argDrawMode.
O parâmetro argDrawMode = AR_DRAW_BY_TEXTURE_MAPPING
permite desenhar os pixels do vídeo como um mapeamento de texturas (veja o Código
8). Se a placa gráfica do computador tiver esta capacidade implementada, o
processamento do vídeo ficará bem mais rápido. Com argDrawMode =
AR_DRAW_BY_GL_DRAW_PIXELS os pixels da imagem são desenhados
individualmente, e portanto, para equipamentos mais novos é menos recomendado.
Agora é o momento de carregar os dados VRML, isto é, os objetos 3D
representados em arquivos cujo nome é passado em model_name (veja o Código 9).
Nesta chamada de função retorna ainda uma estrutura descrevendo este objeto e o
número de objetos que devem ser lidos.

/* carrega os dados dos objetos - marcadores treinados e mapas de


bits associados */
if ((object = read_VRMLdata(model_name, &objectnum)) == NULL )
exit(0);
printf("Objectfile num = %d\n", objectnum);
Código 9 – Carregamento dos objetos virtuais.
É momento de verificar se o objeto pode ser renderizado pela biblioteca
LibVRML ou não (veja o Código 10). Algum impedimento desta renderização em um
dos objetos fará com que a aplicação não prossiga.

/* testa a renderização de todos os objetos VRML */


printf("about to render VRML objects \n");
glEnable(GL_TEXTURE_2D);
for (i = 0; i < objectnum; i++ ) {
printf("rendering %d \n",i);
arVrml97Draw( object[i].vrml_id );
}
glDisable(GL_TEXTURE_2D);
Código 10 – Renderização dos objetos virtuais carregados no Código 9.
Depois de renderizados os objetos, os parâmetros de iluminação dos modelos
deverão ser inicializados (veja o Código 11). Segundo um dos próprios autores do
ARToolKit, brevemente haverá uma versão com tratamento de sombreamento em
tempo real no ARToolKit.
207
/* inicializa a iluminação */
init_lights();
Código 11 – Inicialização da iluminação.

6.2.7.2 mainLoop
Esta é a rotina na qual a maior parte das chamadas de função do ARToolKit. Ela
contém o código correspondente aos passos 2, 3, 4 e 5 da aplicação.
Primeiro o quadro do vídeo é capturado usando a função arVideoGetImage
(veja o Código 12).

/* captura um quadro de vídeo */


if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
arUtilSleep(2);
return;
}
Código 12 – Captura de um quadro de vídeo.
Algumas câmeras não possuem configuração de inversão vertical da imagem.
Nas câmeras testadas para escrever este tutorial, as imagens apareciam invertidas.
Portanto, foi incluído um código para inverter a imagem. Dependendo do
processamento que estiver sendo feito, esta etapa pode deixar a aplicação mais lenta. Se
esta inversão não for imprescindível, pode ser retirada.
Um passo importante em aplicações que incluem a biblioteca LibVRML no
ARToolKit é a inicialização do temporizador do renderizador.
Depois disso, a imagem é mostrada e um outro quadro é capturado (veja o
Código 13).

argDrawMode2D();
/* mostra a imagem na tela como um mapa de bits
argDispImage( dataPtr, 0, 0 );
/* captura o próximo quadro de vídeo */
arVideoCapNext();
Código 13 – Exibição da imagem e captura.
Então os quadrados que contenham os marcadores corretos na imagem
capturada devem ser detectados. Para isso são passados os parâmetros: dataPtr, que é
o ponteiro indicando o início da memória de vídeo; thresh que é o limiar para separar
o que é fundo de um eventual objeto; marker_info, que é a estrutura que contém
informações sobre o marcador e; marker_num que é um valor contendo o número de
marcadores detectados. Um retorno negativo indica uma falha que deve ocasionar a
saída da aplicação (veja o Código 14).
208

/* detecta os macadores no quadro de vídeo */


if (arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 )
{
cleanup();
exit(0);
}
Código 14 – Chamada da função de detecção de marcadores.
O número de marcadores encontrados está contido na variável marker_num. O
parêmetro marker_info é um ponteiro para uma lista de estruturas de marcadores
contendo a informação de coordenadas, valores de confiança do reconhecimento e os
identificadores dos objetos correspondentes a cada um dos marcadores.
Todos os valores de confiança dos marcadores detectados são comparados e
associados ao número identificador correto, isto é, com o maior valor de confiança (veja
Código abaixo).

/* verifica se o objeto deve ou não ser visível */


for (i = 0; i < objectnum; i++ ) {
k = -1;
for (j = 0; j < marker_num; j++ ) {
if (object[i].id == marker_info[j].id ) {
if (k == -1 )
k = j;
else {
if (marker_info[k].cf < marker_info[j].cf )
k = j;
}
}
}
if (k == -1 ) {
object[i].visible = 0;
continue;
}
Código 15 – Verificação do valor de confiança para exibição do objeto.
A transformação entre os cartões marcadores e a câmera pode ser encontrada
usando a função arGetTransMat. A posição real da câmera e sua orientação com
relação ao objeto marcador i estão contidas na matriz 3x4 object[i].trans (veja
o Código 16).

if ( object[i].visible == 0 ) {
arGetTransMat( &marker_info[k],
object[i].marker_center,
object[i].marker_width,
object[i].trans);
}
else {
arGetTransMatCont(&marker_info[k], object[i].trans,
object[i].marker_center, object[i].marker_width,
object[i].trans);
}
209
object[i].visible = 1;
Código 16 – Chamadas das funções para obter o posicionamento e a pose da
câmera.
Finalmente, os objetos virtuais podem ser desenhados na placa usando a função
draw (veja o Código 17).

/* desenha os objetos virtuais associados aos padrões marcadores */


glClearDepth( 1.0 );
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
draw( object, objectnum );
Código 17 – Código para desenhar os objetos virtuais.
A função draw e as rotinas gráficas associadas ao OpenGL estão no arquivo
draw_object.c. Na função draw, a matriz 3x4 contida em object[k].trans é
convertida em um arranjo de 16 posições, glpara, usando a chamada de função
argConvGLpara. O arranjo glpara é então passado para a função draw_object.
Estes 16 valores são os valores da posição e orientação da câmera real, portanto usá-los
para posicionar a câmera virtual faz com que os objetos gráficos desenhados pareçam
estar exatamente alinhados com o marcador físico correspondente.
A posição da câmera virtual é configurada na função draw_object usando a
função glLoadMatrix(gl_para) do OpenGL. Diferentes objetos gráficos são
então desenhados de acordo com o marcador na placa, tal como um cubo para o padrão
cujo nome é "cubo" e um cone para o padrão cujo nome é "cone". É neste momento que
é chamado o renderizador VRML, na biblioteca LibVRML97, que vai associar o grafo
de cena ao marcador detectado. O relacionamento entre os padrões e os objetos virtuais
mostrados sobre os padrões é determinado no arquivo vrml_data no diretório
bin/Data.
Ao final da execução da função mainLoop, o temporizador do renderizador
VRML é atualizado para que eventuais e o buffer de atualização disponibilizado pela
troca entre o que está sendo desenhado e o que está sendo mostrado (veja o Código 18).

/* atualiza a animação VRML */


arVrml97TimerUpdate();

/* disponibiliza um novo quadro de vídeo */


argSwapBuffers();
Código 18 – Atualizações do temporizador do renderizador e do buffer de
vídeo.
210
Os passos mencionados acima executam a cada interação do laço de
renderização. Enquanto o programa estiver executando, os eventos do mouse são
tratados pela função mouseEvent e os eventos de teclado pela função keyEvent.

6.2.7.3 cleanup
A função cleanup é chamada para finalizar o processamento de vídeo e
desconectar o dispositivo de vídeo, liberando-o para outras aplicações. Isto acontece
quando se chama as rotinas arVideoCapStop(), arVideoClose() e
argCleanup().

6.2.8 Reconhecendo outros padrões


O programa simpleVRML faz uma comparação com padrões pré-definidos para
reconhecer os diferentes padrões dentro dos quadrados marcadores. Os quadrados no
fluxo de entrada de vídeo são comparados com os padrões pré-treinados. Estes padrões
são carregados em tempo de execução e ficam no diretório bin/Data. Neste diretório,
o arquivo texto vrml_data especifica quais objetos marcadores devem ser
reconhecidos e os padrões são associados a cada objeto. O arquivo vrml_data
começa com o número de objetos que serão especificados, seguido de uma estrutura de
dados para cada objeto. Cada um dos marcadores no arquivo vrml_data é
especificado por uma estrutura com os elementos:
• Nome
• Nome do arquivo de padrões a ser reconhecido
• Largura do marcador a ser rastreado
Por exemplo, a estrutura correspondente ao marcador com o cubo virtual é
mostrada no Código 19.

#padrao 1
cube
Data/patt.hiro
80.0
Código 19 – Exemplo de estrutura que define o padrão do marcador e seu
objeto virtual.
Observe que as linhas que começam com um caracter # são linhas de comentário
e são ignoradas pelo analisador do arquivo.
Para mudar os padrões que são reconhecidos, o nome de arquivo do padrão (no
exemplo, patt.hiro) deve ser substituído pelo nome do arquivo com o padrão
211
desejado. Estes arquivos de padrões pré-definidos são simplesmente um conjunto de
exemplos de imagens do padrão desejado. O programa que cria estes arquivos de
padrões pré-definidos é chamado mk_patt e fica no diretório bin. O código fonte do
mk_patt é o arquivo mk_patt.c, que fica no diretório util.
Para criar um novo padrão pré-definido, primeiro edite em um editor de imagens
o arquivo blankPatt.gif, localizado no diretório patterns. É apenas um
quadrado preto com um quadrado branco no meio. Então crie uma imagem em preto e
branco do padrão desejado que caiba no meio deste quadrado e imprima-o. Os melhores
padrões são assimétricos e sem muitos detalhes. A Figura 6-9 mostra alguns padrões
possíveis. Insira o novo padrão no centro do quadrado vazio.

(a) (b) (c)

Figura 6-9 – Exemplos de padrões que podem ser usados como marcadores.
Uma vez confeccionado o novo padrão, vá para o diretório bin e execute o
programa mk_patt. Será pedido para que você entre com um nome de arquivo de
parâmetros de câmera (veja Figura 6-10). Entre com o nome do arquivo
camera_para.dat. Este é o nome default para o arquivo de parâmetros de câmera.

Figura 6-10 – A execução do utilitário mk_patt.

O programa abrirá então uma janela de vídeo conforme mostra a Figura 11.
Coloque o padrão a ser treinado em uma superfície plana em condições de
iluminação similares àquelas que existirão quando a aplicação de reconhecimento estará
executando. Então, coloque a câmera de vídeo apontando diretamente para o padrão e
vire-o até que um quadrado com dois lados vermelhos e dois lados verdes apareça em
212
torno do padrão (veja a Figura 6-11). Isto indica que o software mk_patt encontrou o
quadrado em torno do padrão de teste. A câmera deve ser rotacionada até que os lados
vermelhos do quadrado estejam no topo e à esquerda do quadrado na imagem de vídeo,
conforme mostra a Figura 11. Uma vez que o quadrado encontrado esteja orientado
corretamente clique o botão esquerdo do mouse. Será então pedido um nome de arquivo
para o padrão. Fornecido o nome do arquivo, é gerada uma imagem em mapa de bits do
padrão que é criado e copiado para este arquivo. Este padrão é então usado na
comparação de padrões do ARToolKit. Outros podem ser treinados simplesmente
apontando a câmera para novos padrões e repetindo o processo, ou clicando o botão
direito do mouse para sair da aplicação. É preciso copiar os novos arquivos de padrões
no diretório bin/Data antes de usá-los. É preciso também que se edite o arquivo
vrml_data para associar os padrões com os objetos virtuais.

Figura 6-11 – Janela mostrando a cena visualizada no utilitário mk_patt.

6.2.9 Outros programas de exemplo


O programa simpleVRML mostra como o ARToolKit pode ser usado para
desenvolver aplicações que sobreponham imagens virtuais com objetos virtuais. No
diretório bin há outros programas de exemplos: o exview e o simple. Estes
programas usam os mesmos padrões de marcações da aplicação simple.exe.

6.2.9.1 ExView
A aplicação ExView (veja a Figura 6-12) permite que você tenha uma visão
externa da câmera, como se a câmera estivesse sendo rastreada. Isto é útil para verificar
213
a acurácia do rastreamento. Esta aplicação permite também mostrar como as bibliotecas
do ARToolKit podem ser usadas para encontrar uma representação quaternion da
orientação do ponto de vista. No exemplo simpleVRML, o ponto de vista da câmera
foi definido usando transformações matriciais. Isto é difícil de se fazer corretamente
para aplicações 3D que usem representações por quaternion, que é o caso do VRML. O
ARToolKit também suporta a saída de quaternions, permitindo que rotinas de
rastreamento de outros pacotes de renderização sejam também utilizadas.

Figura 6-12 – Execução do utilitário ExView.


Esta aplicação mostra também um ponto forte do ARToolKit. Embora o
ExView disponibilize um mapeamento monocular impreciso, muitas aplicações
colaborativas são viáveis com um rastreamento que não exija muita precisão. Por
exemplo, interfaces na qual o usuário esteja imerso e interagindo com ícones exigem
apenas que se aponte para os objetos e não uma manipulação direta.

6.2.9.2 Simple
O simple.exe é o programa mais simples do ARToolKit. Na verdade ele não
interage com o VRML. Isto é útil quando há algum problema do qual se suspeita
alguma relação com o grafo de cena VRML. Se o simple executar e o simpleVRML
214
não, isto é uma indicação de que há algum problema na configuração dos objetos ou no
próprio renderizador do grafo de cena VRML. A Figura 6-13 mostra um instantâneo do
simple.

6.3 Calibração de Câmeras com o ARToolKit


As propriedades default da versão atual do ARToolKit estão contidas no arquivo
de parâmetro da câmera, camera_para.dat, que é lido sempre que a aplicação é
iniciada. Os parâmetros com os quais o ARToolKit vem configurado conseguem
abranger um amplo conjunto de modelos e fabricantes de câmeras. Contudo, usando
uma técnica relativamente simples de calibração de câmera, é possível gerar um outro
arquivo de parâmetros para câmeras específicas. Em uma interface de Realidade
Aumentada por visão direta (see-through), é desejável conhecer os parâmetros da
câmera para remover distorções da câmera e posicionar com mais acurácia os objetos
virtuais sobre a cena real.

Figura 6-13 – Resultado da execução do exemplo simple.exe.

Nesta seção será descrito o uso das rotinas de calibração de câmera do


ARToolKit. O início do processo de calibração é a impressão dos arquivos de padrões
de calibração calib_cpara.pdf e calib_dist.pdf. Estes arquivos ficam no
diretório patterns. O arquivo calib_cpara.pdf (veja Figura 6-14a) é uma grade
de linhas e deverá ser impresso em escala para que as linhas fiquem separadas de
exatamente 40 mm. O arquivo calib_dist.pdf (Figura 6-14b) contém um padrão
de 6x4 pontos e deverão também ser impressos em escala para que os pontos fiquem
215
separados de 40 mm. Uma vez que estes arquivos estejam impressos, eles deverão ser
colados separadamente em algum material plano e rígido, tais como dois pedaços de
papelão. As Figura 14a e 14b mostram estes padrões como vistos pelas lentes das
câmeras.

(a) (b)

Figura 6-14 – Padrões de calibração (a) calib_cpara.pdf e (b)


calib_dist.pdf.
As principais propriedades de câmera que devem ser extraídas deste processo
são o ponto central da imagem da câmera, as distorções da lente e a distância focal da
câmera. O programa calib_dist é usado para calcular o ponto central da imagem e
as distorções das lentes. Já o programa calib_param calcula a distância focal da
câmera. Os códigos executáveis de ambos os programas podem ser encontrados no
diretório bin e seus códigos-fonte ficam respectivamente nos diretórios
util/calib_distortion e util/calib_cparam.
O programa calib_dist deverá ser executado antes do calib_cparam,
pois o calib_cparam usa o resultado do calib_dist. No restante desta seção
explicaremos como e o que executa cada um destes programas.

6.3.1 Executando o calib_dist


O programa calib_dist usa a imagem calib_dist.pdf de uma grade de
pontos 6x4 igualmente separados. Quando vistos pela lente da câmera, sua distorção
causa um efeito chamado pin-cushion (do inglês "almofada de alfinetes") que produz
um espaçamento irregular na distribuição dos pontos na imagem da câmera (por
216
exemplo, as imagens da Figura 6-14). O programa calib_dist mede o espaçamento
entre os pontos e usa isto para calcular a distorção das lentes.
Para executar o software, conecte a câmera que você quer calibrar na porta
adequada (USB, por exemplo) e então digite calib_dist na linha de comando (veja
a Figura 15).

Figura 6-15 – Execução do utilitário calib_dist.


Aparecerá uma janela mostrando o vídeo que está sendo adquirido. Aponte a
câmera para o padrão de calibração de tal modo que todos os pontos estejam na imagem
capturada e então clique com o botão esquerdo do mouse. Isto congelará a imagem de
vídeo, como mostrado na imagem capturada da Figura 16. Agora, pressione o botão
esquerdo do mouse sobre a imagem e desenhe (segurando o botão do mouse
pressionado) um retângulo preto (que aparecerá quando você clicar) em volta de cada
ponto da imagem. Comece com o ponto mais próximo ao canto superior esquerdo da
imagem e prossiga até que todos os pontos tenham sido desenhados. Os pontos devem
ser cobertos na seguinte ordem:

1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24

Depois de um retângulo ser desenhado, um software de processamento de


imagens encontrará o ponto coberto pelo retângulo e colocará uma cruz vermelha em
seu centro. Se não aparecer uma cruz vermelha, redesenhe o retângulo até que o ponto
seja encontrado, isto é, até que apareça a cruz vermelha.
217

Figura 6-16 – Um retângulo sendo desenhado em torno de um ponto.


Uma vez capturada cada imagem, enquanto cada retângulo estiver sendo
desenhado, aparecerá a seguinte saída (veja a Figura 17), mostrando cada ponto
capturado.

Figura 6-17 – Saída de texto enquanto cada ponto estiver sendo desenhado.
Uma vez encontrados todos os 24 pontos da imagem, pressione botão esquerdo
do mouse novamente. Isto armazenará a posição dos pontos e descongelará a imagem de
vídeo. A saída ilustrada na Figura 6-18 mostra a saída da tela depois disso, isto é, a
posição capturada de cada um dos pontos, bem como suas respectivas posições na
grade.
218

Figura 6-18 – Saída mostrando as posições capturadas de cada ponto.


Você deverá agora tomar outra imagem e repetir o processo para outras 5 a 10
imagens, em vários ângulos e posições diferentes. Quanto mais imagens tomadas, mais
precisa será a calibração. As figuras 19a e 19b mostram exemplos de imagens típicas.

(a) (b)

Figura 6-19 – (a) Pose e posição diferentes do padrão de calibração da


distorção. (b) A mesma imagem com os pontos marcados.
Uma vez que você tenha tomado de 5 a 10 imagens, pressione o botão direito do
mouse para parar a captura de imagens e começar a calcular os valores de distorção da
câmera.
219
O cálculo destes parâmetros pode demorar alguns minutos, seja paciente. Os
valores centrais x e y e o fator de distorção são os valores finais principais gerados pelo
programa calib_dist. Estes valores serão diferentes para cada câmera e deverão ser
salvos para que se possa usá-los no programa calib_cparam. A Figura 6-20 mostra a
saída ao término desta etapa de calibração.

Figura 6-20 – Saída do resultado final da calibração da distorção da câmera.


220
Para verificar se estes parâmetros estão corretos, pressione o botão esquerdo do
mouse novamente. Isto mostrará aquela primeira imagem capturada com as linhas
vermelhas desenhadas passando pelos pontos de calibração. Estas linhas deverão se
cruzar no centro de cada um destes pontos (veja Figura 21). Cada vez que o botão
esquerdo do mouse é pressionado, a próxima imagem capturada é mostrada.

Figura 6-21 – Verificações da aplicação da calibração mostrando linhas


passando pelos pontos do padrão de calibração.
Uma vez satisfeito com os resultados do calib_dist, clique no botão direito
do mouse para sair e executar o código calib_cparam.

6.3.2 Executando o calib_cparam


O calib_cparam é usado para encontrar a distância focal da câmera, além de
outros parâmetros. Ele usa o padrão contido no calib_cparam.pdf, um padrão de
grade de 7 linhas horizontais e 9 linhas verticais. Este padrão deve ser impresso e colado
a um pedaço de papelão ou alguma outra placa rígida.
O calib_cparam é executado como segue:
1) Digite calib_cparam na linha de comando (veja a Figura 22) e entre com
as coordenadas do centro e com o fator de distorção encontrado pelo calib_dist.
221

Figura 6-22 – Entrada, pela linha de comando, dos parâmetros


do utilitário calib_caparam.
Aparecerá uma janela de captura de vídeo.
2) Coloque o padrão de calibração em frente à câmera de tal modo que: (a) a
placa fique perpendicular ao eixo óptico da câmera; (b) todas as linhas da grade sejam
visualziadas; e (c) a grade esteja cobrindo o maior espaço possível na imagem.
3) Pressione o botão esquerdo do mouse para capturar a imagem. Aparecerá
então uma linha branca horizontal na imagem (veja a Figura 23).

Figura 6-23 – A linha branca aparecendo sobre a imagem do padrão de


calibração
4) Mova a linha branca de modo a cobrir o máximo possível a linha preta do
topo da grade. A linha pode se movimentar para cima ou para baixo usando-se as teclas
de seta para cima e para baixo. A linha pode ainda ser rotacionada no sentido horário e
anti-horário usando as teclas de setas para a direita e para a esquerda. Uma vez que a
linha branca esteja alinhada com a linha do topo da grade, pressione a tecla enter. Esta
222
linha se tornará azul e então aparecerá outra linha branca (ver Figura 24). Este processo
deverá ser repetido para todas as linhas horizontais.

Figura 6-24 – A linha se torna azul e surge uma outra linha branca.
Uma vez que a última linha horizontal tenha sido ajustada, uma linha branca
vertical aparecerá e o processo deverá ser repetido para as linhas verticais. A primeira
linha branca vertical deverá ser ajustada sobre a linha da grade mais à esquerda e as
outras linhas se ajustarão da esquerda para a direita (ver Figura 6-25).

Figura 6-25 – Ajuste das linhas verticais.


A ordem das linhas é muito importante. Elas deverão ser ajustadas de cima para
baixo e da esquerda para a direita até que todas as 16 linhas tenham sido desenhadas na
tela.
223
5) Uma vez que o processo tenha terminado para uma imagem, o padrão de
grade deverá ficar mais distante 100mm da câmera (mantendo a câmera perpendicular
ao padrão) e o processo deve ser repetido novamente. A Figura 26 ilustra a última linha
ajustada para uma das imagens capturadas.

Figura 6-26 – O ajuste da última linha branca vertical.


6) Repita o processo cinco vezes, afastando o padrão de calibração por um total
de 500mm da câmera. Depois da quinta etapa de calibração, o programa
automaticamente calculará os parâmetros da câmera. Será pedido que você entre com
um nome de arquivo para armazenar estes parâmetros nele (veja Figura 6-27).
Uma vez que os valores estejam armazenados em arquivo de dados da câmera,
pressione o qualquer botão do mouse para sair.
224

Figura 6-27 – Resultado final do utilitário calib_cparam.


Mudando o nome deste arquivo de dados da câmera para camera_para.dat
e colocando-o no diretório bin/Data ele já pode ser usado nos programas exemplos
do ARToolKit. A calibração da sua câmera deverá produzir resultados de rastreamento
bem melhores que o da configuração padrão de parâmetros.
A distância padrão entre as linhas da grade no arquivo calib_cparam.pdf é
exatamente 40 mm, enquanto o padrão deve ser afastado da câmera em 100mm para
cada mensuração, que deve ser repetida 5 vezes. Estes valores são todos determinados
no código fonte calib_cparam.c no diretório util/calib_cparam (veja
Código 20).
Se você quiser modificar a distância entre as linhas da grade, o trecho de código
fonte abaixo deve ser modificado.

inter_coord[k][j][i+7][0] = 40.0*i;
inter_coord[k][j][i+7][1] = 40.0*j;
inter_coord[k][j][i+7][2] = 100.0*k;
Código 20 – Trecho do programa calib_cparam.c para alterar o distanciamento
dos padrões de calibração.
Neste código, 40 é a distância entre as grades e entre os pontos, e 100.0 é a
distância padrão em que devem ser afastados os padrões a partir da câmera, a cada vez.
O número de medidas que devem ser tomadas pode ser alterado na variável loop_num
(veja Código 21).
225
*loop_num = 5;
Código 21 – Variável que deve ser alterada para mudar o número de distâncias
do padrão de calibração até a câmera.

6.4 Bibliotecas e Funções do ARToolKit


Esta seção fornece uma lista parcial das funções fornecidas pelo ARToolKit.
Neste documento não são listadas as funções de calibração da câmera.
A biblioteca ARToolKit consiste de 3 pacotes encontrados no diretório lib:
• libAR.lib: biblioteca para rastreamento de marcadores, calibração e
entrada de parâmetros. Contém as funções de suporte para a detecção
dos marcadores.
• libARvideo.lib: biblioteca para capturar quadros da entrada de
vídeo. Estas bibliotecas de vídeo variam a cada versão e, dependendo
do suporte oferecido, disponibiliza bibliotecas para Windows WDM,
Linux Video 4 Linux, para câmeras Firewire ou então para placas de
aquisição. É a parte que mais têm se alterado no surgimento de novas
versões.
• libARgsub.lib: contém rotinas gráficas, baseadas nas bibliotecas
OpenGL e Glut, para mapeamento do vídeo como textura em um
ambiente 3D, bem como para o posicionamento dos objetos virtuais
sobre o marcador.
A figura 28 ilustra a estrutura hierárquica das bibliotecas. A exceção a esta
estrutura é a função argCalibHMD no libARgsub.lib que usa tanto o
libAR.lib quanto libARvideo.lib.
226

Figura 6-28 – Estrutura de bibliotecas do ARToolKit


A partir da versão 2.43 foram incluídas as bibliotecas de grafo de cena VRML,
LibVRML97. Esta biblioteca de grafo de cena inclui outras 4 bibliotecas:
• libARvrml.lib: esta biblioteca implementa um visualizador VRML
sobre o OpenGL. Na verdade ela implementa um visualizador
utilizando as funções da biblioteca LibVRML97 que atuam diretamente
sobre o OpenGL. Estende ao ARToolKit a classe OpenGLViewer
fornecida pela biblioteca libvrml97gl.
• libvrml97core.lib: é a implementação das funções VRML97.
Contém todos os comandos para gerar uma cena a partir de um código
VRML e, claro, o seu analisador léxico e sintático (parser).
• libvrml97js.lib: é a implementação do script (javascript)
versão 1.1 do engine Mozzila. Estes scripts permitem gerar animações
3D, porém nem todos os aspectos são considerados.
• libvrml97gl.lib: é uma implementação de uma classe
OpenGLViewer que renderiza as cenas VRML sobre uma janela
OpenGL.
Essas bibliotecas são, na verdade, implementações agrupadas pela LibVRML97.
Uma discussão detalhada sobre suas funções não está no escopo deste tutorial.
227
6.4.1 Estruturas de Dados Básicas
As informações sobre a detecção de marcadores ficam contidas na estrutura
ARMarkerInfo definida no arquivo de protótipos ar.h no diretório include.
Na estrutura do Código 22, id é um número de identificação do marcador, cf é
um valor de confiança de que o marcador foi identificado corretamente, pos[2] é o
centro do marcador em um sistema de coordenadas de tela ideal, line[4][3] é a
equação das retas para os quatro lados dos marcadores em um sistema de coordenadas
de tela ideal e vertex[4][2] são as coordenadas dos vértices no sistema de
coordenadas de tela. Para as equações das retas em line[4][3] os valores
line[X][0], line[X][1], e line[X][2] são os valores a, b, c da equação da
reta ax+by+c=0.

typedef struct {
int area;
int id;
int dir;
double cf;
double pos[2];
double line[4][3];
double vertex[4][2];
} ARMarkerInfo;
Código 22 – Estrutura de descrição de marcadores.

6.4.2 Funções de Realidade Aumentada


As funções comumente usadas em aplicações de realidade aumentada estão
armazenadas na biblioteca libAR.lib. Há funções para:
• carga inicial dos padrões e dos padrões treinados:

int arInitCparam( ARParam *param);


int arLoadPatt( char *filename );
• detectar marcadores e posições da câmera:

int arDetectMarker( ARUint8 *dataPtr, int thresh,


ARMarkerInfo **marker_info,
int *marker_num );
int arDetectMarkerLite( ARUint8 *dataPtr, int thresh,
ARMarkerInfo **marker_info,
int *marker_num);
int arGetTransMat( ARMarkerInfo *marker_info,
double pos3d[4][2],
double trans[3][4] );
int arSavePatt( ARUint8 *image,
ARMarkerInfo *marker_info,
char *filename);
A seguir estas funções são descritas com um pouco mais de detalhe.
228
6.4.2.1 arInitCparam
6.4.2.1.1 Função: Iniciar os parâmetros especificados na estrutura de
parâmetros da câmera. O argumento *param aponta para uma memória
estática na biblioteca AR. Estes parâmetros de câmera são normalmente
lidos pelo programa de inicialização a partir de um arquivo de dados. Em
aplicações de RA por visão direta, parâmetros default de câmera são
suficientes, ou seja, não é preciso qualquer calibração de câmera.

6.4.2.1.2 Variável: *param – a estrutura do parâmetro de câmera.


6.4.2.1.3 Retorno: sempre zero.

6.4.2.2 arLoadPatt
6.4.2.2.1 Função: Carregar o mapa de bits do padrão especificado no arquivo
em filename, no vetor de padrões para uso posterior pelas rotinas de
detecção de marcadores.
6.4.2.2.2 Variável: *filename – nome do arquivo que contém o mapa de bits
a ser carregado
6.4.2.2.3 Retorno: o número do padrão carregado ou –1 em caso de falha.

6.4.2.3 arDetectMarker e arDetectMarkerLite


6.4.2.3.1 Função: detectar os marcadores quadrados no frame de entrada de
vídeo.

6.4.2.3.2 Variáveis: ARUint8 *dataPtr – um ponteiro para imagem


colorida que é para ser pesquisada para marcadores quadrados. O
formato do pixel é ABGR, mas as imagens são tratadas em níveis de
cinza. Portanto, a ordem dos componentes BGR não importa. Entretanto,
a ordem do componente alfa, A, é importante.

6.4.2.3.3 int thresh – especifica o valor de limiar (entre 0 e 255)


a ser usado para converter a imagem de entrada em uma imagem
binária.
229
ARMarkerInfo **marker_info – um ponteiro retornado para uma matriz de
estruturas ARMarkerInfo, que contém todas as informações sobre os
quadrados detectados na imagem.
int *square_num – número de marcadores detectados na imagem.

6.4.2.3.4 Retorno: zero quando a função completa normalmente, -1 caso


contrário.
A função arDetectMarkerLite(...) é uma versão mais simples
da arDetectMarker, mas que não chama as funções de correção de erro e,
portanto, executa um pouco mais rápido, mas com mais erros de detecção.

6.4.2.4 arGetTransMat
6.4.2.4.1 Função: calcular a transformação entre um marcador detectado e a
câmera real, isto é, a posição e orientação da câmera relativas à
marcação de rastreamento.
6.4.2.4.2 Variáveis: ARMarkerInfo *marker_info – a estrutura que
contém os parâmetros para o marcador para o qual a posição e
orientação da câmera será relativa. Essa estrutura é encontrada usando
arDetectMarker.
double pos3d[4][2] – posições físicas dos vértices do marcador.
arGetTransMat assume que o marcador está no plano xy, e que o eixo z
está apontando para baixo do plano do marcador. Deste modo, as posições
dos vértices podem ser representadas em coordenadas 2D, ignorando a
informação do eixo z. A ordem das posições dos vértices são especificadas
no sentido horário. Por exemplo, para um marcador com lado medindo 50
mm e com a origem das coordenadas do marcador no seu centro:

pos3d[4][2] = { { -25.0, -25.0 }, { 25.0, -25.0 },


{ 25.0, 25.0 }, {-25.0, 25.0 } };

pos3d[4][2] é especificado no arquivo do parâmetro vrml_data e lido na


inicialização do programa.
230
double conv[3][4] – é a matriz de transformação entre as coordenadas do
marcador e as coordenadas do frame da câmera, que é a posição relativa da
câmera real em relação ao marcador real.
6.4.2.4.3 Retorno: Sempre zero.

6.4.2.5 arSavePatt

6.4.2.5.1 Função: usado no mk_patt para gravar um mapa de bits do padrão


do marcador que está sendo detectado.

6.4.2.5.2 Variáveis: ARUint8 *image – ponteiro para a imagem contendo o


padrão do marcador a ser treinado.
ARMarkerInfo *marker_info – um ponteiro para a estrutura ARMarkerInfo
do padrão a ser treinado.
char *filename – o nome do arquivo em que a imagem do mapa de bits será
gravada.
6.4.2.5.3 Retorno: zero – se a imagem foi salva com sucesso, -1 caso contrário

6.4.3 Funções de Aquisição de Vídeo


As seguintes funções da biblioteca libARvideo.lib são mais comumente
usadas:

int arVideoOpen( void );


int arVideoClose( void );

int arVideoInqSize( int *x, int *y);


unsigned char *arVideoGetImage( void );
As funções de vídeo são definidas abaixo com mais detalhe.

6.4.3.1 arVideoOpen
6.4.3.1.1 Função: abre o driver de vídeo para tentar encontrar todos os
dispositivos de vídeo registrados no Windows
6.4.3.1.2 Variáveis: nenhuma
6.4.3.1.3 Retorno: zero – sucesso, -1 se o driver de vídeo não puder ser aberto.
231
6.4.3.2 arVideoClose
6.4.3.2.1 Função: é uma função que precisa ser chamada para finalizar a
captura de vídeo.
6.4.3.2.2 Variáveis: nenhuma
6.4.3.2.3 Retorno: zero – se finalizou com sucesso, -1 caso contrário.

6.4.3.3 arVideoInqSize
6.4.3.3.1 Função: retorna tamanho do quadro de vídeo capturado.
6.4.3.3.2 Variáveis: int *x, *y – ponteiros para largura (*x) e altura
(*y) da imagem capturada.

6.4.3.3.3 Retorno: zero – se as dimensões foram encontradas com sucesso, -1


caso contrário

6.4.3.4 arVideoGetImage
6.4.3.4.1 Função: capturar um único quadro de vídeo
6.4.3.4.2 Variáveis: nenhuma
6.4.3.4.3 Retorno: retorna um ponteiro para o quadro de vídeo capturado ou
NULL se um quadro não puder ser capturado.

6.5 Limitações da RA baseada em Visão Computacional


Há algumas limitações de sistemas de Realidade Aumentada baseados apenas
em visão computacional. Os objetos virtuais só podem ser exibidos quando as marcas
estiverem sendo rastreadas. Esta dependência do rastreamento limita o tamanho dos
objetos virtuais e seus movimentos. Portanto, se os usuários cobrirem parte do padrão
com suas mãos ou outros objetos, o objeto virtual desaparecerá. Além disso, há limites
na inclinação dos marcadores. Se o usuário inclinar muito o marcador em relação ao
eixo óptico da câmera, o padrão inscrito no marcador pode se tornar irreconhecível pelo
programa, impedindo-o de tomar a decisão do padrão que deve ser exibido.
Há também limitações de espaço. Quanto maior for o tamanho físico do padrão,
maior será a distância da qual você poderá detectá-lo e, portanto, maior será o volume
do espaço de interação no qual o usuário poderá ser rastreado. Contudo, aumentar o
232
tamanho do padrão não resolve sempre, pois pode haver alguma dificuldade em seu
enquadramento pela câmera se houver a necessidade de aproximação da câmera. A
Tabela 2 mostra alguns limites máximos típicos para marcadores quadrados de
diferentes tamanhos de um experimento relatado em [KATO, BILLINGHURST &
POUPYREV 2000]. Estes resultados foram obtidos a partir de padrões de marcação de
diferentes tamanhos, colocando-os perpendicularmente à câmera e movendo a câmera
para trás até que o objeto virtual desapareça.

Tabela 2 – Resultado de experimento comparando o tamanho dos padrões de


marcação com o espaço útil de interação.

Tamanho do Padrão (em Espaço de Interação Útil


cm) (em cm)
6,985 40,64
8,89 63,5
10,795 86,36
18,72 127
Esta limitação de espaço também é afetada de alguma maneira por padrões
cheios de detalhes. Quanto mais simples o padrão, melhor. Padrões com grandes regiões
pretas e brancas (isto é, padrões de baixa freqüência) são mais eficazes. Para se ter uma
idéia, neste experimento, o padrão quadrado de 10,795 centímetros, usado no resultado
da tabela acima, foi substituído por um padrão do mesmo tamanho, mas com mais
detalhes. Esta simples troca reduziu o espaço de rastreamento de 86,36 para 38,1
centímetros.
O rastreamento também é afetado pela orientação dos marcadores em relação à
câmera. Conforme os marcadores se inclinam, menos os padrões do centro serão
visíveis e o reconhecimento torna-se menos confiável. Padrões confeccionados sobre
superfícies maleáveis (como o papel sulfite comum), que se curvam facilmente também
não são adequados, tornando-se sujeitos a indecisões de reconhecimento.
Os resultados do rastreamento são afetados também por condições de
iluminação. A saturação luminosa pode criar reflexões e regiões brilhantes nas marcas
do papel tornando mais difícil a tarefa de encontrar as marcas quadradas. Para reduzir o
brilho, os padrões podem ser confeccionados com material não reflexivo. Por exemplo,
os marcadores podem ser confeccionados com papel camurça, encontrado em
papelarias.
233
Pode-se perceber, a partir destas limitações, que o ambiente no qual a aplicação
de RA ocorrerá assim como as interações entre os objetos, exigem que as aplicações
sejam planejadas para que se possa determinar os tamanhos adequados dos marcadores,
suas possíveis inclinações, ou ainda a iluminação do ambiente. Marcadores que se
movimentam ao alcance das mãos dos usuários devem ter um tamanho menor que
aqueles que são utilizados apenas para visualizados a uma certa distância, como por
exemplo, uma decoração virtual em um apartamento real. É fácil notar que marcadores
estacionários são menos suscetíveis a problemas de reconhecimento que aqueles que se
movimentam muito. Uma taxa de quadros deve dar ao usuário a ilusão de uma interação
real. Atualizações de quadro com menos que 20 fps podem comprometer a fidelidade da
aplicação, principalmente se esta aplicação envolver a manipulação de objetos virtuais.
Outros experimentos explicitando estas limitações podem ser encontrados em [DAVIS,
CLARKSON & ROLLAND 2003; MALBEZIN, PIEKARSKI & THOMAS 2002;
OWEN, XIAO & MIDDLIN 2002].

6.6 Aplicações Educacionais em Ambientes de Realidade


Aumentada com ARToolKit

6.6.1 Introdução
Os sistemas que permitem maior interatividade entre o homem e a máquina,
tornam-se cada vez mais utilizados em todos os setores, pois enriquece a relação
homem-máquina e possibilita um controle maior do usuário frente às tarefas.
Nesse sentido, os sistemas virtuais possibilitam experiências com a sensação de
presença, através da integração dinâmica de diferentes modalidades perceptivas, que
envolvem imagens, sons, tato, etc. Assim, torna-se possível a capacidade de manipular,
relacionada às reações sensório-motora em tempo real [Lévy, 1999].
Por outro lado, os ambientes educativos devem oferecer condições favoráveis à
criação, comportando-se como um espaço agradável e permitindo aplicações práticas e a
relação do conhecimento com experiências, necessidades e realidade do aluno (usuário).
De maneira geral, a construção do conhecimento dá-se através da reflexão, da
crítica, da identificação e da busca de resoluções dos problemas, propiciando situações
que determinem o desafio - papel importante na formação de atitudes [Valente. 1991,
2001]. Os ambientes podem contribuir, estimulando a curiosidade e auxiliando no
desenvolvimento da autonomia.
234
A aprendizagem ocorre, quando o indivíduo está engajado e utiliza de forma
consciente estratégias de resolução de problemas para a construção significativa. Não se
deve questionar o valor da instrução, mas é importante a descoberta de novos
conhecimentos, através da relação do novo com a experiência anterior.
Assim, a possibilidade de interação entre objetos reais e virtuais, que ocorre
através da Realidade Aumentada (RA), pode oferecer ao usuário maiores informações
sensitivas, facilitando a associação e a reflexão sobre a situação. Os sistemas de
Realidade Aumentada permitem que o usuário decida sobre os ambientes, compondo
cenas com imagens de objetos tridimensionais geradas por computador misturadas com
imagens reais, aumentando as informações do cenário e oferecendo condições para a
imersão no ambiente criado. A principal característica destes ambientes é que as
informações do mundo real são utilizadas para criar um cenário incrementado com
elementos gerados por computador [Dainese, 2003].

6.6.2 Intervenções Educacionais com Realidade Aumentada


Três características são responsáveis por tornar as situações de intervenção
educacionais interessantes: curiosidade, fantasia e desafio. Através dos ambientes de
realidade aumentada, é possível proporcionar ao usuário (aluno) situações lúdicas,
tornando as atividades mais motivadoras.
Deve-se destacar a importância das relações sociais para o aluno garantir seu
envolvimento com situações novas, considerando aquelas vividas anteriormente. Assim,
ele poderá construir o novo, através do fazer, motivado pelo envolvimento afetivo. O
ambiente deve ser favorável ao interesse do usuário, além de ser um ambiente
contextualizado e significativo. Os problemas emergem no ambiente e o usuários com
autonomia deve decidir resolvê-lo. O professor (usuário) deve ter preparo para utilizar a
tecnologia e aproveitar os recursos que as ferramentas podem oferecer, de forma a
garantir flexibilidade intelectual, capacidade de criar, inovar e, principalmente, enfrentar
o desconhecido para promover o desenvolvimento cognitivo.
Em ambientes de Realidade Aumentada, o mundo real é “aumentado” com
informações que não estão presentes na cena capturada, e o usuário passa ser um
elemento participativo no cenário em que imagens reais são misturadas com virtuais
para criar uma percepção aumentada. [Azuma, 2001]
A interface deve ser entendida como um espaço de comunicação, um sistema
semiótico, onde signos são usados para interação, possibilitando o acesso ao ambiente
235
[Garbin, 2004]. Para garantir uma boa usabilidade, os fatores humanos devem ser
respeitados. Isso remete à questão da diversidade dos usuários, suas características
cognitivas, de personalidade, cultura, idade, comportamento e habilidades e
necessidades especiais [Baranauskas,2003. Os estudos sobre a memória humana
(principalmente a de curta duração), vêm oferecendo subsídios para soluções
inteligentes sobre a interface, cuja idéia central é liberar o usuário da memorização de
comandos para tornar o ambiente mais agradável e natural através de interfaces gráficas.
Um ambiente educativo deve ser atrativo e interessante, oferecendo, através de
situações lúdicas e espontâneas, atividades que proporcionem o desenvolvimento
cognitivo. A interface deve ser planejada para oferecer flexibilidade ao usuário e, para
facilitar a aprendizagem, o sistema não deve ser linear-fechado, onde apenas uma
resposta é correta frente a um tipo de estímulo apresentado. A aceitação de uma
interface depende da capacidade de sua linguagem de interação em comunicar suas
funções com clareza. Assim, no desenvolvimento de interfaces de realidade aumentada
como mediador pedagógico, a questão de qualidade deve ter como objetivo a intenção
do usuário e, principalmente, a usabilidade, possibilitando criar o novo a partir das
experiências vividas.
Os requisitos de ambientes de realidade aumentada para satisfazer as
necessidades educativas, enquanto mediador pedagógico para sistemas complexos, são:

• Oferecer flexibilidade, em função do ambiente;


• Exibir uma conduta adaptativa;
• Operar em tempo real;
• Oferecer a possibilidade de interação entre o real e virtual;
• Operar através de interação direta com linguagem natural;
• Oferecer um ambiente complexo, e aberto para:
- Identificação de grande quantidade de dados;
- Identificação de reações perceptuais e motoras com muitos graus de
liberdade.
Nos ambientes de realidade aumentada, espera-se que o usuário possa:

• Utilizar símbolos e abstrações;


• Utilizar linguagem natural;
• Realizar ações que compõem, alteram ou criam novas situações;
• Interagir com objetos virtuais em tempo real;
236
• Relacionar ou compor cenas e ambientes com a integração entre o real e o virtual;
• Realizar ações autônomas no ambiente conduzidas pelo desejo e imaginação.

6.6.3 Sistema de Realidade Aumentada


Um sistema de Realidade Aumentada típico é formado de uma ou mais câmeras,
software para construção de objetos virtuais, sistema gráfico e dispositivo de interação
para as tarefas de: a) captura da cena real, b) criação de objetos virtuais, c) sobreposição
dos objetos reais e virtuais no mesmo cenário, d) rastreamento para posicionamento e
orientação espacial do usuário e, e) interação em tempo real.
O processo de criar um ambiente de Realidade Aumentada consiste em obter
imagens reais, via câmera, e misturá-las com objetos virtuais criados por computador
dentro do mesmo ambiente. Uma tarefa importante é extrair informações para instruir o
sistema gráfico no processo de formação de um ambiente, a partir do ponto de vista do
usuário. Uma das formas para efetuar esta operação é utilizar marcadores que permitem,
ao sistema gráfico, definir coordenadas espaciais e orientação dos objetos, a partir do
ponto de vista do usuário, além de identificar alterações de posicionamento e interação
do usuário com os objetos.
Após alguns experimentos, desenvolveu-se aplicações como: quebra-cabeça;
livro interativo, pá de transporte de objetos virtuais e aprendizagem de mecãnica
quântica com o Orbitário. Estas aplicações tiveram como base brinquedos e objetos
reais, utilizados em situações de ensino, com o objetivo de oferecer ao usuário a
possibilidade de interagir e visualizar novas situações.
Nesse contexto, a Realidade Aumentada [Azuma, 1997] enriquece o ambiente
real com objetos virtuais, com base em tecnologias que permitem misturar o cenário real
com virtuais. Isto pode ser feito, através do uso de WebCam que permite a captura do
cenário real e o rastreamento das mãos ou de algum dispositivo auxiliar (placa com
marcador). Esse ambiente permite fornecer maior realismo às aplicações e o uso das
mãos para manipulação dos objetos, minimizando os inconvenientes da Realidade
Virtual.
Com esse fator motivacional, a Realidade Aumentada possibilita implementar
ambientes que permitam a aplicação de estratégias diferenciadas para o
desenvolvimento cognitivo.
O trabalho consistiu de duas etapas: a) desenvolvimento tecnológico e b)
aplicações educacionais.
237
Uma vez que o ARToolKit é um software aberto, o desenvolvimento
tecnológico consistiu na alteração de seu código de programação para dar
funcionalidades específicas não contempladas no software original, mas necessárias
para o desenvolvimento de aplicações diferenciadas. Nesse sentido, foram introduzidos
trechos de programas que permitiram a introdução de som (Santin, 2004), controle de
posicionamento (Lahr, 2004), controle de sequência de objetos e transporte de objetos
(Santin, 2004).
As aplicações baseadas em ARToolKit dependem de três elementos: o cenário
real, objeto virtual e uma placa quadrada (marcador) com uma moldura e um identificar
desenhado dentro dela. Ligando-se o sistema, a imagem capturada pela WebCam
aparece na tela do monitor. Ao introduzir o marcador no campo de visão da câmera
(usando as mãos), o software ARToolKit posiciona o objeto virtual sobre o marcador no
cenário real, misturando as imagens. Ao movimentar-se o marcador, o objeto virtual
acompanha este movimento, permitindo sua manipulação com as mãos.
Com o uso de som [Santin, 2004], associa-se, a cada objeto, um som
correspondente (ruídos, locuções, etc) que é disparado quando a placa entra no campo
de visão da WebCam, além do aparecimento do objeto virtual sobre a placa. Como
exemplo, pode-se citar a visualização de um carro virtual sobre a placa acompanhada do
som do motor.
Com o uso de uma placa adicional de controle [Santin, 2004], foi possível alterar
o objeto virtual associado a uma placa, trocando suas características, ou mesmo, a troca
do objeto. Como exemplo, pode-se citar a presença de um carro em uma placa, que
muda de cor, ou de modelo, com cada introdução da placa de controle. O som associado
também pode ser alterado por esta placa.
Através do posicionamento espacial, foi possível registrar a trajetória dos
objetos, capturando-se cada posicionamento e desenhando-se o deslocamento da
trajetória [ Utiyama, 2004]. Como exemplo, a movimentação do carro no campo de
visão da câmera, pode ser visualizada.
No transporte de objetos [Santin, 2004] [ Lahr, 2004], uma placa de controle, ao
aproximar-se da placa com objeto virtual, permitiul a movimentação do objeto de uma
placa para outra, ou a cópia de objetos entre placas. Com isto, foi elaborada uma
ferramenta de autoria [Galana, 2004], que propiciou a montagem de cenários de
Realidade Aumentada com uso das mãos pelo usuário.
238
6.6.4 Quebra-cabeças
O quebra-cabeça, com Realidade Aumentada consistiu em conjunto de peças que
formam uma imagem de um lado e no seu verso um marcador. Ao montar corretamente
o quebra-cabeça, a pessoa visualiza a imagem final na parte da frente. Virando-o e
expondo o marcador, montado no seu verso, à câmera, aparece o objeto virtual
correspondente. Como exemplo, foi utilizado o quebra-cabeça de um trem (Figuras 1 e
2), que, na frente, mostra a figura de um trem e, sobre o marcador no verso, um trem
virtual em movimento

.
Figura 6-29 – Parte superior do quebra-cabeças

6.6.5 Livro Interativo com Realidade Aumentada

Outra aplicação foi o desenvolvimento do Livro Interativo de Realidade


Aumentada (LIRA) (Akagui, 2004) que consistiu na montagem de um livro explicativo
sobre poliedros. Cada folha do livro apresentou um marcador de forma que, ao expô-lo
no campo de visão da câmera, apareceu o poliedro virtual (Figuras 3 e 4) em 3D sobre o
livro.
239

Figura 6-30 - Poliedro virtual

Figura 6-31 - Alteração do poliedro

O uso do marcador permitiu uma variação da visualização do poliedro, alterando


suas cores, mostrando sua versão aramada e colocando-o para girar de forma a permitir
a visualização de vários pontos de vista.

6.6.6 Pá de transporte de objetos virtuais


A Figura 5 mostra uma sequência de transporte de um objeto de uma placa para
outra, usando uma pá [Santin, 2004] [Lahr, 2004], implementada com o software
ARToolKit, permitindo assim a obtenção de um mecanismo de autoria de ambientes
virtuais sobre uma mesa ou algo equivalente.
240

Figura 6-32 - Seqüência de transporte de um objeto

6.6.7 Aprendizagem de mecânica quântica com realidade


aumentada: O Orbitário
A Mecânica Quântica, em conjunto com a teoria da Relatividade, é a pedra
angular da Física do século XX e influenciou alguns dos mais recentes e estupendos
avanços científicos que ocorreram em áreas como a Biologia, a Química e a Física.
Sendo a base de sustentação da física das partículas elementares, nuclear, atômica,
molecular e do estado sólido, os seus impactos foram consideráveis com
desenvolvimentos tecnológicos como o microscópio eletrônico de varrimento por efeito
túnel (STM), o relógio atômico do sistema de posicionamento global (GPS), a produção
de imagens por ressonância magnética (NMR) e a tomografia por emissão de pósitrons
(PET). Estes avanços foram possíveis graças ao uso de computadores, que permitiram
novas formas de ver e compreender a estrutura atômica e molecular.
Contudo, a aprendizagem da Mecânica Quântica é normalmente considerada
difícil pelos alunos, devido ao seu caracter axiomático. Quando os alunos estudam
Mecânica Quântica, têm frequentemente de visualizar informação 3-D mostrada em
gráficos 2-D. Uma dificuldade adicional dos alunos é a utilização de conceitos que são
muito diferentes dos que são aprendidos na Mecânica Clássica (por exemplo, um elétron
num dado estado pode ser detectado em diferentes pontos do espaço, com diferentes
probabilidades dadas pelo módulo do quadrado da função de onda). Contudo, no ensino
tradicional da Mecânica Quântica, supõe-se que o conceito de probabilidade é de fácil
assimilação para os alunos. A noção de ocupação probabilística do espaço parece,
porém, oferecer algumas dificuldades dos alunos.
Existe uma desfasagem entre a inovação tecnológica e a sua aplicação no ensino.
Contudo, desde os primórdios da utilização dos computadores no ensino, têm sido
reconhecidas as potencialidades dos computadores como ferramenta de ensino e
aprendizagem. Uma das mais promissoras tecnologias de apoio ao ensino e
aprendizagem das ciências é a realidade virtual. Entre as fronteiras desta e da realidade
existe o espectro da realidade aumentada na qual cenários do mundo real (por exemplo,
os gráficos 2-D habituais dos manuais de Mecânica Quântica) podem ser combinados
com modelos virtuais (por exemplo, os respectivos modelos 3-D correspondentes às
representações 2-D). Uma das vantagens pedagógicas da realidade aumentada é a
241
possibilidade de permitir a visualização simultânea de processos a diferentes escalas.
Pode ainda juntar os gráficos 2-D dos textos de Mecânica Quântica com os respectivos
modelos 3-D.
Motivados por estas idéias, está sendo desenvolvido, aplicado e avaliado um
programa baseado em realidade aumentada para ajudar no estudo de conceitos de
Mecânica Quântica para alunos dos anos terminais do ensino secundário e do primeiro
ano da universidade. Os conceitos pertencem ao âmbito da Mecânica Quântica não
relativista, incluindo a interpretação probabilística da função de onda, as propriedades
das soluções da equação de Schrödinger, os princípios da incerteza e de exclusão de
Pauli, etc. Também serão ilustradas algumas experiências importantes como a de
difração de Rutherford, a de Thompson sobre a razão e/m para um elétron, etc.

6.6.7.1 Dificuldades de aprendizagem da Mecânica Quântica


Algumas dificuldades associadas à aprendizagem da Mecânica Quântica estão
ligadas com a necessidade de ver o invisível. A utilização de modelos bidimensionais
nos livros de texto e a manipulação de modelos matemáticos (em geral mal
compreendidos) não facilitam a compreensão, sobretudo para alunos com menores
aptidões espaciais [Allendoerfer, 1990]. Isto explica a afirmação comum entre
estudantes de que a Mecânica Quântica é difícil, pois “é tudo matemática”. De acordo
com Hurwitz et al. [Hurwitz, 1998], um aluno com maiores dificuldades de raciocínio
espacial estará em desvantagem face a outros mais dotados desse ponto de vista.
Tem havido alguma movimentação neste domínio, com alguns autores a
aperceberem-se do poder da imagem para ajudar à compreensão de certos conceitos. A
título de exemplo, refere-se o livro de Brandt e Dahmen “The Picture Book of Quantum
Mechanics” [Brandt, 2000], que revela a importância dada hoje à visualização no ensino
da Física. Esta obra utiliza várias Figuras tridimensionais para representar, por exemplo,
superfícies com densidade de probabilidade constante do átomo de hidrogênio.
Contudo, a maior diversidade de aplicações é apoiada pelo uso de computadores, como
será visto em seguida.

6.6.7.2 O computador e a aprendizagem da Mecânica Quântica


Vários autores [Redish, 2000] [Rebello, 2000] defendem o uso regular de
ferramentas computacionais de simulação e visualização no ensino, com particular
destaque para a utilização de software que permita a interatividade [Boyce, 1997]. Com
242
efeito, a utilização de recursos computacionais no ensino introdutório da Mecânica
Quântica é uma tendência que tem vindo a crescer rapidamente nos últimos anos.
Existem já vários programas cujo objectivo é auxiliar os estudantes a visualizar alguns
aspectos do mundo microscópico. Atomic Orbitals CD, por exemplo, é um software
multimídia desenvolvido por Y. Wong que permite visualizar a três dimensões as
formas das orbitais do hidrogênio e as densidades eletrônicas, entre outros aspectos.
Rebello e Zollman [Rebello, 2000] também desenvolveram um projeto denominado
Visual Quantum Mechanics, cujo objetivo é introduzir tópicos de Mecânica Quântica,
com a ajuda de simulações, de atividades interativas e de laboratórios, recorrendo a um
mínimo de ferramentas matemáticas. Alguns casos práticos começaram mesmo já a ser
incorporados no contexto de sala de aula, no ensino secundário [Jones, 1999] e no
universitário. Por exemplo, Shotsberger e Vetter [Shotsberger, 2001], da Universidade
de North Carolina, Wilmington, nos EUA, referem a utilização frequente do
HyperChem (software de modelação e visualização de estruturas moleculares) por
alunos, em aulas de Química no ensino secundário, para criar, modificar e medir
estruturas moleculares. Aqueles autores defendem que os alunos devem ter um papel
activo na utilização das ferramentas computacionais.
Uma das tecnologias computacionais recentes é a realidade virtual. Apontada
como um poderoso instrumento de ensino e treino, esta tecnologia disponibiliza uma
vertente inovadora, quer através da interação com modelos tridimensionais quer através
de experiências multisensoriais [Trindade, 1999]. O grande interesse por esta área
permitiu a sua especialização em vários setores e a possibilidade de diferentes
combinações. Uma dessas possibilidades é a realidade aumentada.
Considerada uma variante da realidade virtual, a realidade aumentada
disponibiliza um tipo não convencional de interface, que permite misturar imagens de
um ambiente real, obtidas por câmara de vídeo ou por outro processo, com objetos 3-D
virtuais, enriquecendo a visão do usuário. No ambiente assim gerado, o utilizador tem a
sensação de que os objetos reais e virtuais coexistem no mesmo espaço na medida em
que os objetos virtuais são passíveis de visualização e de interação como se existissem
no mundo real. Desta forma, a realidade aumentada enfatiza a visualização em conjunto
com a interação, pois, com o auxílio de dispositivos de visualização mais ou menos
imersivos, objetos virtuais podem ser sobrepostos ao ambiente real, de maneira
altamente realista, incrementando a percepção do usuário [Trindade, 1999].
243
Vários trabalhos têm sido desenvolvidos com o intuito de avaliar as
potencialidades da realidade virtual no ensino e na aprendizagem das ciências. Por
exemplo, o Centro de Física Computacional da Universidade de Coimbra, em
colaboração com o Exploratório Infante D. Henrique e o Departamento de Matemática
da Universidade de Coimbra, desenvolveram um ambiente virtual sobre a estrutura da
água denominado Água Virtual. Trata-se de um programa que aborda conceitos
relacionados com fases de água, transições de fase, agregados moleculares, estruturas de
gelo para além da visualização de elementos básicos de mecânica quântica como
orbitais atômicas do átomo de hidrogênio e orbitais moleculares da água. O programa é
voltado para alunos dos anos terminais do ensino secundário e do primeiro ano do
ensino superior e pode ser disponibilizado gratuitamente a pedido [ Água Virtual, 2004].
O Orbitário
O Orbitário [Trindade, 2004] é destinado ao estudo de orbitais hidrogenóides,
num nível introdutório, e encontra-se no início da sua avaliação. A escolha da Mecânica
Quântica encontra a sua justificação nas razões anteriormente invocadas, nomeadamente
a exploração de conceitos abstractos, que são ensinados nas aulas, mas para os quais não
existem modelos de referência acessíveis (conceitos de orbital e de densidade
eletrônica) [Barton, 1997] [Story, 1998]].
O programa foi desenvolvido com o ARToolKit, que é o software livre
normalmente utilizado para desenvolver aplicações de realidade aumentada. Trata-se de
uma ferramenta de código aberto com frequentes atualizações, encontrando-se acessível
em vários sites [Kato, 2003] .
Um procedimento fundamental no desenvolvimento da aplicação consiste na
sobreposição dos modelos virtuais (as orbitais) com o ambiente real (por exemplo, o
manual). Para tal, é preciso obter a posição e a orientação dos objetos da cena real e
associá-los com os modelos previamente armazenados no computador. Isto é
normalmente conseguido com o recurso a determinados padrões, isto é, placas com
marcas fiduciais que contém símbolos para se diferenciarem uma das outras, tornando-
as singulares.
Usando como exemplo a associação do modelo da orbital 2p à respectiva marca
fiducial (Figura 6), a imagem da placa fiducial, captada por uma webcam, é convertida
para um formato binário. Uma vez reconhecido o padrão, é calculada a posição e
orientação do marcador relativamente à webcam. O modelo da orbital associado ao
padrão é identificado e é feito o rendering do modelo virtual no vídeo. O modelo da
244
orbital (estático ou dinâmico) irá aparecer sobreposto ao respectivo padrão e a sua
representação poderá ser feita de forma imersiva (num capacete de visualização ou
óculos com ou sem estereoscopia) ou de forma não imersiva no monitor do computador
(Figura 6-33). Ao manipular a placa (que pode estar incorporada num livro de texto), o
objeto virtual realizará os mesmos movimentos da placa, como se a ela estivesse preso.

Figura 6-33 - Sobreposição do modelo virtual ao objecto real tomando como exemplo a
orbital 2p x.
A webcam capta o padrão pré-definido e converte-o para um formato binário
para reconhecimento. O modelo da orbital associado ao padrão é identificado e é
calculada a posição e a orientação do marcador relativamente à webcam. Finalmente
efetua-se o rendering do modelo virtual no vídeo que aparecerá sobreposto ao
respectivo marcador.
245

Figura 6-34 – modelo de orbital


Uma vez reconhecido o padrão, o modelo da orbital (estático ou dinâmico) irá
aparecer sobreposto ao respectivo marcador e a sua representação poderá ser feita, por
exemplo, de forma não imersiva no monitor do computador; b) Ao manipular a placa
(que pode estar incorporada num manual), o objeto virtual realizará os mesmos
movimentos do marcador, como se a ele estivesse preso.
Como o ARToolKit usa código aberto, foi possível desenvolver recursos
adicionais no código referentes à interação da aplicação e à implementação de som.
No que toca à interação, é possível alterar o modelo virtual, a partir da
introdução de uma placa adicional de controle. A alteração dinâmica do objeto virtual, a
partir da introdução de uma placa adicional de controle, consiste na utilização de uma
placa que possa interferir no objeto virtual de outra placa, de modo a trocá-lo ou alterá-
lo, o que viabiliza a associação de mais objetos virtuais a uma só placa, de acordo com a
necessidade da aplicação. Isto permite, por exemplo, que se possa visualizar a mesma
orbital mas para diferentes orientações espaciais ou para diferentes distribuições de
densidade eletrônica.
Esta (simples) interação, que consiste apenas na troca de uma placa de controle,
é acompanhada de som que explica as alterações visíveis no modelo, como por exemplo
a variação da densidade eletrônica. Com a inserção do som, consegue-se com a
modificação do ARToolKit para que seja executado o arquivo de áudio com o
surgimento do objeto virtual, quando se introduz a placa em frente à câmara.
246
Assim, foi possível combinar num ambiente o melhor da exibição bidimensional
(dos manuais) com a exibição computacional 3D, apelando-se a uma utilização conjunta
do livro de texto e do computador, contrariamente ao que habitualmente acontece com a
utilização do software.

6.6.8 Conclusões
Em atividades educativas com uso de recursos computacionais, é necessário o
planejamento adequado do uso de tecnologias em software e hardware, que possibilitam
explorar: a carga cognitiva do usuário, o senso de observação, a atenção, a exploração e
a retenção de informações, utilizando elementos de percepção visual, tátil e auditiva.
Para isso, é necessário desenvolver sistemas computacionais que apresentem: 1)
facilidade na identificação dos componentes; 2) adaptabilidade ao nível do usuário; 3)
adequação dos programas às necessidades curriculares; 4) existência de recursos
motivacionais; 5) posssibilidade constante de alterações do sistema (inclusão de novos
elementos); 6) fornecimento de retorno; 7) integração do sistema com outros recursos;
8) capacidade de armazenamento de respostas; 9) registro de tempo de resposta e
latência e 10) liberdade de manipulação e navegação - controle sobre os elementos.
Uma das vantagens do uso da Realidade Aumentada é a possibilidade de
criar interfaces multisensorias, sem a necessidade de periféricos de alto custo, como
óculos e capacete de visualização, luva, caverna (CAVE), utilizados em experimentos
de realidade virtual. Com isto, é possível o desenvolvimento de ambientes relevantes e
interessantes para o usuário, utilizando materiais acessíveis e disponíveis nos
laboratórios de informática das escolas.
Considerando a importância do processo de construção do conhecimento
para a formação do indivíduo, os ambientes de realidade aumentada podem contribuir
de forma a oferecer condições de experimentar, criar, descobrir, sem instruções
previamente elaboradas ou definidas pelo sistema, pois o ambiente funciona como
mediador, auxiliando o educando na descoberta e construção do novo.
A construção do ambiente gráfico ficou muito mais simplificada e rápida,
reduzindo-se exclusivamente ao que é essencial: os modelos que se pretendem explorar
no ensino e aprendizagem.
A tecnologia envolvida desempenha um papel muito menos dominante e
distrativa para o aluno. Tal como referido por Cornu [Cornu, 1995], “as novas
tecnologias apenas estarão integradas no ensino quando elas não forem ferramentas
247
suplementares mas sim quando elas se tornarem ‘naturais’ e ‘invísiveis’ como o
telefone, o televisor e as calculadoras de bolso. As novas tecnologias só estarão
realmente integradas na pedagogia quando, dessa união, surgirem novos métodos
pedagógicos bem sucedidos”.

6.7 REFERENCIAS BIBLIOGRÁFICAS

Agua Virtual (2004) http://aguavirtual.mediaprinter.pt


Akagui, D.; Kirner, C. (2004) “LIRA - "Livro Interativo com Realidade Aumentada", Proc.
of VII Symposium on Virtual Reality, SP, outubro de 2004.
Allendoerfer, R. (1990) "Teaching the shapes of the hydrogenlike and hybrid atomic
orbitals". Journal of Chemical Education, 67 (1990) 37-40.
Azuma, R. (1997) "A Survey of Augmented Reality", Presence: Teleoperators and Virtual
Environments, vol. 6, 4, August 1997), p. 355-385.
Azuma, R, et al. (2001) "Recent Advances in Augmented Reality". IEEE Computer
Graphics and Applications, November/December 2001, vol. 21, p. 34-37.
Baranauskas, M. C. C.; Rocha, H. V. (2003) "Design e Avaliação de Interfaces
Humano–Computador". Campinas – SP: NIED/UNICAMP, 2003.
Barton, G. (1997) "Quantum dynamics of simple systems". Contemporary Physics, 38
(1997) 429-430.
Boyce, W. (1997) "Interactive Multimedia Modules in Mathematics, Engineering, and
Science". Computers In Physics, 11 (1997) 151-157.
Brandt, S., Dahmen, H. (2000) "The Picture Book of Quantum Mechanics". Springer,
NewYork (2000).
Cornu, B. (1995) "New technologies: integration into education". In D. Watson e D.
Tinsley (Eds.), Integrating Information Technology into Education. Chapman & Hall,
New York (1995).
Dainese, C.A., Garbin, T.R. e Kirner, C. (2003) "Sistema de Realidade aumentada para o
Desenvolvimento da Criança Surda", In:VI Symposium on Virtual Reality:, 2003.
Ribeirão Preto - SP. SBC, 2003. p.273-281.
Galana, S.C., Silva, R.R.P.C.L., Kirner, C. (2004) “Autoria Colaborativa de Mundos
Virtuais Educacionais com Realidade Misturada” Anais do 1o Workshop de Realidade
Aumentada, Piracicaba, SP, maio de 2004, p. 17-20.
Garbin, T.R., Dainese, C.A., Kirner, C., Santos, A.M., Jesus, M.A. (2004) “Avaliação de
Interface de um Sistema de Realidade Aumentada para a Criança Surda com base no
Construcionismo” Anais do 1o Workshop de Realidade Aumentada, Piracicaba, SP,
maio de 2004, p. 33-36.
Hurwitz, C., Abegg, G., Garik, P., Nasr, R. (1998) "High school students’ understanding of
the quantum basis of chemistry". J. of Research in Science Teaching, 34(1998) 535-545.
Jones, L. (1999) "Learning Chemistry through design and construction. UniServe Science
News", 14 (1999) 3-7.
248
Kato, H.; Billinghurst, M.; Poupyrev, I. (2003) "ARToolKit version 2.33 Manual",
Nov.,2003.http://www.hitl.washington.edu/research/shared_space
Lahr. P; Lourenço, P. C.; Dainese, C. (2004) “Desenvolvimento de uma ferramenta para
Rastreamento em Sistemas de Realidade Aumentada”. Anais do I WorkShop sobre
Realidade Aumentada – WRA 2004, UNIMEP, Maio, 2004, 37-40.
Lévy, P. (1999) "O que é virtual?", Tradução de Paulo Neves, São Paulo: Ed. 34, 1999.
Rebello, N., Zollman, D. (2000) "Conceptual understanding of quantum mechanics after
using hands on experiments and visualization instructional materials". In Annual
Meeting National Association for Research in Science Teaching, Boston
(http://www.phys.ksu.edu/perg/papers/narst, Novembro de 2000).
Redish, E., Bao, L. (2000) "Student difficulties with energy in quantum mechanics". In
AAPT Winter Meeting, Phoenix (http://www.physics.umd.edu/perg/cpt.html,
consultado em Outubro de 2000).
Shotsberger, P., Vetter, C. (2001) "Teaching and learning in the wireless classroom.
Computer", 34 (2001) 110-111.
Santin, R.; Kirner, C. (2004) “Desenvolvimento de Técnicas de Interação para Aplicações
de Realidade Aumentada com o ARToolKit”. Anais do I WorkShop sobre Realidade
Aumentada – WRA 2004, UNIMEP, Maio, 2004, 13-16.
Story, R. (1998) "Bridging a quantum-mechanical barrier". IEEE Transactions on
Education, 41 (1998) 54-60.
Trindade, J., Fiolhais, C., Gil, V. (1999) "Virtual Water, an application of virtual
environments as an education tool for physics and chemistry". In G. Cumming, T.
Okamoto, L. Gomez (Eds.), Proceedings of ICCE’99, 7th International Conference on
Computers in Education, Chiba, Japão, (1999) 655-658.
Trindade, J., Kirner, C., Fiolhais, C. (2004) “An Augmented Reality Application for
Studying Atomic Orbitals: Orbitário” Proc. of IADIS International conference on
Cognition and Exploratory Learning in Digital Age, Lisboa, Portugal, Dec., 2004.
Utiyama, F., Kirner, C. (2004) "Rastreamento e Visualização de Trajetórias para
Treinamento com Realidade Aumentada", Proc. of VII Symposium on Virtual
Reality, SP, outubro de 2004.
Valente, J.A. (2001) "Aprendendo para a vida: o uso da informática na educação especial".
In Valente, J.A.Aprendendo para a vida: os computadores na sala de aula. São Paulo.
Cortez Editora, p.29-42, 2001.
APPLE, C. FireWire. (http://developer.apple.com/firewire/). 2004.

BERRE, A., INGVALDSEN, K., SYVERINSEN, T. & SALOMONSEN, M.


ARToolKit for Dummies, 2002. (http://rasmus.uib.no/~st02204/HCI/).

CAREY, R. & BELL, G. The Annotated VRML 2.0 Reference Manual. Addison-
Wesley, 504pp, 1997.
249
DAVIS, L., CLARKSON, E. & ROLLAND, J.P. Predicting Accuracy in Pose
Estimation for Marker-based Tracking. In: Proceedings of the Second IEEE and
ACM International Symposium on Mixed and Augmented Reality (ISMAR '03),
Tokyo, Japan, p28-35, 2003.

GEIGER, C., REIMANN, C., STICKLEIN, J. & PAELKE, V. JARToolKit - A Java


binding for ARToolKit. In: The First IEEE Augmented Reality ToolKit
International Workshop, p124, 2002.

HARTLEY, R. & ZISSERMAN, A. Multiple View Geometry in Computer Vision.


Cambridge University Press, 655pp, 2003.

KATO, H. Inside ARToolKit. 2002. (http://www.ikg.uni-hannover.de/lehre/katalog/


Augmented_Reality/pdf_files/ART02-Tutorial.pdf)

KATO, H. & BILLINGHURST, M. Marker Tracking and HMD Calibration for a


Video-based Augmented Reality Conferencing System. In: Proceedings of the
2nd IEEE and ACM Internationall Workshop on Augmented Reality, San
Francisco, CA, USA, p85-94, 1999.

KATO, H., BILLINGHURST, M. & POUPYREV, I. ARToolKit Version 2.33, 44pp,


2000. (http://www.hitl.washington.edu/people/grof/SharedSpace/Download/AR
ToolKit2.33doc.pdf).

KE, X. Tutorial: Installation of the ARToolkits and the relevant hardware (Version
2.11), 2000. (http://www.ece.nus.edu.sg/stfpage/eleadc/ARToolkit-tutorial-
v2.pdf).

MALBEZIN, P., PIEKARSKI, W. & THOMAS, B.H. Measuring ARToolKit


Accuracy in Long Distance Tracking Experiments. In: Proceedings of the 1st
Augmented Reality Toolkit Workshop, Darmstadt, Germany, p124-125, 2002.

MICROSOFT, CO. Introduction to DirectShow. http://msdn.microsoft.com/library/


default.asp?url=/library/en-us/directshow/htm/introductiontodirectshow.asp.
2004.
250
MICROSOFT, CO. Microsoft Vision SDK, Version 1.2. http://msdn.microsoft.com/
library/default.asp?url=/library/en-us/dnvissdk/html/vissdk.asp. 2000.

MICROSOFT, CO. WDM: Introduction to Windows Driver Model.


http://www.microsoft. com/whdc/archive/wdm.mspx. 2002.

MORLEY, C. LibVRML97 / Lookat. http://www.vermontel.net/~cmorley/vrml.html .


2000.

NOMAD ELECTRONICS.COM. Capture using Video for Windows. http://www.


nomadelectronics.com/VidCap/Capture using VFW/captureVFW.htm. 2004.

OPENVRML.ORG. OpenVRML. http://www.openvrml.org/. 2003.

OWEN, C.B., XIAO, F. & MIDDLIN, P. What is the best fiducial? In: Proceedings
of The First IEEE Augmented Reality Toolkit International Workshop, p124,
2002.

SGI OpenGL. Ver. 1.4. Silicon Graphics Incorporated, 2003.


(http://www.opengl.org/)

WAGNER, D. & SCHMALSTIEG, D. ARToolKit on the PocketPC platform. In:


Proceedings of the 2nd Augmented Reality Toolkit Workshop, p14-15, 2003.
251

Alice: uma Ferramenta de Autoria


Jennifer Lima, Veronica Teichrieb, Judith Kelner

Universidade Federal de Pernambuco, Centro de Informática


CP 7851, Cidade Universitária, 50732-970, Recife, Pernambuco, Brasil
{jsml,vt,jk}@cin.ufpe.br

7 – Introdução à ferramenta Alice

7.1 O que é Alice?


Alice é um software que auxilia na construção de mundos virtuais 3D compostos
por objetos gráficos que têm comportamentos associados que mudam com o tempo.
Objetos em Alice podem mover, girar, mudar de cor, emitir sons, reagir ao mouse e
teclado, e muito mais.
Alice não é uma ferramenta de modelagem de objetos 3D ou um software de
CAD (projeto auxiliado por computador). Os objetos 3D em Alice podem ser
construídos usando ferramentas comerciais de terceiros; todavia, Alice já vem com
muitos objetos 3D pré-construídos e existem vários outros disponíveis na internet
gratuitamente.
As primeiras versões de Alice permitiam a construção de mundos virtuais
através da utilização da linguagem Alice, baseada em Python. Atualmente, Alice é uma
ferramenta de autoria, com um ambiente de desenvolvimento embutido, na qual o
usuário pode construir mundos virtuais através da interface gráfica da ferramenta ou
usando a linguagem Alice.

7.2 Configurações necessárias e instalação


Para que não haja problemas na execução do programa Alice, as seguintes
configurações são necessárias:
 Sistema operacional: Windows ME, Windows 2000 ou Windows XP;
 Hardware mínimo: Pentium 500 MHz ou superior, placa gráfica VGA, 128
MB de RAM e placa de som;
 Hardware recomendado: Pentium 1.0 GHz ou superior, placa de vídeo 3D
16 MB, resolução de 1024 x 768 e 256 MB de RAM.
252
A versão mais atualizada do Alice é a Alice v2.0 beta que se encontra disponível
em http://www.alice.org/downloads/authoringtool/. Neste site, os usuários podem fazer
o download do Alice gratuitamente observando as seguintes instruções:
 Leia o Alice End User License Agreement disponível em
http://www.alice.org/downloads/license.html.
 Faça o download através de
http://www.alice.org/downloads/authoringtool/AliceInstall.exe escolhendo a
opção Save to Disk e especificando o diretório onde você deseja salvar o
AliceInstall.exe.
 Quando o download estiver concluído, localize e instale o Alice v2.0 através
do arquivo AliceInstall.exe.
 Quando a instalação estiver concluída, o ícone do Alice aparecerá na sua
área de trabalho.
 Qualquer problema encontrado durante a instalação pode ser comunicado
através do e-mail alice-admin@cs.cmu.edu.
253

7.3 Conceitos básicos

7.3.1 O ambiente do Alice


A interface do Alice está dividida em cinco áreas principais. Estas áreas são as
seguintes:
World Window: mostra ao usuário o mundo que está sendo construído ( Figura
7-1 ). É nesta área também que se localizam os controles da câmera. Estes controles
permitem ao usuário mudar o modo de visualizar o mundo.

Figura 7-1 − World Window


Object Tree: contém a lista de objetos que fazem parte do mundo que está
sendo construído (Figura 7-2).

Figura 7-2 - Object Tree


Details Area: fornece informações mais detalhadas sobre o mundo ou sobre os
objetos que pertencem ao mundo (Figura 7-3).
254

Figura 7-3 - Details Area


Events Area: permite dizer a Alice quando os objetos farão certas coisas (Figura
7-4). Esses eventos serão programados pelo usuário.

Figura 7-4 - Events Area


Editor Area: permite que os usuários programem os objetos pertencentes ao seu
mundo para que eles façam certas coisas como mover ou girar (Figura 7-5).
255

Figura 7-5 - Editor Area

7.3.2 Utilização de mundos exemplo


Para carregar um mundo em Alice, basta ir ao menu File (Arquivo) e escolher
Open World (Abrir Mundo), como mostrado na Figura 7-6:

Figura 7-6 - Abrindo um mundo


Depois disso, através desta caixa de diálogo, será possível escolher e abrir um
mundo que vem com Alice. O mundo escolhido é carregado como mostrado na Figura
7-7.
256

Figura 7-7 - Mundo exemplo carregado


Para visualizar o que o mundo pode fazer, basta clicar no botão Play. A janela
mostrada na Figura 7-8 aparecerá e as ações serão executadas.

Figura 7-8 - Execução do mundo exemplo


A visualização das informações referentes a cada objeto pode ser realizada de
duas maneiras:
 Selecionando o objeto na Object Tree como mostrado na Figura 7-9.
257

Figura 7-9 - Objeto selecionado


 Selecionando o objeto na Opening Scene como mostrado na Figura 7-10.

Figura 7-10 - Objeto selecionado


Depois de selecionado o objeto, a Details Area mostrará mais informações sobre
o mesmo. Como mostrado na Figura 7-11, a Details Area possui três guias com
informações. A primeira guia, chamada properties, permite a visualização de
informações referentes às propriedades físicas dos objetos selecionados. A segunda
guia, chamada methods, indica quais habilidades o objeto possui. A terceira guia,
chamada questions, possui questões, sobre eles mesmos e o mundo, para as quais os
objetos podem responder.
258

Figura 7-11 - Detalhes de um objeto

7.3.3 Introdução à interface “drag-and-drop” do Alice


A interface “drag-and-drop” é utilizada para escrever o roteiro que o mundo irá
executar. Para realizar essa operação devemos seguir os seguintes passos:
1) Na ObjectTree, clicar no objeto que se quer comandar para obter mais
informações sobre o mesmo, como mostrado na seção anterior;
2) Na Details Area, clicar em Methods para saber o que o objeto pode fazer;
3) Então, escolhe-se uma ação na Details Area e arrasta-a para a Editor Area,
especificando os parâmetros do comando (comandos serão explicados
detalhadamente na seção 6).
Como exemplo, a Figura 7-12 mostra a inserção do comando jump no roteiro
executado pro este mundo exemplo.
Para ver a execução do comando, basta clicar no botão play. Uma nova janela
aparecerá e o comando será executado.
259

Figura 7-12 – Drag-and-drop de comandos

7.3.4 Coleção de objetos


Alice possui uma coleção de objetos pré-definidos que vêm junto com os
arquivos de instalação e podem ser inseridos nos mundos que estão sendo criados. Além
desses objetos, os usuários podem encontrar outras centenas deles disponíveis na
internet através do site http://www.alice.org/gallery/index.html.
A janela para inserir objetos é mostrada a seguir, na Figura 7-13.

Figura 7-13 - Inserindo objetos


Para adicionar objetos ao seu mundo basta clicar no botão AddObjects que está
localizado na área World Window. Aparecerá a janela mostrada na Figura 7-14:
260

Figura 7-14 - Local Gallery


Nesta janela, você irá escolher o tipo de objeto que deseja acrescentar ao seu
mundo. Vamos escolher, por exemplo, Animals. Quando clicarmos em Animals a janela
apresentada na Figura 7-15aparecerá:

Figura 7-15 - Animals


Então basta escolher o objeto a ser acrescentado. Vamos escolher, por exemplo,
Bunny. A janela mostrada na Figura 7-16 aparecerá.

Figura 7-16 - Bunny


Nesta janela podemos visualizar informações como o tamanho em bytes do
objeto e o número de partes que ele possui (partes de objetos serão discutidas na seção
7.6).
261
Para adicionar o objeto ao mundo basta clicar no botão Add instance to world e
ele fará parte do mesmo como mostrado na Figura 7-17.

Figura 7-17 - Objeto adicionado ao mundo


Quando adicionado ao mundo, o objeto pode ser visto de várias perspectivas
como mostrado na Figura 7-18.

Figura 7-18 - Visualização quadro a quadro


Uma outra maneira de adicionar objetos é utilizando a interface “drag-and-
drop”. A utilização desta interface permite o posicionamento do objeto em qualquer
posição da cena de abertura e não no seu centro como acontece na maneira de adicionar
anterior.

7.3.5 Usando o mouse


O mouse pode ser usado para mover os objetos pelo mundo. Basta clicar no
objeto que se quer mover e deslocá-lo para onde se deseja. Ele é bom para
262
posicionamentos rápidos e não muito precisos. Para precisão, o melhor seria utilizar
comandos. Além disso, objetos têm menus para comandos que você pode acessar com o
botão direito do mouse.
Alice permite a movimentação dos objetos através do mouse de várias maneiras
como mostrado na Figura 7-19do (1) ao (6).

(1) Para cima e para baixo (2) Girar para direita e para esquerda

(3) Girar para frente e para trás (4) Girar ao redor do próprio eixo

(5) Redimensionar (6) Copiar objeto


Figura 7-19 - Movimentação dos objetos através do mouse

7.3.6 Introdução aos comandos Alice


Os objetos em Alice podem obedecer a comandos na linguagem Python. Esta
linguagem é muito simples e o programador não terá dificuldades em aprendê-la até
porque os comandos são utilizados explicitamente na interface “drag-and-drop”.
263
Ao longo desta apostila serão explicados os mais importantes comandos em
Python e no Apêndice I você encontrará um resumo desses comandos.
O primeiro comando que iremos aprender é o comando move. Este comando
permite mover objetos em uma determinada direção, a uma determinada distância. A
sua assinatura é: objeto.move(direção, distância). Por exemplo: bunny.move(forward,
1).
Um outro comando importante é o comando turn. Este comando permite girar
objetos em uma determinada direção, um determinado número de voltas. A sua
assinatura é a seguinte: objeto.turn(direção, voltas). Por exemplo: bunny.turn(left, 1/4).
Objetos em Alice podem mover forward, back, left, right, up, and down,
equivalentes ao português frente, trás, esquerda, direita, cima, e baixo, respectivamente.
As seis direções se referem ao objeto em movimento: o coelho se moveu para a
esquerda dele, não a nossa (Figura 20).
Dica: para saber em que direção um objeto Alice irá se mover ponha-se no lugar
desse objeto e use seu próprio senso de esquerda/direita e frente/trás para "simular" o
movimento que você quer.

Figura 7-20 - Direções do movimento

7.3.7 Partes de objetos


Objetos em Alice têm partes, e estas partes podem ter partes, e assim por diante.
Para ver quais são as partes de cada objeto, clique no sinal de mais (+) na Object Tree
(Figura 7-21).
264

Figura 7-21 - Objetos com partes


O nome da parte de um objeto é simplesmente o nome do objeto, seguido de um
ponto, e seguido pelo nome da parte (objeto.parte).
Um exemplo de comandos em partes dos objetos é o seguinte:
IceSkater.ThighL.pointat(Camera)
Este é o nosso terceiro comando. O comando PointAt é usado para fazer um
objeto ou uma de suas partes apontar para um ponto específico.
A sua assinatura é a seguinte: objeto.pointat(ponto específico).

7.4 – Construindo mundos em Alice

7.4.1 Mundos existentes

7.4.1.1 World Window


Um mundo Alice tem duas partes: a cena de abertura e o roteiro. As áreas World
Window e Editor Area dão acesso às duas partes deste mundo. A cena de abertura a que
nós nos referimos pode ser comparada a uma cena de abertura de uma peça teatral: o
palco está montado, os atores estão no lugar, mas a ação ainda não começou.
Resumindo, é como o mundo está antes de o roteiro ser executado. Um exemplo de cena
de abertura pode ser visualizado na Figura 7-22 .
265

Figura 7-22 - Opening Scene

7.4.1.2 Manipulação da câmera


A maneira como a cena de abertura é visualizada pode ser mudada manipulando
a câmera. Através de alguns botões na área World Window (Figura 7-23), você pode
deixar o mundo da maneira desejada.

Figura 7-23 - Controles da câmera

7.4.1.3 Editor Area


A Editor Area comanda o roteiro. Um roteiro Alice é como um roteiro para uma
peça. Ele descreve a ação que acontecerá. Em Alice, um roteiro é uma coleção de
comandos Alice que dizem aos objetos no mundo o que fazer e como fazê-lo. Na Figura
7-24 é mostrado um exemplo de como um roteiro com comandos Alice é construído.
266

Figura 7-24 - Roteiro composto por comandos

7.4.1.4 Como mudar um mundo


Os mundos em Alice são fáceis de mudar. Mudar qualquer parte de um mundo
Alice produz um mundo novo e diferente.
Mudar a cena de abertura causa mudança na posição inicial de objetos, enquanto
mantêm-se os mesmos comandos do roteiro.
Mudar o Roteiro altera o que os objetos no mundo fazem, embora iniciem nas
mesmas posições.
A posição dos comandos no roteiro também pode ser alterada acarretando em
uma mudança total no resultado da simulação.

7.4.1.5 Mudando a cena de abertura


A cena de abertura pode ser modificada acrescentando-se novos objetos,
modificando a posição de objetos já existentes através do mouse ou mudando a posição
inicial da câmera.
Lembrando que como apenas a cena de abertura foi modificada, os objetos
continuarão executando o mesmo roteiro.

7.4.1.6 Mudando o roteiro


Para modificar o roteiro podemos criar uma nova ação, refazer uma ação já
existente ou trocar a ordem das ações que estavam sendo executadas.
267
Lembrando que como estamos trocando apenas o roteiro, os objetos irão iniciar
do mesmo modo que anteriormente.

7.4.1.7 O comando DoInOrder


Todos os comandos de um roteiro Alice são executados ao mesmo tempo. Nós
precisamos de uma maneira para dizer a Alice para executar um comando após o outro.
O comando DoInOrder aceita uma lista de comandos que podem ser executados
em ordem (um após o outro).
A sua assinatura é a seguinte: DoInOrder(comando, comando, comando).
Por exemplo: DoInOrder(snowman.move(forward, 1), oven.door.turn(down,
1/4))
Para acrescentá-lo ao roteiro, basta fazer o “drag-and-drop” do comando, como
mostrado na Figura 7-25

Figura 7-25 - Comando DoInOrder

7.4.1.8 O comando DoTogether


O comando DoTogether pega uma lista de comandos Alice para executar (da
mesma maneira que o comando DoInOrder). Contudo, o comando DoTogether executa
todos os comandos da lista ao mesmo tempo.
A sua assinatura é a seguinte: DoTogether(comando, comando, comando).
268
Por exemplo: DoTogether(cementtruck.resize(fronttoback, 2, likerubber),
cementtruck.move(forward, 1))
Alice irá executar esses dois comandos simultaneamente.
Este é o nosso sexto comando. O comando resize torna um objeto maior ou
menor. A sua assinatura é: objeto.resize(quantia).
Um exemplo de utilização do comando DoTogether pode ser visualizado na
Figura 7-26.

Figura 7-26 - Comando DoTogether

7.4.2 Mundos novos

7.4.2.1 Criação
Você já está pronto para aprender a criar seu próprio mundo do zero. Para isso
você precisa de um mundo novo e limpo para começar. Selecione New World (Novo
Mundo) a partir do menu File (Figura 7-27).
269

Figura 7-27 - Novo mundo


Quando selecionada a opção New World, a tela mostrada na Figura
7-28aparecerá. O usuário pode então escolher qual será o plano de fundo da sua cena de
abertura. Para isso, basta clicar no plano de fundo escolhido e depois em Open.

Figura 7-28 - Templates do plano de fundo


270
7.4.2.2 Ajustando a cena de abertura
A cena de abertura aberta dependerá do escolhido pelo usuário na hora da
criação do novo mundo. Um exemplo pode ser visualizado abaixo:

Figura 7-29 - Cena de abertura


Para ajustar a cena de abertura pode-se acrescentar novos objetos, modificar a
posição de objetos que já foram acrescentados através do mouse ou mudar a posição
inicial da câmera através dos botões de manipulação de câmera.

7.4.2.3 Escrevendo o roteiro


Para escrever o roteiro pode-se usar o “drag-and-drop” de comandos Alice.
Com esses comandos, você irá “ensinar” aos objetos de um mundo Alice a fazer coisas
novas. As histórias podem ser construídas combinando os comandos e colocando-os em
uma ordem lógica.
A história é sobre um coelhinho que está dormindo, mas é acordado por um
telefone celular (Figura 7-30).

Figura 7-30 - Exemplo de mundo


Vamos tomar como exemplo o roteiro abaixo (Figura 7-31).
271

Figura 7-31 - Roteiro


Vamos acrescentar mais comandos a esse roteiro. Primeiramente, vamos olhar
para a Details Area e observar os métodos que o mundo possui (Figura 7-32).

Figura 7-32 - Métodos


Queremos que o coelhinho pule em cima do celular e o amasse. Como não existe
nenhum método que faça isso, teremos que construí-lo.
Para construir, clica-se em Create New Method e atribui-se um nome ao método.
No nosso caso o nome do método será bunny squashes phone. Depois disso, Alice abre
uma pasta para o método na Editor Area, como mostrado na Figura 7-33.
272

Figura 7-33 - Pasta criada para o novo método


Após isso, olha-se o que o objeto sabe fazer para acrescentar comandos ao
método de modo que ele faça o desejado. No nosso caso fica da seguinte maneira, como
ilustrado na Figura 7-34:

Figura 7-34 - Corpo do novo método


Depois disso, arrasta-se o novo método para o roteiro que fica da seguinte forma
(Figura 7-35):
273

Figura 7-35 - Roteiro final


Através desse roteiro, nossa história acontece como foi planejada.
Normalmente, todos os métodos em Alice levam 1 segundo para executar. Se o
usuário quiser que uma ação demore mais ou menos para ser executada deve ser feito o
seguinte (mais detalhes sobre isso no capítulo 4): a duração da ação deve ser
especificada clicando-se ao lado do comando em more e logo após em duration.
Exemplo na Figura 7-36.

Figura 7-36 - Especificando a duração da ação


Alice permite que o usuário modifique métodos existentes nos mundos exemplo.
Isto pode ser feito através do botão edit encontrado ao lado de cada método. Para isso,
basta clicar em edit e Alice abre uma janela para o método escolhido. Nesta janela,
274
usando a interface “drag-and-drop” pode-se acrescentar ou remover ações. Um
exemplo pode ser visto na Figura 7-37.

Figura 7-37 - Mudando um método

7.4.2.4 Mudanças
As mudanças realizadas na cena de abertura podem ser desfeitas ou refeitas
utilizando o botão undo ou o botão redo, ambos mostrados na Figura 7-38.

Figura 7-38 - Botões Undo e Redo


Alice permite ao usuário desfazer ou refazer as mudanças tantas vezes quanto
for necessário.

7.4.2.5 O comando Loop


Alice possui o comando loop. Quando um comando entra em loop ele se inicia
novamente tão logo termine.
A sua assinatura é a seguinte: loop(comando, número de vezes).
Por exemplo: loop(inchworm, 4).

7.4.2.6 O comando RespondTo


O comando Alice RespondTo diz a Alice ao quê responder e como agir. Ele
serve para deixar o mundo interativo.
275
A sua assinatura é a seguinte: objeto.RespondTo( AoQuêResponder,
ComoAgir).
Por exemplo: cementtruck.respondto(leftmousedown, inchworm).

7.5 Detalhes em comandos Alice

7.5.1 Palavras-chave e dicas

7.5.1.1 A palavra-chave Duration


Palavras-chave são palavras opcionais que aparecem dentro de comandos Alice
e fazem com que os comandos básicos façam coisas mais interessantes. No Apêndice II
estão listadas as mais importantes palavras-chaves.
Duration é um exemplo de palavra-chave. Ela permite que uma determinada
ação demore mais ou menos para ser realizada.
Por exemplo: windmill.blades.roll(right, 1, duration = 3).
Assim, as pás do moinho levarão 3s para girar completamente.
O comando roll permite que o objeto gire para alguma direção, determinado
número de vezes. A sua assinatura é a seguinte: objeto.roll(direção, número de vezes).

7.5.1.2 A palavra-chave Speed


Em vez de usar a palavra-chave Duration para especificar o tempo que as pás
levam para girar, você pode usar a palavra-chave Speed para fazer as pás girarem a uma
velocidade específica.
Por exemplo temos, windmill.blades.roll(right, 1, speed = 1/3).
Assim, as pás do moinho irão girar a uma velocidade de 1/3.

7.5.1.3 A palavra-chave AsSeenBy

Com essa palavra-chave você pode mover ou girar qualquer objeto do ponto de
vista de outro objeto. Por exemplo, podemos fazer um objeto se mover na direção de
outro apenas acrescentando essa palavra-chave ao comando.
Por exemplo, temos, horse.move(forward, 1, asseenby = windmill).
Assim, o cavalo irá se mover na direção do moinho.
276
7.5.1.4 A dica EachFrame
Como palavras-chave, você pode usar dicas para dar aos comandos mais
detalhes. A dica EachFrame serve para que os objetos continuem fazendo um
determinado comando tão freqüentemente quanto possível.
Por exemplo, bunny.head.pointat(helicopter, eachframe).
Assim, a cabeça do coelhinho continuará olhando para o helicóptero até o final
do roteiro.

7.5.2 Interação
Os eventos dizem ao Alice o que fazer e quando fazer. Esses eventos podem ser
um clique do mouse ou o pressionar de uma tecla do teclado. Dessa, forma o mundo
Alice estará interagindo com o usuário.
Vejamos o seguinte exemplo de evento: queremos que quando o mundo se inicie
alguns pingüins comecem a cantar uma pequena música. O evento fica da seguinte
maneira (Figura 7-39):

Figura 7-39 - Evento inicial


Agora vamos criar um outro evento para que quando um pingüim seja
pressionado pelo mouse, ele cante uma nota musical. Para construí-lo temos que
pressionar o botão create new event e escolher “When the mouse is clicked on
something” (Figura 7-40):
277

Figura 7-40 - Mouse Click


Depois, arrasta-se da Details Area o método “penguim sing note” e escolhe-se
que o pinguin que vai cantar a nota é o que o mouse clicar. O evento fica da seguinte
maneira (Figura 7-41).

Figura 7-41 - Novo evento


Então quando o pingüim for clicado ele cantará uma nota musical.
Como pode ser observado, existem botões para reproduzir, parar e gravar as
notas musicais cantadas pelos pingüins. A idéia agora é fazer estes botões funcionarem.
Primeiramente, vamos fazer funcionar o botão play. Para isso, devemos
pressionar o botão create new event e escolher “when mouse is clicked”. Depois disso,
escolhemos o PlayButton como mostrado na Figura 7-42.
278

Figura 7-42 - Inserindo evento


Depois, devemos escolher o que o botão play deve fazer. Deve ser escolhida a
ação play como mostrado na Figura 7-43.

Figura 7-43 - Inserindo evento


O mesmo deve ser feito para os dois outros botões e os eventos finais devem se
parecer com os mostrados na Figura 7-44.
279

Figura 7-44 - Eventos finais


Para deletar qualquer evento ou método do mundo Alice que está sendo
construído, basta utilizar a interface “drag-and-drop” como mostrado na Figura 7-45.

Figura 7-45 - Utilizando a lixeira


Através deste manual, o usuário pôde aprender sobre as principais áreas da
interface do Alice, suas principais funcionalidades e como construir ou editar mundos
em Alice.

7.6 Ajuda
Para aprender mais sobre Alice e o que é possível fazer, sugerimos os seguintes
locais, todos em inglês:
 Tutorial Interativo
O próprio programa Alice possui um tutorial interativo. Basta clicar em “Start
the Tutorial” na caixa “Welcome to Alice”. Você também pode escolher qual
tutorial deseja fazer escolhendo diretamente um dos quatro nos botões abaixo do
botão “Start the Tutorial”.
280
 Seção de Documentação Online
Esta seção contém conselhos para usuários avançados de Alice que completaram
o tutorial interativo e estão procurando por novas idéias e desafios.
 Menu Alice de Help
Este contém o manual de referência Alice, uma fonte exaustiva de informação
sobre funções e opções da Alice. Aqui você também encontrará exemplos e
demonstrações que poderá usar para começar seus trabalhos.
 Lista de correspondência: alice-users@cs.cmu.edu
A lista de correspondência é a melhor maneira de usuários Alice ajudarem
outros usuários. Os criadores de Alice também lêem esta lista, inserindo algumas
respostas e comentários quando necessário.

7.7 Resumo dos comandos


Tabela 1-1 - Comandos

Comando Assinatura do Comando

Move (mover) objeto.move(direção, distância)

Turn (virar) objeto.turn(direção, voltas)

Roll (Girar) objeto.roll(direção, número de vezes)

PointAt (Olhar para) objeto.pointat(ponto específico)

Resize (Redimendionar) objeto.resize(quantia)

objeto.RespondTo( AoQuêResponder,
RespondTo (ResponderA)
ComoAgir)

Loop (Repetir) loop( comando, número de vezes)

DoInOrder (Fazer na ordem) DoInOrder(comando, comando, comando)

DoTogether (Fazer Simultaneamente) DoTogether(comando, comando, comando)

7.8 Palavras-chave que Alice reconhece


Tabela 2-1 - Palavras-chave

Palavra-Chave Valores que a Palavra pode Receber

AsSeenBy (ComoVistoPor) Qualquer objeto no mundo. Você pode mover e girar qualquer
objeto como ele é visto por outro.

Speed (Velocidade) Qualquer número. Para movimeno, este número é metros por
281
segundo, para girar, rotações por segundo.

Style (Estilo) Qualquer destes: Gently, Abruptly, EndGently (or


BeginAbruptly), BeginGently (or EndAbruptly) - significando:
Gentilmente, Abruptamente, TerminaGentilmente (ou
ComeçarAbruptamente), ComeçarGentilmente (ou
TerminarAbruptamente). Você pode usar estas para
descrever como quer que uma animação comece ou termine.

Qualquer número, em segundos. Você pode usar esta


Duration (Duração) palavra para descrever a duração de uma animação. Se você
não disser nada, normalmente levará um segundo.

Qualquer número, em segundos. Para animações que


Lifetime (TempoDeVida) normalmente duram para sempre, você pode usar esta
palavra para parar após um certo tempo.

Qualquer um destes: ObjectAndParts, ObjectAndChildren,


ObjectOnly - significando ObjetoEPartes, ObjetoEFilhos e
SomenteObjeto. Você usa esta palavra quando está pegando
HowMuch (Quanto)
informação sobre um objeto ou quando está mudando as
propriedades de um objeto para descrever quanto do objeto
quer considerar/afetar.
282

8 Modelagem e Implementação de Animações para


Ambientes Virtuais utilizando O.D.E.
Rafael Rieder, Jorge Luis Salvi, Douglas Matté Lise
Jacques Duílio Brancher
rafael@uri.com.br
URI - Campus de Erexim

8.1 Histórico
Uma das principais dificuldades quando se trata da programação de jogos de
computador é a simulação da física aos objetos do ambiente virtual. Colisões, frenagem,
efeitos de gravidade são assuntos até certo ponto complexos de serem tratados pelos
desenvolvedores.
Para suprir tal necessidade, em 2001, surgiu a O.D.E. (Open Dynamics Engine).
A O.D.E. é uma biblioteca open-source, multiplataforma, desenvolvida por Russel
Smith, voltada à simulação de objetos rígidos articulados e dinâmicos. Ela tem um
enfoque ao nível de mercado, demonstrado pela sua qualidade e facilidade em trabalhar
junto com APIs C/ C++ e Delphi.
Ela disponibiliza como principais características à manipulação de fenômenos
físicos como articulação de corpos, gravidade, detecção de colisão e fricção de objetos
em mundos virtuais. Além disto, é possível simular comportamentos tais como uma
prensa hidráulica em operação, motores elétricos, suspensão de veículos, enfim, tudo o
que envolva a física. Outro exemplo prático de sua manipulação são os jogos de corrida,
que apresentam elementos como frenagem, aceleração, atrito e movimentações laterais
presentes em qualquer ação do usuário. Também permite também considera forças,
torques, massa e energia nos corpos, dando mais realismo ao produto em questão.
Assim, este tutorial visa apresentar a comunidade científica um breve apanhado
dos recursos desta biblioteca, associando seu trabalho juntamente com a biblioteca
GLScene, que incorporou seus recursos na versão 2.0, com contribuição de Mattias
Fagerlund.
A estrutura deste material está disposta em uma breve explicação de sua
instalação, seguido da descrição de suas características, acompanhada de exemplos
demonstrativos (com e sem GLScene), finalizando com dicas e procedimentos para a
construção de um ambiente ideal utilizando a física em seus objetos 3D.
283
8.2 Instalação
A seguir, são apresentados os modos de instalação da biblioteca O.D.E. para
desenvolvedores C/ C++ e Delphi, em suas devidas plataformas:

8.2.1 Instalação em C/C++


Plataformas (mínimo):
• MS-Windows, MS Visual C/C ++ 6;
• MS-Windows, MinGW;
• MS-Windows, CygWin;
• Linux (X86, Mandrake 8.1);
• Linux (Alpha, RS/6000 e Sparc Ultra 60, Debian 2.2);
• FreeBSD 4.3 ;
• Mac OS-X ;
• Solaris 8 (Sparc R220).

Download:
• http://www.ode.org/

Passos de Instalação:
1º Passo: Descompacte o arquivo da O.D.E. em um diretório específico;
2º a 4º passo (opcional – para Windows): se você está no Windows e usa o MS Visual
C, você pode usar o workspace e os arquivos de projeto do subdiretório da distribuição
do VC6;
2º Passo: Utilize o GNU Make;
3º Passo: Edite as configurações no arquivo config/user-settings. A lista de plataformas
suportada aparece ali;
4º Passo: Dê um make para configurar e compilar O.D.E. e programas de testes
gráficos. Tenha certeza de que você está usando a versão correta do GNU Make. A
ordem de make segue abaixo:
make configure: cria o arquivo de configuração include/ode/config.h

make ode-lib: compila o core da O.D.E.;

make drawstuff-lib: compila a biblioteca gráfica OpenGL básica;

make ode-test: compila alguns testes já com a O.D.E.;


284
make drawstuff-test: compila uma simples aplicação da biblioteca gráfica.

5º Passo: Para instalar a biblioteca O.D.E. nas suas IDE’s, você deve copiar os
diretórios /lib e /include para o lugar da sua suíte de desenvolvimento (por exemplo):
include/ode/ --> /usr/local/include/ode/
lib/libode.a --> /usr/local/lib/libode.a

8.2.2 Instalação em Delphi


Plataformas (mínimo):
• MS-Windows – Borland Delphi Versões 4, 5, 6 e 7.

Download:
• http://www.glscene.org/

Passos de Instalação:
1º Passo: Descompacte a biblioteca num diretório à parte, dentro do path do Delphi,
preferencialmente, (\arquivos de programas\ borland\ delphi\ glscene);
2º Passo: Em seguida, copie o arquivo “glscene.inc” para dentro do diretório \LIB do
Delphi;
3º Passo: Também copie os arquivos com extensão “dll” para dentro do diretório \BIN
do Delphi;
4º Passo: Acesse o diretório do Delphi e, dentro da pasta criada para a GLScene,
execute os arquivos com extensão “dpk”. Compile e instale-os, na ordem (como
exemplo, Delphi 7):
• GLScene7.dpk (biblioteca padrão);
• GLS_sld7.dpk (plug-in para áudio);
• GLS_fmod7.dpk (plug-in para áudio);
• GLS_bass7.dpk (plug-in para áudio).
• GLS_ode7.dpk (plug-in para a O.D.E.).
5º Passo: Por fim, copie todos os arquivos com extensão “dcu” gerados na compilação
para um diretório chamado “DCU”, dentro do diretório da GLScene. Após isto,
configure o path destes arquivos no menu Tools, opção: \Enviroment Options\Library
Path, adicionando um novo caminho.
285

8.3 Passos básicos


Para se criar qualquer simulação utilizando esta engine é preciso seguir os
seguintes passos:
• Criar um mundo dinâmico onde a física dos corpos irá atuar;
• Criar os corpos no mundo citado acima;
• Definir as propriedades de estado de todos os corpos como, por exemplo, a
posição, a massa, a escala, a força, etc;
• Criar as articulações entre os corpos desejados;
• Fixar as articulações com seus devidos corpos;
• Definir os parâmetros para todas as articulações, tias como: velocidade angular e
linear, ângulos e posições de parada, etc;
• Criar a colisão geométrica dos objetos que estão no mundo;
• Criar grupos de articulações;
• Ao final da simulação destruir os grupos de articulações, as colisões do mundo e
finalmente o mundo.
O mundo é um container para corpos e articulações. A maioria das aplicações
utiliza somente um mundo onde todos os objetos podem interagir entre si. No entanto,
caso existam dois mundos distintos, seus objetos em particular não terão contato entre si
(a menos que você configure para que isto ocorra).
A exemplificação dos passos citados acima pode se verificada na criação de
humanóides, onde para se criar uma perna é preciso ter a coxa, a canela e o joelho,
implementados pela biblioteca como corpo1, corpo2 e articulação1, respectivamente
exemplos. Seqüencialmente a isto, são realizadas as uniões coxa-joelho e joelho-canela
para a aplicação dos parâmetros que darão movimentos a este conjunto.
A cada passo da simulação, é preciso chamar o sistema de colisão, aplicar as
forças nos corpos e ajustar os parâmetros das articulações, para que o mundo esteja
sempre atualizado.
No trabalho de Mojón (Figura 8-1- À esquerda o robô no mundo real e a direita
a simulação com utilização da O.D.E.), é possível verificar a potencialidade da
biblioteca O.D.E. onde é apresentada a simulação de um robô.
Os próximos capítulos tratarão sobre as potencialidades de cada recurso físico,
dispostos na ordem: corpos rígidos, acumulação de força, articulações (joints e
286
constraints), erros de articulações e parâmetro para redução de erros (E.R.P.),
constraints leves e mescla de força em constraints (C.F.M.), fricção e detecção de
colisões.

Figura 8-1- À esquerda o robô no mundo real e a direita a simulação com utilização da
O.D.E.
No material, abordaremos exemplos em alto nível de abstração. Caso prefira
acompanhar este tutorial associando suas construções a exemplos utilizando linha de
código, utilize como material auxiliar o Tutorial O.D.E., escrito pelo seu criador,
disponível em http://www.ode.org/.

8.4 Tipos de Dados e Conversões

8.4.1 Os Tipos básicos de Dados


A biblioteca de O.D.E. pode ser construída para usar números de ponto flutuante
de única ou dupla precisão. Números de precisão única são mais rápidos e usam menos
memória, mas a simulação terá maior erro numérico podendo resultar em problemas
visíveis. Você terá menos exatidão e estabilidade com precisão única.
O dado do tipo ponto flutuante é dReal. Outros tipos geralmente usados são
dVector3, dVector4, dMatrix3, dMatrix4, dQuaternion.

8.4.2 Objetos e identificações


Há os vários tipos do objeto que podem ser criados:
• dWorld – um mundo dinâmico;
• dSpace – um espaço de colisão;
287
• dBody – um corpo rígido;
• dGeom - geometria (usando para colisões);
• dJoint – uma articulação;
• dJointGroup – um grupo de articulações.
As funções que tratam destes objetos fazem exame e retornam a ID do objeto.
Os tipos de IDs dos objetos são dWorldID, dBodyID, etc..

8.4.3 Argumentos de conversão


Todos vetores (x,y,z) que fornecem a função “set” são dados como argumentos
individuais x,y,z.
Todos vetores (x,y,z) resultam seus argumentos para a função “get()” que são
ponteiros para vetores do tipo dReal.
Os vetores maiores sempre são fornecidos e retornados como ponteiros para
vetores do tipo dReal.
Todas as coordenadas são no frame global exceto quando forem de uma outra
froma específica.

8.5 Dinâmica de Corpos Rígidos (Rigid Body Dynamics)


Objetos básicos para o “preenchimento” dos ambientes de simulação 3D. Estes
tipos de objetos, chamados de corpos, podem mover-se dentro dos cenários,
representando simulações de maneira natural e física. Este comportamento dos objetos
sólidos possibilita a percepção, por parte do usuário, de ações do nosso meio ambiente
como gravidade, pressão, elasticidade, colisões, entre outros. Objetos podem colidir,
deslizar, rodar, empurrar o outro, aumentando ainda mais o realismo e a complexidade
das simulações.
Um corpo rígido tem várias propriedades de ponto de visualização na simulação.
Algumas propriedades modificam com o passar do tempo:
• Vetor posicional (x,y,z) do ponto de referência do corpo. Esta referência deve
corresponder ao centro de massa do corpo;
• Velocidade linear do ponto de referência, um vetor (vx,vy,vz);
• Orientação do corpo, representado por um vetor quaternário (qs,qx,qy,qz) ou
uma matriz rotacional 3x3;
• Vetor de velocidade angular (wx,wy,wz) a qual descreve como a orientação
modifica com o passar do tempo.
288

Outras propriedades dos corpos são geralmente constantes no passar do tempo:


• Massa de um corpo;
• Posição do centro de massa a respeito do ponto de referência. A implementação
do centro de massa e do ponto de referência deve coincidir;
• Matriz de Inércia. Esta é uma matriz 3x3 que descreve como a massa do corpo é
distribuída ao redor do centro de massa.

Conceitualmente, cada corpo tem uma estrutura física de coordenadas x,y,z


embutidas em si, que movem e rotacionam com o corpo, conforme mostra a Figura 8-2.

Figura 8-2 - Estrutura física de um corpo rígido. Fonte: O.D.E. Site Oficial.
A origem desta estrutura física de coordenadas é o ponto de referência do corpo.
Alguns valores na O.D.E. (vetores, matrizes, etc) são relacionados a ele, enquanto
outros são relacionados à estrutura de coordenadas globais.
Observe que o shape de um corpo rígido não é uma propriedade dinâmica (a não
ser que várias propriedades maciças influenciem-no). É somente na detecção de colisão
que o detalhamento do shape é cuidado.
Os corpos são conectados um ao outro através de articulações. Uma “ilha” de
corpos é um grupo que não pode ser separado – em outras palavras, cada corpo é
conectado de alguma maneira ao outro formando ilhas de corpos.
Por exemplo, uma chave é conectada a um chaveiro através de uma argola de
metal. Estes três objetos formam uma ilha de corpos. Cada ilha no mundo é tratada
separadamente quando os passos de simulação são realizados.
289
Corpos também podem ser habilitados ou desabilitados, quando se sabe que o
corpo é imóvel ou irrelevante em específico passo da simulação. A desabilitação de
corpos é uma maneira efetiva de economizar tempo de computação.

8.6 Articulações (Joints)


Na vida real, uma articulação (joint) é algo como uma dobradiça, usada para
conectar dois objetos. Na O.D.E. uma articulação é muito similar: é um relacionamento
forçado entre dois corpos, podendo assumir somente determinadas posições e
orientações relativas umas com as outras. Estes relacionamentos são chamados de
constraints. A Figura 8-3 apresenta três diferentes tipos de constraints e suas
articulações:

Figura 8-3 - Três diferentes tipos de constraints. Fonte: O.D.E. Site Oficial.
A primeira é uma articulação ball-and-socket, que pressiona a esfera de um
corpo contra um soquete de outro corpo. A segunda é um hinge que pressiona dois
corpos para uma mesma posição, procurando alinhar ambas ao longo do eixo de uma
dobradiça. O terceiro é um slider que força um pistão a um soquete, alinhados,
adicionando pressão nos dois corpos para manterem-se na mesma orientação.
Cada vez que um passo de simulação é realizado (também chamado de
integração), todas as articulações tornam-se habilitadas a aplicar pressão nos corpos que
afetam. Estas forças são calculadas para que os corpos movam-se coordenadamente,
preservando todos os relacionamentos comuns.
Cada articulação tem um número de parâmetros de controle para suas
geometrias. Um exemplo é a posição de um ball-and-socket para uma articulação ball-
and-socket. As funções de configuração articulam os parâmetros de todas as
coordenadas globais, não relacionadas às coordenadas do objeto. Conseqüência disto é
que os corpos rígidos que têm uma conexão articulada devem ser posicionados
corretamente antes da articulação ser confirmada (união).
Existem também grupos de articulações. Cada grupo de articulações é um
container especial que prende articulações em um mundo. As articulações podem ser
290
adicionadas a um grupo, e quando estas não são necessárias para um grupo inteiro, elas
podem ser rapidamente destruídas com uma única chamada de função.
Entretanto, articulações individuais em um grupo não podem ser destruídas antes
que o grupo inteiro esteja vazio. Isto se torna útil para contato de articulações, os quais
são adicionados e removidos de um mundo a cada simulação.
A articulação inicialmente não tem nenhum efeito de simulação porque ainda
não está conectada a nenhum corpo. O ID do grupo de articulações é zero para alocar
uma articulação normal. Se não for zero, a articulação fará parte de um grupo de
articulações. O contato será inicializado através da estrutura dContact;
Quando se pretende finalizar um mundo, é importante destruir primeiramente
todos os objetos, desconectando suas ligações de corpos e removendo-os do mundo.
Entretanto, se a articulação é membro de um grupo, é necessário eliminar ou esvaziar
(empty) o grupo.

8.6.1 Tipos, parâmetros e configuração de articulações

1.1.1. Ball and Socket


Uma articulação do tipo ball and socket é mostrada na Figura 8-4. A seguir, são
apresentados os passos para a construção desta estrutura:
• Configurar o ponto de ancoragem. A articulação tentará manter-se junto a este
ponto em cada corpo. A entrada é especificada pelas coordenadas do mundo;
• Iniciar o ponto de ancoragem, em coordenadas do mundo. A primeira função
retorna o ponto em corpo1. Se a articulação está correta, o mesmo será
executado para corpo2. A segunda função faz o mesmo, só que de forma
contrária. Ela é mais utilizada para verificar a distância entre as partes a serem
unidas.
291

Figura 8-4 - Articulação Ball and Socket. Fonte: O.D.E. Site Oficial.

8.6.2 Hinge
Uma articulação do tipo hinge (dobradiça) é mostrada na Figura 8-5. A seguir,
são apresentados os passos para a construção desta estrutura:
• Ajustar o ponto de ancoragem do hinge e os parâmetros do eixo;
• Iniciar o ponto de ancoragem, em coordenadas do mundo. Executa o mesmo
processo que o tipo ball and socket, anteriormente destacado;
• Iniciar os parâmetros do eixo;
• Iniciar o ângulo do hinge. O ângulo é medido entre 2 corpos, ou entre um corpo
e um ambiente estático, e está entre –π ... +π. Quando a âncora ou o eixo são
ajustados, a posição corrente dos corpos ligados é examinada, e sua posição
recebe ângulo zero.

Figura 8-5- Articulação Hinge. Fonte: O.D.E. Site Oficial.

1.1.2. Slider
292
Uma articulação do tipo slider é mostrada na Figura 8-6. A seguir, são
apresentados os passos para a construção desta estrutura:
• Criar um mundo dinâmico onde a física dos corpos irá atuar;
• Configurar o parâmetro do eixo slider;
• Iniciar os parâmetros do eixo;
• Ajustar a posição linear do slider. Quando o eixo é ajustado, a posição corrente
dos corpos ligados é examinada, e sua posição recebe ângulo zero.

Figura 8-6- Articulação Slider. Fonte: O.D.E. Site Oficial.

1.1.3. Universal

Uma articulação do tipo universal é mostrada na Figura 8-7.

Figura 8-7 - Articulação Universal. Fonte: O.D.E. Site Oficial.


Uma articulação universal é como um ball-and-socket que pressiona, em grau
extra, rotações livres. Seja um eixo1 sobre um corpo1, e um eixo2 sobre um corpo2,
perpendiculares ao eixo1, a rotação dos dois corpos sobre a direção perpendicular dos
dois eixos será igual. Exemplos deste tipo de articulação: reboques de automóveis e
engates entre vagões de trem.
293
Na figura acima, dois corpos estão articulados juntos por uma cruz de metal. O
eixo1 é ligado ao corpo1, e o eixo2 ligado ao corpo2. A cruz mantém estes eixos em 90
graus: se você segurar e torcer o corpo1, o corpo2 fará o mesmo.
Uma articulação universal é equivalente a um hinge-2, onde os eixos do hinge-2
são perpendiculares um ao outro, com a conexão rígida perfeita no lugar da suspensão.
As articulações universais que são encontradas em carros, mais especificamente
em colunas de direção. Em algum ponto desta, surge a necessidade de uma mudança na
direção. O problema é que se houver apenas uma dobra, a parte posterior não
rotacionará sobre si própria. Por outro lado, se for inserida uma articulação universal, é
possível usar uma restrição para forçar a segunda parte da coluna, rotacionando sobre o
mesmo ângulo, bem como a primeira parte.
Outro uso deste tipo de articulação é na união dos braços ao corpo de um
simples personagem. Imagine uma pessoa mantendo seus braços esticados. Você pode
movimentar os braços para cima e para baixo, para frente e para trás, mas não pode
rotacionar sobre seu próprio eixo.
Os passos para a construção desta estrutura são os seguintes:
• Ajustar a âncora e os parâmetros do eixo. Eixo1 e Eixo2 devem ser
perpendiculares um ao outro;
• Iniciar o ponto de ancoragem. Será retornado o ponto de um dos corpos, e, se a
articulação estiver perfeitamente correta, o mesmo será executado para o outro
corpo;
• Iniciar os parâmetros dos eixos.

8.6.3 Hinge-2
Uma articulação do tipo hinge-2 é mostrada na Figura 8-8.
294
Figura 8-8 - Uma articulação hinge-2. Fonte: O.D.E. Site Oficial.
A articulação hinge-2 equivale a dois hinges conectados em série, com a
diferença em seus eixos. Um exemplo, mostrado na figura acima, é o sistema de direção
das rodas de um carro, onde um dos eixos permite que a roda seja guiada e o outro
permite que a roda gire.
A articulação hinge-2 tem um ponto de ancoragem e dois eixos. O eixo1 está
relacionado ao corpo1 (onde o corpo1 é o chassi do veículo), enquanto o eixo2 está
relacionado ao corpo2 (onde o corpo2 é a roda).
O hinge-2 tem seu eixo1 perpendicular ao eixo2, equivalente a uma articulação
universal com suspensão adicionada.
Passos para a construção desta estrutura:
• Ajustar a âncora e os parâmetros do eixo. Eixo1 e Eixo2 devem ser
perpendiculares um ao outro;
• Iniciar o ponto de ancoragem. Será retornado o ponto de um dos corpos, e, se a
articulação estiver perfeitamente correta, o mesmo será executado para o outro
corpo;
• Iniciar os parâmetros dos eixos;
• Iniciar os ângulos hinge-2 (ao redor dos eixos 1 e 2) e suas taxas de variação.
Quando a âncora ou o eixo estão ajustados, a posição corrente dos corpos
ligados é examinada, e sua posição recebe ângulo zero.

8.6.4 Articulação Fixa


A articulação fixa mantém uma posição e orientação entre dois corpos, ou entre
um corpo e um ambiente estático. Esta articulação quase nunca é utilizada, exceto
quando você precisa realizar uma depuração de código. Se você precisar que dois
corpos permaneçam unidos, é melhor representá-los como um simples corpo.

8.6.5 Contato
Uma articulação de contato é mostrada na Figura 8-9.
295

Figura 8-9 - Uma articulação de contato. Fonte: O.D.E. Site Oficial.


A articulação de contato impede que o corpo 1 e o corpo 2 se interpenetrem no
ponto de contato. Isto ocorre somente permitindo que os corpos tenham uma velocidade
que parte na direção do contato normal. As articulações de contato têm tipicamente um
tempo de vida de uma etapa de tempo. São criadas e excluídas em resposta à detecção
da colisão.
As articulações de contato podem simular a fricção no contato aplicando forças
especiais nos dois sentidos da fricção que são perpendiculares à normal.
Quando uma articulação de contato é criada, uma estrutura dContact deve ser
fornecida. Esta deve ter a seguinte definição, onde:
struct dContact {
dSurfaceParameters surface;
dContactGeom geom;
dVector3 fdir1;
};

• geom é uma subestrutura que é configurada pelas funções de colisão. Esta é


descrita na seção de colisões;
• fdir1 é um vetor “da primeira direção da fricção” que define um sentido adiante
da qual a força de fricção é aplicada. Deve ser do comprimento da unidade e
perpendicular ao contato normal (assim ele é tipicamente tangencial à superfície
de contato). Deve ser definido somente se o flag dContactFDir1 é configurado
em surface.mode. A “segunda direção da fricção " é um vetor computado para
ser perpendicular ao contato normal e à fdir1;
296
• surface é uma subestrutura que é configurada pelo usuário. Seus membros
definem as propriedades da colisão de superficies. Ela tem os seguintes
parâmetros:
o int mode - Flags de Contato. Devem ser sempre configurados. Suas
combinações seguem descritas na tabela 8.1:
o dReal mu: Coeficiente da fricção de Coulomb. Deve estar no intervalo
[0, dInfinity). 0 resulta em um contato sem atrito, e o dInfinity resulta
em um contato que nunca desliza. Importante observar que os contatos
sem atrito consomem menos tempo para processar do que os com atrito,
e os contatos de atrito infinito podem ser mais baratos do que contatos
com fricção finita;
o dReal mu2: Coeficiente da fricção do Coulomb opcional para a direção 2
da fricção (0..dInfinity);
o dReal bounce: Parâmetro de compensação (0..1). 0 significa que as
superfícies não são flexíveis em toda a sua extensão, 1 ao contrário são
completamente flexíveis. Isto é ajustado somente se o flag
correspondente também for ajustado.
o dReal bounce_vel: A velocidade mínima necessária para a batida (em
m/s). Velocidades baixas minimizarão um choque entre dois corpos;
o dReal soft_erp: Parâmetro “suavidade” do contato normal.
o dReal soft_cfm: Parâmetro “softness” do contato normal.
o dReal motion1,motion2 :Velocidade de superfície atrito de superfície nas
direções 1 e 2 (em m/s).;
o dReal slip1,slip2 : Os coeficientes de inclinação de deslizamento (FDS)
para as direções 1 e 2 da fricção.

Tabela 8.1 – Flags de Contato para surfaces. Fonte: O.D.E. Site Oficial.
Flag Definição
dContactMu2 Se não estiver configurado, use mu para as duas direções do
atrito. Se estiver configurado, usa-se mu para a direção do atrito
1 e mu2 para a direção do atrito 2.
dContactFDir1 Se ajustado, use fdir1 para a direção 1 da fricção. Caso
contrário, o ajuste será automático para 1, sendo perpendicular
ao contato normal (no qual sua orientação resultante é
297
imprevisível).
dContactBounce Se estiver configurada, a superfície de contato é flexível, e
assim os corpos irão chocar-se, proporcionando um ricocheteio.
A quantidade exata de ricocheteio é controlada pelo parâmetro
de impacto.
dContactSoftERP Se configurada, o parâmetro da redução de erro do contato da
normal pode ser ajustada com o parâmetro do soft_erp. Isto é
útil para fazer superfícies suaves.
dContactSoftCFM Se configurada, o parâmetro de limitação de força de contato
normal pode ser setado com o parâmetro soft_cfm. É útil para se
fazer superfícies suaves.
dContactMotion1 Se ajustada, a superfície de contato assumida move-se
independentemente do movimento dos corpos. Este é um tipo
de esteira. Quando este flag é setado, motion1 define a
velocidade de superfície na direção 1 da fricção.
dContactMotion2 Idem ao dContactMotion1, mas para a direção de atrito 2.
dContactSlip1 Force-dependent-slip (FDS) na direção 1 do atrito (inclinação).
dContactSlip2 Force-dependent-slip (FDS) na direção 2 do atrito (inclinação).
dContactApprox1_1 Usa a pirâmide de aproximação de atrito para a direção 1. Se
isto não for especificado, então a aproximação do constante-
força-limite será usada (onde mu é um limite da força).
dContactApprox1_2 Usa a pirâmide de aproximação de atrito para a direção 2. Se
isto não for especificado, então a aproximação do constante-
força-limite será usada (onde mu é um limite da força).
dContactApprox1 Equivalente a dContactApprox1_1 e dContactApprox1_2.

O FDS é um efeito que faz com que superfícies de contato entre si tenham uma
velocidade que seja proporcional à força aplicada tangencialmente a cada superfície. A
força não causa uma aceleração constante nas superfícies – ela causa uma aceleração
breve para chegar a uma velocidade constante.
Isto é útil para modelar, por exemplo, pneus. Considere um carro parado em uma
estrada. Empurrando o carro para frente, este começa a se mover (isto é os pneus
começarão a girar). Empurrando o carro na direção perpendicular não ocasionará
nenhum efeito, porque os pneus não giram nesse sentido. Contudo se o carro estiver se
298
movendo a uma velocidade v, aplicando uma força f na direção perpendicular fará com
que os pneus deslizem na estrada com uma velocidade proporcional ao f*v, o que
realmente é suscetível a acontecer.
Importante ressaltar que o FDS não tem relação com os efeitos de
aderência/deslize de atrito de Coulomb – ambos os modos podem ser usados juntos em
um único ponto de contato.

8.6.6 Motor Angular


Um motor angular (AMotor) permite que as velocidades angulares relativas de
dois corpos sejam controladas. A velocidade angular pode ser controlada em até três
eixos, permitindo que os motores de torque e parada sejam ajustados para a rotação
sobre aqueles eixos. Isto é útil principalmente em conjunto com articulações esféricas,
mas isto pode ser usado em qualquer situação onde o controle angular é necessário. Para
usar um AMotor com uma articulação esférica, junte simplesmente dois corpos e
habilidade a articulação, tornando-a unida ao grupo.
O AMotor pode ser usado em modos diferentes. No modo dAMotorUser , o
usuário ajusta diretamente os eixos que o Amotor controla. Na modalidade do
dAMotorEuler, AMotor computa os ângulos de Euler que correspondem à rotação
relativa, permitindo ajuste aos motores de torque de ângulo e as paradas. Uma
articulação AMotor com ângulos do Euler é mostrada na Figura 8-10.

Figura 8-10 – Uma articulação AMotor com ângulos de Euler. Fonte: O.D.E. Site Oficial.
Neste diagrama, a0, a1 e a2 são os três eixos ao longo do qual o movimento
angular é controlado. Os eixos verdes (incluindo a0) são ancorados ao corpo 1. Os eixos
azuis (incluindo a2 são ancorados ao corpo 2. Para pegar o eixo do corpo 2 dos eixos
do corpo 1 a seguinte seqüência de rotações é executada:
299
• Rotação por θ0 sobre a0;
• Rotação por θ1 sobre a1(a1 foi rotacionado de sua posição original);
• Rotate by θ2 sobre a2 (a2 foi rotacionado duas vezes a partir de sua posição
original).
Há uma limitação importante ao usar os ângulos de Euler: o ângulo do θ1 não
pode começar fora da escala -π/2...π/2. Se isto acontecer, então a articulação AMotor
tornar-se-á instável (há uma particularidade entre +/- π/2). Para tanto, você deve ajustar
as paradas apropriadas no eixo número 1.
Passos para a construção desta estrutura:
• Atribuir e receber o mode do motor angular. O parâmetro mode deve ser uma
das seguintes constantes:

Tabela 8.2 – Constantes para Motor Angular. Fonte: O.D.E. Site Oficial.
Flag Definição
dAMotorUser O eixo AMotor e as configurações do ângulo de articulação são
inteiramente controladas pelo usuário. Este é o modo padrão.
dAMotorEuler Os ângulos de Euler são computados automaticamente. O eixo a1
é computado também automaticamente. Os eixos do AMotor
devem ser ajustados corretamente quando neste modo, como
descritos abaixo. Quando este modo é ajustado inicialmente
atribua as orientações relativas atuais dos corpos corresponderão
a todos os ângulos do Euler em zero.

• Atribuir e receber o número dos eixos angulares que serão controlados pelo
AMotor (de 0 a 3);
• Atribuir e receber os eixos de AMotor, onde:
o 0: O eixo é ancorado para o quadro global.
o 1: O eixo é ancorado para o primeiro corpo.
o 2: O eixo é ancorado para o segundo corpo.
O vetor dos eixos (x, y, z) é sempre especificado em coordenadas globais.
Para o modo dAMotorEuler:
o Somente os eixos 0 e 2 necessitam ser configurados. O eixo 1 será
determinado automaticamente a cada passo de tempo;
o Os eixos 0 e 2 devem ser perpendiculares entre si;
300
o O eixo 0 deve ser ancorado para o primeiro corpo, o eixo 2 deve ser
ancorado para o segundo corpo.
• Informar ao AMotor que o ângulo atual está junto com o eixo especificado. Esta
função deve ser chamada somente no modo dAMotorUser, porque neste modo o
AMotor não tem nenhuma outra maneira de saber os ângulos de articulação. A
informação do ângulo é necessária se as paradas forem ajustadas ao longo do
eixo central, mas não é necessário para os eixos dos motores;
• Retornar o ângulo atual para o eixo especificado;
• Retornar a taxa do ângulo atual para o eixo especificado. No modo
dAMotorUser isto é sempre zero, porque não há informação disponível. No
modo dAMotorEuler esta é a taxa correspondente ao ângulo Euler.

8.7 Informações Gerais


O parâmetro de geometria articulada que ajusta funções deve somente ser
chamado depois que a articulação fez a união dos corpos, e se estes estiverem
posicionados corretamente – caso contrário, a articulação não pode ser inicializada
corretamente, e não fará nada.
Para o parâmetro de chamada de funções, se o sistema está fora do alinhamento
(isto é, existe algum erro de articulação comum, então os valores âncora/eixo estarão
corretos com relação ao corpo 1 somente (ou o corpo 2) se você especificar o corpo 1
como zero na função dJointAttach.
A âncora padrão para todas as articulações é (0 ,0 ,0). O eixo padrão para todas
as articulações é (1,0,0).
Não há nenhuma função para ajustar diretamente ângulos articulados ou
posições (ou seus valores). Portanto você deve ajustar as posições e as velocidades
correspondentes do corpo.

8.7.1 Parâmetros de Parada e de Motor


Quando uma articulação é criada, inicialmente não há nada que impeça sua
movimentação. Por exemplo, uma dobradiça pode mover-se através de seu ângulo
inteiro, e um indicador deslizará por todo o comprimento.
Esta escala de movimento pode ser limitada ajustando as paradas na articulação.
O ângulo articulado (ou a posição) será impedido de ir abaixo do menor valor de parada,
301
ou de ir acima do maior valor de parada. Observe que um ângulo articulado (ou a
posição) de zero correspondem às posições iniciais do corpo.
Assim como as paradas, muitos tipos articulados podem ter motores. Um motor
aplica um torque (ou força) de um grau de articulação de liberdade para começar a girar
(ou deslizar) em uma velocidade desejada. Os motores têm os limites da força, a qual
significa que eles não podem aplicar mais do que um valor máximo de força/torque à
articulação.
Os motores têm dois parâmetros: uma velocidade esperada e a força máxima que
está disponível para alcançar essa velocidade. Este é um modelo muito simples dos
motores principais ou auxiliares da vida real. Entretanto, é muito útil ao modelar um
motor (principal ou auxiliar) que o mesmo mude para um marcha menor, através de
uma caixa de engrenagens, antes de conectar a articulação. Tais dispositivos são
controlados freqüentemente ajustando a velocidade desejada, e podem somente gerar
uma quantidade máxima de força para conseguir essa velocidade (que corresponde a
uma determinada quantidade de força disponível na articulação).
Os motores também podem ser usados de maneira precisa para modelar a fricção
seca (ou Coulomb) nas articulações. Basta que se ajuste a velocidade desejada a zero e
determine a força máxima a algum valor constante – todo o movimento articulado será
impedido então por essa força.
A alternativa para o uso de articulação de parada e motores é aplicar
simplesmente as forças aos corpos afetados de maneira manual, através da programação
por parte do usuário. Aplicar forças ao motor é fácil, e as articulações de parada podem
ser emuladas com forças de restrição da mola. De qualquer modo, a aplicação de forças
diretamente não é uma boa aproximação e pode conduzir a sérios problemas de
estabilidade se não for executado com cuidado.
Considere o exemplo de aplicação de força a um corpo para conseguir uma
velocidade desejada. Para calcular esta força você usa a informação sobre a velocidade
atual, algo como esta:
força = k * (velocidade desejada – velocidade corrente);

Isto tem diversos problemas. Primeiramente, o parâmetro k deve ser ajustado


manualmente. Se for muito baixo o corpo levará muito tempo até atingir a velocidade
desejada. Se for muito alto, a simulação tornar-se-á instável. Segundo, mesmo se um k
equilibrado for escolhido, o corpo terá poucas etapas de tempo para chegar até a
302
velocidade. Em terceiro lugar, se alguma outra força externa estiver sendo aplicada ao
corpo, a velocidade desejada pode nunca ser alcançada (uma equação mais complicada
de força seria necessária, que tenha parâmetros extras).
Os motores articulados resolvem todos estes problemas: trazem o corpo até a
velocidade em um determinado tempo, contanto que este não tenha mais força do que o
permitido. Eles não necessitam de nenhum parâmetro extra porque são executados como
constraints.

8.7.2 Configurando forças e torques direcionais


Motores permitem que você ajuste as velocidades articuladas diretamente. Entretanto,
pode-se preferivelmente ajustar o torque ou a força em uma articulação. Existem
funções que trabalham ativamente nestes processos, não afetando o motor do grupo de
articulações.

8.8 Redução de Erros em Simulação – E.R.P. e C.F.M.

8.8.1 Erros de articulação e parâmetros para redução de erros


Quando uma articulação une dois corpos, estes corpos são obrigados a
possuírem posições e orientações relativas um ao outro. Entretanto, é possível que os
corpos estejam em posições onde constraints não se encontram, ocasionando um “erro
de articulação” (Figura 8-11). Isto pode acontecer de duas formas:
• Se o usuário configurou a posição/orientação de um corpo sem ajustar
corretamente a posição/orientação do outro corpo;
• Durante a simulação, podem ter acontecido erros que resultem na separação/
desvio de corpos das suas posições definidas.
303
Figura 8-11 - Exemplo do erro de uma articulação ball and socket (onde a esfera e o
soquete não ficam alinhados). Fonte: O.D.E. Site Oficial.
Existe um mecanismo que reduz este erro de articulação: durante cada passo da
simulação, cada articulação aplica uma força especial para trazer os corpos de volta ao
alinhamento correto. Esta força é controlada por um parâmetro de redução de erros
(E.R.P.), o qual tem valor que varia de 0 a 1.
O E.R.P. especifica qual a proporção de erro que será fixada durante o próximo
passo de simulação. Se E.R.P.=0, então não haverá aplicação de força e os corpos
poderão eventualmente separar-se durante o processo de simulação. Se E.R.P.=1, então
a simulação tentará fixar todos os erros de articulação no próximo passo. Entretanto,
não é recomendado configurar E.R.P.=1, pois o erro de articulação tentará ser fixado ao
extremo durante cada renderização da simulação, ocupando muito tempo de
processamento. O valor E.R.P.=0.1 até 0.8 é recomendado (0.2 é default).
Um valor E.R.P. global pode ser ajustado para afetar mais articulações na
simulação. Entretanto, algumas articulações têm valores E.R.P. locais para controlar
vários aspectos da articulação.

o Constraints leves e mescla de força em constraints


Muitas constraints são por natureza “compactas” em uma simulação. Neste
meio, as constraints representam condições que não são violadas. Por exemplo, uma
esfera deve sempre estar em um soquete, e duas partes de um hinge (dobradiça) devem
sempre estar alinhadas. Na prática, constraints podem ser violadas por erros não
intencionais dentro do sistema, mas o parâmetro de redução de erro pode ser
configurado para corrigir tais erros.
Nem todas as constraints são compactas. Algumas constraints “leves” são
projetadas para sofrerem violação. Por exemplo, uma constraint de contato que impede
que os objetos em colisão penetrem em sua articulação, definida por padrão, age como
se fosse uma superfície de aço. Mas, a constraint de contato pode ser configurada de
forma maleável, fazendo com que os objetos colidam e criem uma penetração natural
em superfícies, originando um “buraco” de proporções definidas, de acordo com a força
empregada. Este tipo de situação é controlado através do sistema C.F.M. (Soft
constraint and constraint force mixing).

o Como usar E.R.P. e C.F.M.


304
E.R.P. e C.F.M. podem ser independentemente configuradas para várias
articulações. Elas podem ser ajustadas nos contatos das articulações, em limites e vários
outros lugares, controlando absorção e elasticidade da articulação.
Se o C.F.M. é zero, a constraint será compacta. Se o C.F.M. é um valor positivo,
será possível violar a constraint “empurrando-a” (por exemplo, constraints de contatos
são forçadas em dois pontos de contato unidos). Em outras palavras, a constraint será
leve, e a leveza aumentará conforme o C.F.M. aumenta. O que realmente acontece aqui
é que a constraint permite uma violação em uma quantia proporcional ao tempo do
C.F.M., que restaura a força necessária para continuar pressionando a constraint. Note
que os ajustes da C.F.M. com valores negativos podem ter efeitos indesejáveis, como
instabilidade.
Ajustando os valores E.R.P. e C.F.M., você pode alcançar vários efeitos. Por
exemplo, você pode simular constraints com elasticidade, onde dois corpos oscilam
através de conexões com elasticidade. Ou você pode simular constraints com alta
absorção, sem oscilações.
Acrescentando C.F.M., especialmente em modo global, podemos reduzir o
número de erros em uma simulação. Se o ambiente é muito simples, isto pode aumentar
sua estabilidade. Agora, se o sistema exige muitas variações de comportamento dos
objetos, uma das coisas a fazer é tentar aumentar o C.F.M. global.

8.9 Detecção de colisão


A biblioteca O.D.E. tem dois components principais para a detecção de colisão
que são: O engine de simulação dinâmica e o engine de colisão que dá informações a
respeito do formato de cada corpo. Em cada passo de tempo ele calcula quais corpos
tocam cada um dos outros e envia as informações sobre o ponto de contato resultante
para o usuário. Este então cria articulações de contato entre os corpos. O uso da
detecção de colisão da O.D.E. é opcional. Um sistema de detecção de colisão alternativo
pode ser usado para suprir os tipos corretos de informações de contato.

o Pontos de Contato
Se dois corpos se tocam, ou se um corpo toca um objeto estático dentro do
ambiente, este é representado por um ou mais pontos de contato. Cada ponto de contato
tem um ponto de contato correspondente de nome dContactGeom:
struct dContactGeom {
305
dVector3 pos; // posição de contato
dVector3 normal; // vetor normal
dReal depth; // profundidade de penetração
dGeomID g1,g2; // geometrias de colisão
};

• pos: Registros da posição de contato em coordenadas globais;


• depth é a profundidade na qual os dois corpos se inter penetram. Se o depth é
zero então os corpos têm um contato leve, isto é eles apenas se tocam. Contudo,
isto é raro – a simulação não é perfeitamente precisa e os corpos geralmente
ficam longe e assim a profundidade é diferente de zero;
• normal é um vetor de tamanho unitário que é, perpendicular a superfície de
contato;
• g1 e g2 são os objetos geométricos que irão colidir.
A convenção é que se o corpo 1 se move na drieção do vetor normal por uma
distância grande (ou equivalentemente se o corpo 2 é movido na mesma distância na
direção oposta) então a profundidade de contato será reduzida para zero. Isto significa
que o vetor normal aponta para o corpo 1.
Na vida real o contato entre dois corpos é uma coisa complexa. Contatos
representados pelos pontos de contato é uma aproximação. Superfícies de contato
podem ser mais precisas fisicamente, mas a representação destes acontecimentos em
simulações de alta velocidade é um desafio de software.
Cada ponto extra de contato adicionado à simulação irá reduzir um pouco mais,
assim algumas vezes nos somos forcados a ignorar os pontos de contato em função da
velocidade. Por exemplo, quando duas caixas colidem muitos pontos de contato podem
ser necessários para representar a geometria da situação, mas nos podemos selecionar
uma somente para manter as três melhores. Desta maneira estamos empilhando a
aproximação no topo da aproximação.

o Objetos Geométricos
Objetos geométricos fundamentais no sistema de colisão. Um geom pode
representar um formato de corpo rígido (tal como uma esfera ou caixa) ou pode
representar um grupo de outras geometrias – este é um tipo especial de geometria
chamada “space”.
306
Qualquer geometria pode ser colidida contra qualquer outra geometria para
produzir zero ou mais pontos de contato. Os objetos space têm uma capacidade extra de
serem capazes de colicir suas geometrias para produzir pontos de contato internos.
Geoms podem ser estabelecidas ou não. Uma geometria estabelecida tem um vetor de
posição e uma matriz de rotação de 3x3, tal como um corpo rígido que pode ser trocado
durante a simulação. Uma geometria não estabelecida não tem esta capacidade – por
exemplo, pode ser trocada durante a simulação. Por exemplo, pode representar algumas
características estáticas do ambiente que não pode ser movido. Spaces não são
geometrias estabelecidas, porque cada um pode ter sua própria posição e orientação,
mas isto não faz sentido para o space por si só para ter uma posição e orientação.
Para usar um engine de colisão em uma simulação de corpo rígido, geometrias
que podem ser alocadas são associadas com objetos de corpos rígidos. Isto permite ao
engine de colisão pegar a posição e orientação das geometrias dos corpos.
Observe que as geometrias são distintas dos corpos rígidos porque estas tem
propriedades (tamanho, formato, posição e orientação) mas sem propriedades dinâmicas
(tais como velocidade ou massa). Um corpo e uma geometria juntos representam todas
as propriedades do objeto simulado.
Cada geometria é uma instância de uma classe, tais como esferas, planos ou
caixas. Há um número de classes nativas, que são descritas abaixo e que podem ser
definidas como classes proprietárias.
O ponto de referência para uma geometria alocável é o ponto que é controlado
pela posição vetorial. O ponto de referência para as classes padrão usualmente
corresponde ao centro de massa destas. Esta característica permite as classes padrão
conectarem-se facilmente a corpos dinâmicos. Se outros pontos de referência forem
solicitados, um objeto de transformação pode ser usado para encapsulá-la.
Os conceitos e funções que são aplicadas a todas as geometrias serão descritos
abaixo, seguidas pelas várias classes de geometrias e as funções que as manipulam.

o Espaços (Spaces)
Um space é uma geometria sem lugar determinado que pode conter outras
geometrias. É similar ao conceito de corpo rígido, exceto que é aplicado para colisão ao
invés de dinâmica.
Objetos Space existem para fazer a detecção de colisão de forma rápida e
transparente. Sem spaces, você poderia gerar contatos em sua simulação pela chamada
307
do dCollide() para encontrar pontos de contato para cada par simples de geometrias.
Para N geometrias este é O(N2) testes, aos quais são mais custosos computacionalmente
se seu ambiente tem muitos objetos.
Uma aproximação melhor seria inserir as geometrias dentro de um space e
chamar dSpaceCollide(). O space então escolherá um tipo de colisão, o que significa
que irá rapidamente identificar quais pares de geometrias que estão potencialmente
colidindo. Estes pares serão passados para uma função callback, na qual poderá
novamente chamar a função dCollide() para eles.
Isto economiza muito tempo que poderia ser gasto em testes de colisão
dCollide() inúteis, porque o número de pares passados para a função callback será uma
fração menor de cada par possível objeto-objeto. Os spaces podem conter outros spaces.
Isto é útil para dividir um ambiente de colisão entre diversas hierarquias para mais
adiante otimizar a velocidade de detecção de colisão.

o Detecção de Colisão
Uma detecção de colisão no mundo é criada para um espaço de atuação, onde
são adicionados os tipos geométricos. Três funções básicas são usadas para isto:
• dCollide() intersecta dois geoms e gera os pontos de contato;
• dSpaceCollide() determina quais pares de geoms no espaço potencialmente
poderão colidir, e chama uma função callback para cada par candidato. Isto não
gera pontos de contato diretamente, porque o usuário pode querer manipular
alguns pares em especial – por exemplo, ignorando eles ou usando diferentes
estratégias de contato. Cada decisão tem que fazer chamada a uma função
callback podendo escolher se colide ou não com o par;
• dSpaceCollide2() determina qual geom de um espaço pode potencialmente
intersectar com geoms de outro espaço, e chama a função callback para cada par
candidato. Pode também testar com um espaço sem geoms. Esta função é usada
quando existe uma hierarquia de colisão, isto é, quando existem espaços que
contém outros espaços.
O sistema de colisão tem sido projetado para dar ao usuário máxima
flexibilidade na decisão de quais objetos serão testados em comparação a outros. Isto
porque existem três funções de colisões ao invés de uma função que apenas gera os
pontos de contato.
308
Espaços podem conter outros espaços. Estes sub-espaços representarão
tipicamente uma coleção de geoms (ou outros lugares) que são alocados próximos uns
dos outros. Isto é usado para aumentar o desempenho de colisão de hierarquias dentro
de um mundo.
Exemplo: suponha que você tem dois carros guiados sobre um terreno. Cada
carro tem seus próprios geoms. Se todos estes geoms estavam inseridos em um mesmo
espaço, a computação do tempo de colisão entre dois carros seria sempre proporcional
ao número total de geoms (ou para cada área deste número, dependendo de qual tipo
espaço é usado).
Para acelerar a colisão um espaço separado é criado para representar cada
veículo. As geometrias do carro são inseridas neste espaço para auxílio. A cada passo de
simulação, dSpaceCollide() é chamada para este nível de espaço. Assim, ocorrerá um
único teste da interseção entre estes espaços (limitados por envoltórios que são caixas
que definem o espaço que este irá ocupar), retornando a ocorrência de toque. A função
callback pode então testar as geometrias destes espaços comparando com
dSpaceCollide2(). Se os carros não estiverem próximos, então a função callback não
será executada.
Se hierarquias de espaço são utilizadas então a chamada de retorno será
recursiva. Neste caso, o usuário deve ter certeza de que a função callback é
corretamente aplicada. Aqui está a mesma função callback que varre todos os espaços e
sub-espaços, gerando os possíveis pontos de contato nas interseções de geoms:
void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
if (dGeomIsSpace (o1) || dGeomIsSpace (o2))
{
// colliding a space with something
dSpaceCollide2 (o1,o2,data,&nearCallback);
// collide all geoms internal to the space(s)
if (dGeomIsSpace (o1)) dSpaceCollide (o1,data,&nearCallback);
if (dGeomIsSpace (o2)) dSpaceCollide (o2,data,&nearCallback);
}
else
{
// colliding two non-space geoms, so generate contact
// points between o1 and o2
int num_contact = dCollide (o1,o2,max_contacts,contact_array,skip);
// add these contact points to the simulation
...
309
}
}
...
// collide all objects together
dSpaceCollide (top_level_space,0,&nearCallback);

Uma função callback de um espaço não permite modificar um espaço enquanto


existe processamento em dSpaceCollide() ou dSpaceCollide2(). Por exemplo, você não
pode adicionar ou remover geoms de um espaço, ou não pode reposicionar geoms
dentro de um espaço. Caso isto ocorra, ocorrerá um erro em tempo de execução no
momento da construção do mundo pela O.D.E.

o Classes Geometria (Geometry)


A classe Geometria é composta por várias classes. As configurações em cada
classe devem seguir as mesmas definições de tamanho do objeto ao qual a classe i.
• Sphere: manipula esferas e seus respectivos raios. Ponto de referência: centro da
esfera;
• Box: trabalha com cubos. Ponto de referência: centro do Box;
• Plane: gera superfícies. A equação do plano é a*x + b*y + c*z = d. O vetor do
plano é (a,b,c) e tem comprimento = 1. Eles não tem uma posição e rotação
atribuídas. Estes planes têm seus parâmetros sempre ajustados em coordenadas
globais. Em outras palavras supõe-se que o plane é sempre parte do ambiente
estático, e não é preso a nenhum objeto móvel;
• Capped Cylinder: trabalha com cilindros lacrados. É como um cilindro normal
com tampões em suas extremidades. Esta característica faz a detecção de colisão
ser mais rápida e exata. O comprimento do cilindro é dado pelo parâmetro
length, e o raio dos tampões e do próprio cilindro é dado por radius;
• Ray: diferente tipo de geom que não representa nenhum objeto sólido. Na
verdade, o Ray gera uma linha infinitesimal, procurando colidir com um objeto
em cada uma de suas extremidades. Exemplo: uma pistola e uma mira. O Ray
será a linha de trajetória da bala que sairá a pistola e acertará o alvo de mira;
• Triangle Mesh: manipula malha de triângulos. Um triangle mesh (TriMesh)
representa uma coleção arbitrária de triângulos. O sistema de colisão dos
TriMesh tem as seguintes características:
o Triângulos não são requeridos para ter um tipo particular de estrutura;
310
o TriMeshes podem interagir com esferas, cubos, rays e outros trimeshes;
o Trabalha bem com grandes triângulos;
o Usa a coerência temporal para acelerar os testes de colisão.

As colisões entre Trimesh/Trimesh executam bem, mas existem duas


advertências:
o O tamanho do passo que você usa terá que ser, em geral, reduzido a um
ponto exato de colisão. Modelos não-convexos são muito mais
dependentes de uma colisão geométrica do que uma colisão primitiva.
o Visando resolver colisões de modo eficiente, dCollideTTL necessita das
posições de colisão dos Trimeshes. Isto é usado para calcular uma
velocidade estimada de cada triângulo que sofreu colisão, informando
local do impacto, normais de contato, etc.
• Geometry Transform: trabalha com dois geoms, onde um geom “T” encapsula
outro geom “E”, permitindo que E seja posicionado e girado arbitrariamente,
respeitando seu ponto de referência.
A maioria dos placeable geoms (como esferas e cubos) tem seus pontos
de referência correspondentes aos seus centros de massa, permitindo serem
facilmente conectados a objetos dinâmicos. Objetos Transform dão uma maior
flexibilidade – por exemplo, você pode deslocar o centro de uma esfera, ou
rotacionar um cilindro de modo que seu eixo central tenha qualquer valor, com
exceção do valor default.
Assim, T imita o objeto E encapsulado: T é introduzido no espaço e
unido a um corpo como se fosse E. E não deve ser inserido no espaço ou unido a
um corpo. A posição e rotação de E é ajustada em valores constantes que dizem
como ocorre a transformação para T. Se a posição e a rotação do E forem
deixadas com seus valores default, T comportar-se-á exatamente como E.

o Objetos compostos
Considere os exemplos abaixo:
• Uma mesa que foi feita com um box para a superfície e um box para cada perna
da mesa;
• Um galho de árvore que é modelado com vários cilindros para cada ramificação
presa a ele;
311
• Uma molécula que tem várias esferas representando cada átomo.

Se estes objetos são considerados rígidos, então é necessário usar um simples


corpo para representar cada um deles. Mas pode parecer que o desempenho da colisão
seja um problema, porque não existem classes single geometry que possam representar
uma forma complexa como uma mesa ou uma molécula. A solução é usar um objeto de
colisão composta que é uma combinação de vários geoms.
Funções extras não são necessárias para monitorar objetos compostos:
simplesmente crie cada componente geom e una-os num mesmo corpo. Para mover e
rotacionar geoms separados com respeito ao mesmo objeto, geometry transforms podem
ser usadas para encapsulá-las.
Entretanto, existe uma advertência: você nunca deve criar um objeto composto
que resultará em pontos de colisão gerados muito próximos uns dos outros. Por
exemplo, considere uma mesa que é feita com um box para a superfície e quatro boxes
para as pernas da mesa. Se a mesa está de cabeça para baixo então os pontos de contato
entrarão em colisão e farão com que as pernas da mesa caiam lateralmente no chão.
Para corrigir isto, a mesa deve ser ajustada de modo com que as pernas não
façam um contato direto com a superfície, evitando sobreposição.

o Notas de implementação

 Grandes Ambientes
Freqüentemente o mundo de colisões conterá muitos objetos que são partes de
um ambiente estático, que não estão associados a corpos rígidos. A detecção de colisão
O.D.E. é otimizada para detectar geoms que não se movem e não precomputam tanta
informação como possível sobre estes objetos para economizar tempo. Por exemplo,
estruturas de dados de colisão interna e envoltórios são precomputados.

 Usando uma diferente biblioteca de colisão

Usar detecção de colisão O.D.E. é opcional – um biblioteca alternativa de


colisão pode ser usada por um determinado tempo para fornecer estruturas do tipo
dContactGeom para inicializar contatos de articulações.
O núcleo da dinâmica da O.D.E. é na maior parte independente da biblioteca da
colisão que é usada, exceto em quatro pontos:
312
• O tipo dGeomID deve estar definido, porque cada corpo pode armazenar um
ponteiro ao primeiro objeto geometry que está associado a ele.
• void dGeomMoved(dGeomID) deve estar definido, pois ela é chamada pelos
códigos dinâmicos enquanto um corpo se move – isto indica que o objeto de
geometria associado com o corpo está agora em uma nova posição;
• void dGeomGetBodyNext(dGeomID) deve também estar definido, pois ela é
chamada pelos códigos dinâmicos para percorrer a lista de geoms que estão
associados a cada corpo. Dado um geom anexado a um corpo, ele retorna o
próximo geom unido aquele corpo, ou zero se não existem mais geoms;
• void dGeomSetBody(dGeomID, dBodyYD) deve estar definido, para remover
todas as referências do geom a um corpo, quando chamado.
Se você quer uma biblioteca alternativa de colisão para conseguir notificar os
movimentos do corpo pela O.D.E., você deverá definir, primeiramente, estes tipos e as
funções apropriadas.

8.10 Exemplos
Esta seção demonstra como criar uma simulação em tempo real de uma
máquina, onde são efetuadas conexões entre objetos O.D.E. utilizando articulações a
fim de criar movimentações realísticas. A ferramenta de demonstração escolhida foi o
Delphi.

8.10.1 Exemplo 1 – Máquina e Aplicação de Forças


Para iniciar a desenvolver a simulação, primeiramente é preciso criar um projeto
no Delphi. Após isto, começa o trabalho com a biblioteca GLScene, que tem a
biblioteca O.D.E. integrada desde sua última versão (GLScene 2).
O primeiro passo é inserir os componentes GLSceneViewer (Figura 8-12B) e
GLScene (Figura 8-12A), da paleta GLScene, ao Form principal. Estes são essenciais,
pois o primeiro delimita a área onde o OpenGL renderiza a cena e representa a cena 3D
vista de uma câmera (especificada na propriedade camera); e o segundo contém a
descrição da cena (luzes, geometria...) que é basicamente uma cena hierárquica gráfica
no qual contém um ou mais objetos. Estes são componentes básicos para a criação de
um cenário.
313

Figura 8-12 – Paleta básica de componentes da biblioteca GLScene.


Em seguida, o Form também recebe os seguintes componentes:
• GLCadencer (E): O cadencer provoca eventos de progressão, que ao contrário de
um temporizador, não acontecem em um intervalo fixo de tempo. Eles
progridem geralmente uma vez que o frame precedente torna-se completo;
• GLODEManager (M): Gerenciador dos objetos envolvidos no mundo virtual;
• GLODEJointList (N): Lista de articulações criadas no mundo.

Quando inserimos GLODEManager, os objetos world e space são


automaticamente criados. Com isso basta apenas ajustar a força da gravidade e difinir o
número de passos para o mundo. Neste caso a gravidade é 0 para x, y e z, pois o
ambiente ficará estático, e o número de passos é definido pelo seguinte código, dentro
do evento OnProgress do GLCadencer:
GLODEManager1.Step(deltaTime);

Com todos os componentes básicos inseridos no Form, é necessário também


criar uma câmera que reproduzirá o cenário. Dando um clique duplo no GLScene
(Figura 8-13) a janela GLScene Editor será apresentada. Através dela é possível fazer a
criação hierárquica de objetos estruturados conforme a figura abaixo.

Figura 8-13– Janela do GLScene Editor.


Abrindo o menu popup do item Cameras selecione a opção Add Camera. Com
isso surgirá uma câmera como “filho” de Cameras. Com a câmera criada, basta agora
associa-la ao GLSceneViewer através de sua propriedade Camera. Além disso, é
preciso também associar a propriedade Scene do GLCadencer com o nome do GLScene
(GLScene1 por padrão inicial).
314
A máquina a ser modelada é composta por quatro cilindros (Cylinder) e dois
cubos (Cube), “filhos” de um DummyCube (bounding box) conforme apresentado
abaixo. Estes objetos são encontrados dentro do GLScene através do seguinte caminho:
Menu popup de Scene objects > Add object > Basic Geometry. Eles devem estar
estruturados conforme a figura abaixo

Figura 8-14 – Janela do GLScene Editor com a Estrutura da Máquina.


Com sua estrutura montada, as propriedades dos objetos terão que ser alteradas
para dar a forma ao cenário a ser simulado. As propriedades que devem ser alteradas
para cada um dos objetos estão listadas nas tabelas abaixo:

Cilindro 1 X 0
BottomRadius 2 Y 1
Direction Z 0
X 0
Y 0 Cilindro 2
Z 1 BottomRadius 0,5
Height 0,5 Direction
Name Wheel X 0
Position Y 0
X -2,5 Z 1
Y 0 Height 5
Z 0 Name Axle
Slices 32 Position
TopRadius 2 X 0
Up
315
Y -2 X 3,5
Z 0 Y 0,5
Slices 16 Z -1,5
TopRadius 0,5 Slices 16
Up TopRadius 0,25
X 0 Up
Y 1 X 0
Z 0 Y 1
Z 0
Cilindro 3 Cubo 1
BottomRadius 0,25 CubeDepth 0,75
Direction CubeHeight 0,25
X 0 CubeWidth 7,5
Y 0 Direction
Z 1 X 0
Height 1 Y 0
Name Pin1 Z 1
Position Name Arm
X 0 Position
Y 0,5 X 0,5
Z -1,5 Y 0,75
Slices 16 Z -1,5
TopRadius 0,25 Up
Up X 0
X 0 Y 1
Y 1 Z 0
Z 0

Cilindro 4 Cubo 2
BottomRadius 0,25 CubeDepth 1
Direction CubeHeight 0,5
X 0 CubeWidth 4
Y 0 Direction
Z 1 X 0
Height 1 Y 0
Name Pin2 Z 1
Position
316
Name Slider Up
Position X 0
X 3,25 Y 1
Y 0 Z 0
Z -1,5

Com as propriedades definidas, a visualização da máquina é apresentada na


figura abaixo:

Figura 8-15– Visualização da câmera após definição dos objetos componentes da máquina.
Agora, ajusta-se o comportamento para os objetos do mundo que irão exercer
movimentos dentro da simulação. Passo isso, selecione cada um dos objetos e mude a
propriedade Behaviours clicando em [...]. Uma nova janela será aberta, como mostra a
Figura 8-16, onde cada objeto será definido como O.D.E. Dynamic.
317

Figura 8-16 – Janela onde é definido o comportamento de cada objeto.

Neste caso, os objetos que receberão esta propriedade são o Arm, Pin2 e Wheel.
Apesar de Axl e Pin1 não estarem definidos como um objeto dinâmico, eles também se
movimentarão. Isto ocorre porque todos os objetos filhos herdam suas propriedades do
objeto pai, neste caso o objeto Wheel.
Assim, um item será inserido nesta janela. Em suas propriedades, é requerido
indicar qual é o gerenciador O.D.E. a ser utilizado através da opção Manager. Há
também outra propriedade chamada Elements onde será definido como o objeto atuará
no sistema de colisão. Mesmo que o objeto mostrado na tela seja uma esfera, e este
tenha sido definido como um elemento box, então esta esfera atuará na simulação como
se fosse um cubo. Por isso, utiliza-se sempre o elemento que tem maior semelhança com
o objeto que se pretende simular.
O processo para os três objetos citados acima é o mesmo, o que muda são os
tipos de elementos a serem usados e suas propriedades, respectivamente. Nas tabelas
abaixo estão disponíveis as propriedades de cada objeto suscetíveis de alterações.
Arm – Element Box
BoxDepth 0,75
BoxHeight 0,25
BoxWidth 7,5
Pin2 – Element Cylinder
Density 1
Density 1
Name Box Length 1
Radius 0,25
Name Cylinder
318
Wheel – Element Cylinder Radius 2
Density 1 Name Cylinder
Length 0,5
Uma vez alterado estas propriedades, são criadas as articulações entre objetos.
As articulações limitam a movimentação e dão sincronismo ao mecanismo
desenvolvido. Para criá-las, selecione o componente GLODEJointList já inserido no
Form principal. Em suas propriedades, acesse a opção Joints. Abrirá uma janela
semelhante ao do processo anterior, onde definimos o comportamento do objeto no
mundo. São criadas quatro articulações, sendo que três são do tipo hinge e outra do tipo
slider. Suas definições seguem abaixo:
Hinge 1 Object1 Wheel
Anchor Object2 Arm
X -2,5 Hinge 3
Y 0 Anchor
Z 0 X 3,5
Axis Y 0,5
X 0 Z -1,5
Y 1 Axis
Z 0 X 0
Manager GLODEManager1 Y 1
Name Wheel Fixed Z 0
Object1 Wheel Manager GLODEManager1
Object2 Name Arm - Pin2
Object1 Arm
Object2 Pin2
Hinge 2
Anchor
Slider
X -2,5
Axis
Y 0,5
X 1
Z -1,5
Y 0
Axis
Z 0
X 0
Manager GLODEManager1
Y 1
Name Pin2 Fixed
Z 0
Object1 Pin2
Manager GLODEManager1
Object2
Name Wheel - Arm
319

Para finalizar, atribuímos uma força para atuar no mundo, dando movimentação
ao objeto. Aplica-se em Arm no sentido x. Para isso, no eventoOnCreate do Form
adicionamos o seguinte código:
TGLODEDynamicBehaviour(Arm.Behaviours[0]).AddForce(AffineVectorMake(-50,0,0));

O.B.S.: para utilizar a função AffineVectorMake( ) é necessário incluir a unit


VectorGeometry na cláusula Uses, localizada no início do código fonte.

Compile e veja o resultado! Observe que a força aplicada no objeto Arm fará
com que o objeto Wheel gire e o objeto Pin2 deslize sobre o objeto Slider. A simulação
está concluída.

8.10.2 Exemplo 2 – Bola e Aplicação de Gravidade


Neste exemplo, demonstramos como criar objetos para a simulação física de um
mundo. Nele, aplicaremos movimentos físicos a uma bola que cairá sobre um plano
inclinado e rolará em direção ao ponto mais baixo da superfície.Utlizaremos a biblioteca
GLScene para desenvolver o exemplo. Nela já está embutido o componente O.D.E.,
responsável pela simulação.
Passos:
• Crie um nova aplicação em Delphi;
• Insira os componentes GLSceneViewer, GLScene, GLCadencer e
GLODEManager ao form principal de nome frmExemplo1;
• Dê um duplo clique no componente GLScene (Figura 8-17) para aparecer a janela do GLScene
Editor. Nela abra menu popup do item Cameras selecione a opção Add Camera. A câmera foi
criada;

Figura 8-17– Tela do GLScene Editor.


320
• Adicione uma luz à câmera através do menu popup do item Scene Objects
adicione o objeto LightSource. Em seguida arraste-o para cima do objeto
GLcamera1;
• Referencie a propriedade camera do GLSceneViewer com o nome da camera
criada anteriormente;
• Agora crie um DummyCube tendo como filho um objeto sphere;
• Crie também um objeto plane como filho de Scene Objects;
• Referencie a propriedade TargetObject da camera com o nome do plano criado
acima;

Figura 8-18 – Hierarquia dos objetos envolvidos no mundo.


• A hierarquia do GLScene Editor deve fica conforme a figura 9.7;
• Ajuste as propriedades de todos os objetos conforme as figuras abaixo:
321

Figura 8-19
– Propriedades do objeto “bola”.

Figura 8-20 –Propriedades do


Cadencer.
322

Figura 8-21–Propriedades da
Câmera.

Figura 8-22–Propriedades do
DummyCube.

Figura 8-23 – Componente GLScene.


323

Figura 8-24– Objeto Luz


(lightsource).

Figura 8-26 – Superfície de Contato.

Figura 8-25– Componente


ODEManager.
324

Figura 8-27–GLSceneViewer.
325
• Após o ajuste das propriedades, a visão da câmera será apresentada conforme as
próximas figuras:

Figura 8-28 – Visualização da câmera após o posicionamento dos objetos no mundo.


• Referencie a propriedade Scene do GLCadencer com o nome do componente
GLScene;
• No evento OnProgress do GLCadencer insira o seguinte código:
GLODEManager1.Step(deltaTime);
• Defina o comportamento do plano criado como objeto estático através da
propriedade Behaviours [...] e tendo como elemento um box (propriedade
Elements [...]) e da esfera como objeto dinâmico e tendo como elemento um
Sphere segundo as seguintes figuras:
326
Figura 8-29– Passos para definir o comportamento do objeto bola.

Figura 8-30 – Passos para definir o comportamento do objeto superfície.


• Basta agora rodar a aplicação e ver o resultado que se obteve com a
programação visual do O.D.E. e GLScene.

8.11 Referências
Grange, Eric. GLScene – Open Solution for Delphi. http://www.glscene.org
(25/08/04).
Mojon, Stéphane. Realization of a Physic Simulation for a Biped Robot. Swiss
Federal Institute of Technology Lausanne (EPFL), 2003.
Smith, Russel. Open Dynamics Engine – O.D.E. User Guide. http://www.ode.org
(25/08/04).

S-ar putea să vă placă și