Você está na página 1de 36

AM 533A - Computação Gráfica e Multimídia I

Utilização do VRML
Texto: Elisa Calhau de Castro e Léo Pini Magalhães
1o semestre de 1999
Aula 1

O que será visto nesta aula:

• I - Introdução ao VRML
o I.1 - O que é VRML
o I.2 - Estrutura do arquivo - Como programar
o I.3 - Nodos
 I.3.1 - Conceito
 I.3.2 - Semântica
 I.3.3 - Utilização dos DEF/USE
o I.4 - Hierarquia de Nodos
 I.4.1 - Conceito
 I.4.2 - Grouping Nodes e Children Nodes
• II - Shape Nodes e Geometria
o II.1 - Shape Nodes e Geometry Nodes
 II.1.1 - Box
 II.1.2 - Cilindro
 II.1.3 - Cone
 II.1.4 - Esfera
 II.1.5 - Texto
 II.1.6 - ElevationGrid Node
 II.1.7 - Extrusão
 II.1.8 - IndexedFaceSet
 II.1.9 - IndexedLineSet
 II.1.10 - PointSet
o II.2 - Appearance Node
• III - Exercícios

I - Introdução ao VRML:
I.1 - O que é VRML?
VRML, "Virtual Reality Modeling Language", é uma linguagem que
nos possibilita descrever objetos 3D e agrupá-los, de modo a construir e
animar cenas ou "verdadeiros mundos virtuais". As cenas criadas são, em
geral, disponibilizadas na WWW e suas áreas de aplicação são bastante
diversificadas, indo desde aplicações na área científica e tecnológica até
entretenimento e educação, passando por representações artísticas e em
multimídia.
Maiores informações veja Tutorial disponível na rede.

Notação:

Os links presentes ao longo das aulas referem-se a um Tutorial de


VRML disponível e desenvolvido no DCA - FEEC (Departamento de
Engenharia de Computação e Automação Industrial).
Por vezes, julgou-se necessária a inclusão da nomenclatura inglesa
de certos atributos da linguagem VRML por serem de uso frequente na
literatura e, consequentemente, auxiliando o aluno na identificação dos
mesmos em consultas a outras fontes de pesquisa.
Exceto como primeiro caracter obrigatório no cabeçalho de todo
arquivo VRML, o símbolo "#" precede comentários ao longo do código
dos programas.
Observa-se, ainda, que o nome dos nodos se inicia com letra
maiúscula e que o nome dos campos ("fields") é escrito em minúsculas.
Os campos são limitados por chaves.

I.2 - Estrutura de Arquivo e Como Programar:


Os arquivos VRML têm extensão ".wrl" .
A primeira linha de um arquivo VRML, o seu header, tem o seguinte
formato:

#VRML V2.0 utf8 [comentários opcionais] <fim-de-linha

Nota-se que há, só e somente só, um espaço em branco separando os termos


"#VRML" de "V2.0" e "V2.0" dos comentários.
As cenas são basicamente compostas por nodos , os quais descrevem
os objetos da cena e suas propriedades. Eles podem ser hierarquicamente
agrupados de modo a viabilizar a representação audio-visual dos objetos, além
de participarem do processo de geração e transmissão de eventos.
Os arquivos com extensão ".wrl" podem ser editados usando-se um
editor de texto comum, tal qual o "Edit" do DOS, "Bloco de Notas" do
Windows, Emacs, etc. A seguir, para que a cena possa ser visualizada é
utilizado um browser VRML, como por exemplo, o Cosmo Player da Silicon
Graphics ou o Cyber da Sony, entre outros. É através desses browsers que o
usuário enxerga e pode, até mesmo, interagir com a cena, participando da
animação.

I.3 - Nodos
I.3.1 - Conceito
Conjuntos de objetos, ou melhor, abstração de objetos e de
certas entidades do mundo real, tais como: esferas, cubos, luz, som, etc. São
definidos como sendo os "componentes fundamentais " de uma cena em
VRML, pois esta é construída a partir da disposição, combinação e interação
entre os nodos.
Cada tipo de nodo (ou node type) contém campos (fields) e
eventos (events) e pode se comunicar com outros nodos através de routes que
correspondem a conexões entre o nodo que está gerando o evento e o nodo
que deverá receber o evento.
Os principais nodos estão descritos numa "tabela de nodos" à
parte.

I.3.2 - Semântica
Cada nodo apresenta, em geral, as seguintes características:

a) Tipo: citam-se como exemplos: Box, Color, Group, Sphere, Sound, etc;
b) zero ou mais atributos para fields que definem como um nodo difere de
outro nodo do mesmo tipo;
c) conjunto de eventos que um nodo pode receber e enviar: cada nodo
pode receber zero ou mais tipos diferentes de eventos, os quais geram
alterações no estado do nodo. Analogamente, podem gerar tipos distintos de
eventos para comunicar alterações em seu estado;
d) implementação: a implementação de cada nodo define como ele reage a
eventos que pode receber, à geração de eventos e às suas características
visuais no mundo virtual;
e) nome: pode-se atribuir um nome a um nodo. Isso permite que possamos
fazer referências a uma instância específica de um nodo. Isso é feito através
das palavras DEF/USE.
Exemplo I.3.2: Definição de um Cone Vermelho
#VRML V2.0 utf8
# Um cone vermelho é definido
Shape {
geometry Cone { bottomRadius 2
height 4
side TRUE
bottom FALSE
}
appearance Appearance {
material Material {
diffuseColor 1 0 0 #Vermelho
}
}
}
Observe, no exemplo acima, que o nome do nodo Cone está em negrito, bem
como seus campos: bottomRadius, height, side e bottom. Note ainda, que
outros nodos foram definidos (Appearance e Material), com seus respectivos
campos: material e diffuseColor.
I.3.3 - Utilização dos DEF/USE
Uma vez tendo atribuído um nome a um nodo, através da
palavra DEF, pode-se, futuramente, referenciá-lo através da palavra USE. A
declaração de USE não cria uma nova cópia do nodo, em vez disso, o mesmo
nodo é inserido na cena uma segunda vez. À utilização de múltiplos exemplos
(ou instâncias) de um mesmo nodo dá-se o nome de "instanciação". Sendo
assim, caso seja necessária a reutilização de um mesmo nodo, várias vezes
numa cena, é mais eficiente atribuir a ele um nome, quando da primeira vez
que o descrevemos e, a partir daí, referenciá-lo pelo nome cada vez que for
necessário usá-lo novamente. Essa técnica, além de tornar o arquivo VRML
menor e mais fácil de ler, diminui o tempo que se leva para carregar a cena, o
que indica uma significativa melhoria na performance geral.

Exemplo I.3.3: Utilização do DEF/USE

#VRML V2.0 utf8

Viewpoint {
position 0 0 10 # Poderia ser omitido já que é o valor
default
}

Transform {

# Um cone é definido e posicionado na origem (valor default = 0 0 0)

children [
DEF Cone_Azul Shape {
geometry Cone {} # Cone
appearance Appearance {
material Material {
diffuseColor 0 0 1 # Azul
}
}
}
# O cone é reutilizado e posicionado em (3 0 4)

Transform{
translation 3 0 4
children USE Cone_Azul
}
]
}

Observe nesse exemplo, que o segundo cone gerado (o da direita)


tem as mesmas dimensões do primeiro, porém, foi posicionado (3 0 4) ao lado
deste e mais próximo do observador (viewpoint = 0 0 10).

I.4 - Hierarquia de Nodos


I.4.1 - Conceito
Um arquivo VRML é, essencialmente, hierárquico. Cada nodo
pode conter outros nodos na sua especificação. De maneira simplificada,
pode-se dizer que é usual haver "nodos incluídos em outros nodos", formando
uma cadeia que culmina na formação de uma cena.
Os nodos que estão mais no topo da hierarquia são chamados de
ancestrais ( ou ancestors ) e os demais são seus descendentes, de modo
análogo ao usado em árvores genealógicas. Dá-se o nome de "nodo raiz" ou
root node ao nodo que não está contido em nenhum outro nodo, sendo que
este deve ser um children node como será visto no próximo item.
Exemplificando, suponha o pequeno arquivo VRML, a
seguir, onde se define um cilindro verde:

Exemplo I.4.1-1: Cilindro Verde

#VRML V2.0 utf8

Shape {
appearance Appearance {
material Material {
diffuseColor 0 1 0
shininess .5
}
}
geometry Cylinder {
radius 4
height 8
side TRUE
top TRUE
bottom TRUE
}
}
Associado a esse exemplo, pode-se construir um diagrama como abaixo, onde
fica mais evidente o "parentesco" entre os nodos:

Fig. I.4.1-1: Diagrama da cena referente ao Cilindro


Verde
Na figura, os nodos ancestrais (também ditos parent nodes) estão à esquerda
dos seus descendentes ou "filhos" (ou children nodes como será visto mais
adiante) e os filhos de um mesmo "pai", alinhados verticalmente.

I.4.2 - Grouping Nodes e Children Nodes


É comum, na construção de cenas, agruparem-se objetos, de
modo a se criar uma nova figura. Os chamados Grouping Nodes estão listados
abaixo. Os nodos que podem ser agrupados e, portanto, incluídos no campo
children de um grouping node também, estão relacionados.

São grouping nodes:

• Anchor
• Billboard
• Collision
• Group
• Inline
• LOD
• Switch
• Transform

São children nodes:

• Anchor  LOD  Sound


• Background  NavigationInfo  SpotLight
• Billboard  NormalInterpolator  SphereSensor
• Collision   Switch
• ColorInterpolator OrientationInterpolator  TimeSensor
• CoordinateInterpolator  PlaneSensor  TouchSensor
• CylinderSensor  PointLight  Transform
• DirectionalLight   Viewpoint
• Fog PositionInterpolator  VisibilitySensor
• Group  ProximitySensor  WorldInfo
 ScalarInterpolator
• Inline  Script
 Shape
A seguir são destacados os nodos que não são válidos como children
nodes:

• Appearance  ElevationGrid  Normal


• AudioClip  Extrusion  PointSet
• Box  ImageTexture  Sphere
• Color  IndexedFaceSet  Text
• Cone  IndexedLineSet 
• Coordinate  Material TextureCoordinate
 MovieTexture 
• Cylinder TextureTransform
Destaca-se, no entanto, a diferença básica entre um grouping
node e um Transform Node ( ou Nodo Transformação): quando se deseja
apenas criar um novo objeto que seja constituído da combinação de outros
objetos, usa-se um grouping node. Porém, caso se deseje somente agrupar
espacialmente os objetos, ou seja, posicioná-los em certa região da cena, usa-
se o nodo Transformação.

II - Shape Nodes e Geometria


II.1 - Shape Nodes e Geometry Nodes
Os nodos do tipo "Shape"são básicos para a construção de
objetos geométricos. Eles associam um nodo geométrico ( geometry node) a
nodos que definem as características visuais do objeto. Os nodos do tipo
"Shape" devem fazer parte da hierarquia de transformação (discutido mais
adiante na Aula 2), a fim de que os resultados gerados possam ser
visualizados. Um nodo Shape contém, exatamente, um único nodo geométrico
em seu campo geometry.
VRML provê um conjunto de nodos geométricos como a
seguir:

• Box
• Cone
• Cylinder
• ElevationGrid
• Extrusion
• IndexedFaceSet
• IndexedLineSet
• PointSet
• Sphere
• Text

Além desses, VRML permite que se criem outros nodos


geométricos através do método de "prototyping" que será discutido
posteriormente (Aula 3).
A seguir, exemplifica-se como criar um "box" default em
VRML, deixando mais clara a relação entre os nodos Shape e Geometry:
# VRML V2.0 utf8
Shape {
appearance Appearance {
material Material {}
}
geometry Box {}
}

Note que nenhum atributo foi atribuído ao box. Neste caso,


diz-se que o objeto está usando atributos default, ou seja, previamente
definidos na linguagem. Assim, o exemplo a seguir é equivalente ao anterior:

# VRML V2.0 utf8


Shape {
appearance Appearance {
material Material {}
}
geometry Box {
size 2 2 2 # eixos xyz respectivamente
}
}
Os nodos geométricos são, a seguir, discutidos mais
detalhadamente.

II.1.1 - Box
Um dos mais simples nodos geométricos é o box, que
corresponde a um paralelepípedo centrado na origem (0,0,0) do sistema de
coordenadas local e alinhado com os eixos cartesianos, tal qual indica a
Fig.II.1-1.
Fig. II.1-1: Box

Os valores default do nodo Box correspondem a um cubo de


dimensões 2 x 2 x 2.

Box {
field SFVec3f size 2 2 2
}
O campo size contém três números, indicando o comprimento
do box ao longo dos eixos x, y, z respectivamente. Para informações
adicionais vide Box Node no Tutorial.

II.1.2 - Cilindro
Cylinder {
field SFBool bottom TRUE
field SFFloat height 2
field SFFloat radius 1
field SFBool side TRUE
field SFBool top TRUE
}

Este nodo define um cilindro centrado na origem (0,0,0) do


sistema de coordenadas cartesianas e com o eixo central ao longo do eixo y,
como pode ser visto na Fig. II.1-2. Seus valores default correspondem a um
cilindro de tamanho 2 nas três dimensões. O atributo radius refere-se ao raio
do cilindro e height à sua altura ao longo do eixo central. Tanto radius quanto
height devem ter valores maiores que 0.0 .
Fig. II.1-2: Cilindro

O cilindro é composto por três partes: lateral (side), a tampa (top)


e o fundo (bottom). A cada uma dessas partes está associada uma variável do
tipo SFBool (tipo prédefinido pela linguagem) que pode ser TRUE, indicando
existência, ou FALSE, caso não exista.
Quando uma textura é associada ao cilindro, ela é feita
diferentemente para cada uma das partes: lateral, tampa e fundo, sendo que
este tópico ("Texturas") será visto mais detalhadamente na aula 2.
Destaca-se, ainda, que o nodo Cilindro só apresenta faces
externas, ou seja, quando visto de dentro para fora, os resultados são
imprevisíveis (dependentes da implementação do browser e não especificadas
na norma).
Maiores informações estão em Cylinder Node no Tutorial.

II.1.3 - Cone
Cone {
field SFFloat bottomRadius 1
field SFFloat height 2
field SFBool side TRUE
field SFBool bottom TRUE
}

Este nodo especifica um cone centrado na origem do sistema local de


coordenadas e cujo eixo central está alinhado com o eixo y, tal qual mostra a
Fig. II.1-3.
Fig. II.1-3: Cone

O campo bottomRadius especifica o raio da base do cone, height a


altura do cone, desde o centro da base até o ápice e bottom se a base do cone é
visível ( TRUE ) ou não ( FALSE ), enquanto side especifica se a lateral do
cone é visível ( TRUE ) ou invisível ( FALSE ).
Por default, o cone tem raio da base igual a 1.0 e altura igual a 2.0 .
Os valores de bottomRadius e height debem ser maiores que 0.0 .
Dependendo do browser utilizado, o Cone pode ser invisível quando
visto do interior, mas, de modo geral, os resultados são imprevisíveis
(dependentes da implementação do browser e não especificadas na norma).
Maiores informações podem ser obtidas em Cone Node no Tutorial.

II.1.4 - Esfera
Sphere {
field SFFloat radius 1
}

Este nodo especifica uma esfera centrada na origem (0,0,0) do


sistema local de coordenadas. O campo radius define o raio da esfera e, por
default, seu valor é 1.0, sendo que sempre deve ser superior a 0.0 .
Quando uma textura ( Texture Node será visto na Aula 2) é
conferida à esfera, toda a sua superfície é coberta, sendo envolvida no sentido
anti-horário, desde a parte de trás da esfera, onde tem-se uma "costura" ou
junta, como visto na Fig. II.1-4 ("texture seam" na figura).
Fig. II.1-4: Esfera

Assim como os nodos apresentados anteriormente, quando a


esfera é vista de dentro para fora, têm-se resultados imprevisíveis
(dependentes da implementação do browser e não especificadas na norma).

Maiores informações, vide Sphere Node no Tutorial.


II.1.5 - Texto
Text {
exposedField MFString string []
exposedField SFNode fontStyle NULL
exposedField MFFloat length []
exposedField SFFloat maxExtent 0.0
}

O nodo Texto é interessante quando se quer incluir, numa cena,


informações, rótulos para objetos, etc. Este nodo contém outro nodo
fundamental para se incluir textos em cenas: FontStyle Node que só é usado
no nodo Texto.
Cabe lembrar que, embora seja escrito no espaço tridimensional da
cena, os textos são primitivas 2D.
Os caracteres do texto são determinados no campo string,
enquanto length refere-se ao "tamanho"de cada caracter do texto dentro do
sistema local de coordenadas. Porém, se a string é muito curta, ela é
expandida ( o texto é escalonado ou acrescentam-se espaços em branco entre
as letras) e, se muito longa, é comprimida. O campo maxExtent limita e
comprime o texto: se o seu tamanho for maior que maxExtent, o texto é
comprimido, caso contrário, não há compressão.
O campo maxExtent é medido na horizontal para textos na horizontal (em
FontStyle Node: horizontal = TRUE ) e na vertical para textos na vertical
(horizontal = FALSE).
O campo fontStyle, por sua vez, contém o nodo FontStyle. Este
define o estilo do texto a ser escrito, podendo-se especificar um dos três tipos
de letra (serif, sans-serif ou typewriter/fixed-width), bem como se o texto
ficará normal (plain roman), em negrito (bold) ou em itálico (italic) e se na
horizontal ou vertical.
O exemplo a seguir, esclarece melhor a sintaxe deste nodo:

Exemplo II.1.5: Nodo Texto

#VRML V2.0 utf8

Viewpoint { position 9 3 17 }
Transform {
translation 0 3 0
children [
Shape {
geometry Text {
string "Curso de VRML"
fontStyle FontStyle {
size 2.5
family "TYPEWRITER" # Sempre maiúscula e entre aspas

style "ITALIC" # Sempre maiúscula e entre aspas


}
}
}
]
}

Cuidado, porém, pois os textos não aparecem sempre da mesma


forma em todos os browsers. De modo geral, os browsers escolhem a
formatação que é mais adequada para os parâmetros fornecidos e de acordo
com o sistema computacional no qual se está trabalhando.

Maiores informações podem ser vistas em Text Node no Tutorial.

II.1.6 - ElevationGrid Node


Este nodo é o ideal quando se deseja representar a topografia de
uma região, desde montanhas até pequenas irregularidades do solo, provendo
uma maneira simplificada de representar superfícies que possuem altos e
baixos diversificados ao longo de uma área.
A sintaxe do nodo é apresentada a seguir (os valores dos campos
são default):

ElevationGrid {
eventIn MFFloat set_height
exposedField SFNode color NULL
exposedField SFNode normal NULL
exposedField SFNode texCoord NULL
field MFFloat height []
field SFBool ccw TRUE
field SFBool colorPerVertex TRUE
field SFFloat creaseAngle 0
field SFBool normalPerVertex TRUE
field SFBool solid TRUE
field SFInt32 xDimension 0
field SFFloat xSpacing 1.0
field SFInt32 zDimension 0
field SFFloat zSpacing 1.0
}
Abaixo, uma breve descrição da funcionalidade de cada campo:

Campo Descrição
número de vértices ao longo da direção x. Seu valor deve ser superior a
xDimension
1.
distância entre dois vértices na direção x. Não pode ser um valor
xSpacing
negativo.
número de vértices ao longo da direção z. Seu valor deve ser superior a
zDimension
1.
distância entre dois vértices na direção z. Não pode ser um valor
zSpacing
negativo.
"lista dos valores das alturas", uma para cada vértice, e enumerada por
height
linha (direção x) em ordem crescente.
pode conter um nodo Color, caso se queira prover cores para cada
color quadrilátero da rede ou para cada vértice, em vez de para toda a rede, o
que se faria usando o nodo Material.
Quando TRUE, indica que se está provendo uma cor por vértice e
quando FALSE, provê-se uma cor por quadrilátero. É ignorado se o
campo color está NULL. Caso se especifique um nodo Color, deve-se
colorPerVertex
prover, pelo menos, (xDimension - 1) x (zDimension - 1) cores para o
caso de colorPerVertex estar FALSE e pelo menos, (xDimension) x
(zDimension) cores para quando está TRUE.
caso não especificado, o browser gera normais automaticamente, mas
normal abre-se aqui a possibilidade de se definir um nodo Normal para se
especificar, explicitamente, as normais a serem geradas.
ignorado se normal for NULL. É TRUE quando se provê uma normal
normalPerVertex
por vértice e FALSE, quando por quadrilátero.
pode conter um nodo TextureCoordinate (vide Aula 2) para se definir,
texCoord
explicitamente, uma textura para "a rede"
por default, as normais (e consequentemente as elevações) são definidas
ccw no sentido positivo de y (i.e. para cima). Porém, se ccw for FALSE, elas
ficarão definidas para baixo, ou seja, sentido negativo de y.
estabelece a possibilidade de se ver o lado de dentro da elevação (caso
solid em que se atribui à variável o valor FALSE) ou se apenas o exterior (o
mais usual) é interessante (TRUE).
ângulo entre as arestas de duas faces (quadriláteros) consecutivos, o que
creaseAngle proporciona o controle sobre a suavidade das curvas (minimizar o
"facetamento" da figura).

Nota:
Eventos serão melhor abordados nas Aulas 3 (item "Nodos
Sensores") e 4 (item "Route").
O exemplo seguinte ilustra este nodo.

Exemplo II.1.6: ElevationGrid Node

#VRML V2.0 utf8

Viewpoint { position 2 1 13 }
Shape {
appearance Appearance { material Material{}}
geometry ElevationGrid {

xDimension 4 # 4 colunas
xSpacing 2.1
zDimension 5 # 5 linhas de 0 a 4
zSpacing 2.0
height [0, 0, 0.2, 0, # linha (row) 0
0, 0.8, 0.4, 0.2 # linha (row) 1
0, 1, 0.6, 0.4 # linha (row) 2
0, 0.8, 0, -0.4 # linha (row) 3
0, 0, 0, 0 ] # linha (row) 4
}
}

Maiores detalhes em ElevationGrid Node no Tutorial.

II.1.7 - Extrusão
Este nodo permite a criação de uma variedade de formas 3D,
construídas a partir da extrusão de uma porção do plano 2D.
A sintaxe do nodo é apresentada a seguir:
Extrusion {
eventIn MFVec2f set_crossSection
eventIn MFRotation set_orientation
eventIn MFVec2f set_scale
eventIn MFVec3f set_spine
field SFBool beginCap TRUE
field SFBool ccw TRUE
field SFBool convex TRUE
field SFFloat creaseAngle 0
field MFVec2f crossSection [ 1 1, 1 -1, -1 -1,
-1 1, 1 1 ]
field SFBool endCap TRUE
field MFRotation orientation 0 0 1 0
field MFVec2f scale 1 1
field SFBool solid TRUE
field MFVec3f spine [ 0 0 0, 0 1 0 ]
}

Campos Descrição
caminho ou figura no plano 2D descrito como uma série de vértices no
crossSection
plano xz e que sofrerá a extrusão
caminho no espaço 3D, ao longo do qual, a figura definida em crossSection
spine sofrerá a extrusão. Também é descrito como uma série de vértices no
sistema local de coordenadas
série de fatores de escala, indicando a dimensão ao longo dos eixos x e z da
figura definida em crossSection e correspondendo aos pontos em spine, de
tal modo que o primeiro valor em scale corresponde ao tamanho que a
scale
figura deverá ter entre os primeiro e segundo pontos especificados em
spine. Caso somente um valor seja especificado, todos os pontos da figura
terão o mesmo tamanho
série de rotações (pares: direção e ângulo), indicando a orientação da figura
definida em crossSection e correspondendo aos pontos em spine, de tal
modo que o primeiro valor em orientation corresponde à orientação que a
orientation
figura deverá ter entre os primeiro e segundo pontos especificados em
spine. Caso somente um valor seja especificado, ele será associado a todos
os pontos de spine
indica se a extremidade da figura que sofre a extrusão aparece tampada ou
beginCap
não
indica se a outra extremidade da figura que sofre a extrusão aparece
endCap
tampada ou não
indica se os vértices em crossSection foram listados no sentido horário
ccw
quando a figura é vista de cima (valores positivos do eixo y)
solid indica se as faces de dentro da figura são visíveis (FALSE) ou não (TRUE)
indica se todas as faces são convexas.Caso a figura em crossSection não
convex seja convexa e tanto beginCap como endCap sejam TRUE, então, atribua
FALSE a convex
o ângulo entre as arestas das faces, de modo a suavisar as bordas, ou seja,
creaseAngle
tornar a figura menos "facetada"

O exemplo seguinte ilustra como este nodo é utilizado.

Exemplo II.1.7: Extrusion Node

#VRML V2.0 utf8


Viewpoint {
position -8 1 1
orientation 0 1 0 -1.75
fieldOfView 0.785398
}

# Extrusao de um triângulo

Shape {
geometry Extrusion {
ccw TRUE
convex TRUE
solid TRUE
beginCap TRUE #parte da frente da figura é fechada
endCap FALSE #parte de trás da figura é aberta

# definem-se os vértices (os quais são interpolados pelo browser) que formam a figura 2D que
sofrerá a extrusão:

crossSection [0 0, 1 1, 1 0, 0 0]

# a direção ao longo da qual ocorre a extrusao:

spine [ 0 0 0, 2 1 0]
}
appearance Appearance {
material Material {
diffuseColor 0 0 1
}
}
}

Inicialmente, são fornecidos os vértices no campo crossSection, que,


uma vez interpolados pelo browser, resultam num triângulo. Após definir-se a
direção de extrusão (em spine), obtem-se um "alongamento" do triângulo, o
que resulta na figura tridimensional.

OBS.: O fato de o "triângulo original" aparecer mais claro na cena, deve-se,


exclusivamente, à própria iluminação (default) definida para a cena.

Maiores informações podem ser obtidas em Extrusion Node no


Tutorial.

II.1.8 - IndexedFaceSet Node


Este nodo representa uma figura 3D construída a partir de
polígonos gerados de um conjunto de vértices localizados em coordenadas
fornecidas (especificadas pelo nodo Coordinate).
Neste nodo, suas faces poligonais são especificadas como listas de índices no
campo coordIndex. O "índice - 1" indica o término de uma face e que a
próxima face será iniciada a seguir.

IndexedFaceSet {
eventIn MFInt32 set_colorIndex
eventIn MFInt32 set_coordIndex
eventIn MFInt32 set_normalIndex
eventIn MFInt32 set_texCoordIndex
exposedField SFNode color NULL
exposedField SFNode coord NULL
exposedField SFNode normal NULL
exposedField SFNode texCoord NULL
field SFBool ccw TRUE
field MFInt32 colorIndex []
field SFBool colorPerVertex TRUE
field SFBool convex TRUE
field MFInt32 coordIndex []
field SFFloat creaseAngle 0
field MFInt32 normalIndex []
field SFBool normalPerVertex TRUE
field SFBool solid TRUE
field MFInt32 texCoordIndex []
}

A seguir, uma breve descrição dos campos presentes na especificação


do nodo:

Campo Descrição
contém um nodo Coordinate onde estão listados os
coord
vértices do IndexFaceSet
lista de polígonos cada qual especificado como
coordIndex
uma lista de índices no nodo Coordinate
pode conter um nodo TextureCoordinate, a fim de
texCoord se especificar, explicitamente, uma textura para o
nodo IndexedFaceSet
estabelece uma lista de índices para o nodo
texCoordIndex
TextureCoordinate
color pode conter um nodo Color com as cores a serem
usadas ou "por face" ou "por vértice"
colorIndex estabelece uma lista de índices para o nodo Color
colorPerVertex Vide OBS. a seguir.
pode conter um nodo Normal a fim de que as
normal
normais sejam especificadas explicitamente
estabelece uma lista de índices para o nodo
normalIndex
Normal
indica se as normais são providas "por vértice"
normalPerVertex (TRUE) ou "por face" (FALSE). O valor deste
campo é ignorado se o campo normal for NULL
indica se os vértices de cada face, quando vista de
ccw frente, são listados no sentido anti-horário (TRUE)
ou horário (FALSE)
indica se as faces são sólidas, em outras palavras,
solid se o usuário pode enxergar o lado interno de cada
uma delas ou não
convex indica se todas as faces são convexas ou não
ângulo segundo o qual permite-se suavizar as
bordas das figuras (ângulo de uma pequena
creaseAngle
curvatura entre arestas adjacentes), diminuindo o
seu "facetamento"
Descrição
Evento
eventIn MFInt32
set_colorIndex atribui valores ao campo colorIndex
set_coordIndex atribui valores ao campo coordIndex
set_normalIndex atribui valores ao campo normalIndex
set_texCoordIndex atribui valores ao campo texCoordIndex
OBS: Caso o campo color seja NULL, o objeto geométrico deverá ser
renderizado normalmente, usando-se um nodo Material e uma textura definidos no
nodo Appearance. Porém, para o caso de color não ser NULL, procede-se da
seguinte maneira:
a) Se colorPerVertex é FALSE, as cores são aplicadas a cada uma das faces
como a seguir:
1- Se o campo colorIndex não está vazio, então, uma cor é usada
para cada face do IndexedFaceSet. Deve haver tantos índices no
colorIndex, quantas forem as faces do IndexedFaceSet. Além
disso, se o maior índice em colorIndex é N, então, deve haver N
+ 1 cores no nodo Color. O campo colorIndex não pode conter
valores negativos.
2- Se o campo colorIndex está vazio, as cores no nodo Color são
aplicadas a cada uma das faces do IndexedFaceSet em ordem.
Deve haver tantas cores quantas forem as faces.
b) Se colorPerVertex é TRUE, as cores são aplicadas a cada um
dos vértices, como a seguir:
1- Se colorIndex não está vazio, as cores são aplicadas aos
vértices do IndexedFaceSet da mesma maneira que o campo
coordIndex é usado para fornecer as coordenadas de cada vértice
no nodo Coordinate. O campo colorIndex deve conter o mesmo
número de índices do campo coordIndex e também "marcadores
de fim de face (-1)" nos mesmos lugares em que aparecem no
campo coordIndex. Se o maior índice em colorIndex for N,
deverá haver N+1 cores no nodo Color.
2- Se colorIndex está vazio, então, o campo coordIndex é usado
para escolher as cores do nodo Color. Se o maior índice em
coordIndex for N, deverá haver N+1 cores no nodo Color.
A série de exemplos, a seguir, ilustra melhor cada um dos casos
citados e a utilização do nodo IndexedFaceSet.
NOTA: Os exemplos foram extraídos da referência [2] com
algumas alterações. Destacaram-se, em negrito, as partes do
código diretamente relacionadas ao assunto aqui discutido,
porém, a título de curiosidade e ilustrando as potencialidades
da linguagem, foram introduzidos também outros nodos que,
por enquanto, não fazem parte do escopo das aulas
ministradas, mas que são facilmente encontrados nas
referências e em livros e tutoriais sobre VRML.
Maiores informações, ver IndexedFaceSet no Tutorial.
Exemplo II.1.8 A - Especificação de um IndexedFaceSet colorido "por face"

#VRML V2.0 utf8


Background {
skyColor 0 0 0.2
}

NavigationInfo {
type "EXAMINE" # Permite-lhe girar a figura
}

Viewpoint { # Sua localizacao na cena


position 0 -6 17
orientation 0.338246 -0.218865 0.915253 0.88
}
Group {
children [

Transform {
children Shape {
appearance NULL
geometry IndexedFaceSet {

coord Coordinate {
point [ -5 -5 0, # Vertice 0
5 -5 0, # Vertice 1
5 5 0, # Vertice 2
-5 5 0, # Vertice 3
0 0 5 ] # Vertice 4
}

color Color {
color [ 1 0 0, # Cor (vermelho) para a
face 0
0 1 0, # Cor (verde) para a
face 1
0 0 1, # Cor (azul) para a face
2
1 1 0, # Cor (amarelo) para a
face 3
0 1 1 ] # Cor (cyan) para a face
4 (base)
}

# Note que o maior indice = 4, logo, deve haver 5 pontos


em point
# O indice "-1" indica que o conj. de vertices precendes
forma uma face, ou seja, o indice "-1" serve como um
separador de faces

coordIndex [ 0, 1, 4, -1, # Face 0: lado


1, 2, 4, -1, # Face 1: lado
2, 3, 4, -1, # Face 2: lado
3, 0, 4, -1, # Face 3: lado
3, 2, 1, 0, -1 ] # Face 4: base

normal NULL

texCoord NULL

colorPerVertex FALSE # Colorir "por


face"
}

}
]
}
Exemplo II.1.8 B - Especificação de um IndexedFaceSet colorido "por face" com cores
indexadas

#VRML V2.0 utf8

Group {
children [
Background {
skyColor 1 1 1
}
NavigationInfo {
type "EXAMINE"
}
Viewpoint {
position -3 0 17
orientation -0.069951 -0.669532 0.739483 0.26
}
Transform {
children Shape {
appearance NULL

geometry IndexedFaceSet {
coord Coordinate {
point [ -5 -5 0,
5 -5 0,
5 5 0,
-5 5 0,
0 0 5 ]
}

color Color {
color [ 1 0 0, # Cor com indice
0
0 0 1, # Cor com indice
1
1 1 0 ] # Cor com indice
2
}

coordIndex [ 0, 1, 4, -1, # Face 0:


lado
1, 2, 4, -1, # Face 1:
lado
2, 3, 4, -1, # Face 2:
lado
3, 0, 4, -1, # Face 3:
lado
3, 2, 1, 0, -1 ] # Face 4:
base
colorIndex [ 2, # Aplicada a face 0
1, # Aplicada a face 1
2, # Aplicada a face 2
1, # Aplicada a face 3
0 ] # Aplicada a face 4

normal NULL

texCoord NULL

colorPerVertex FALSE
}

}
]
}

Nos próximos dois exemplos, as cores são associadas aos vértices, o que
possibilita um efeito visual bem mais bonito, apresentando gradações de cor
por toda a superfície das faces. Isso é possível graças às interpolações que são
feitas pelos browsers.

Exemplo II.1.8 C - Especificação de um IndexedFaceSet colorido "por vértice"

#VRML V2.0 utf8

Group {
children [
Background {
skyColor 1 1 1
}
NavigationInfo {
type "EXAMINE"
}
Viewpoint {
position -2 -5 17
orientation 0.510051 -0.340034 0.790079 0.51
}
Transform {
children Shape {
appearance Appearance {
material Material {
}

texture NULL

textureTransform NULL
}

geometry IndexedFaceSet {
coord Coordinate {
point [ -5 -5 0, # Vertice 0
5 -5 0, # Vertice 1
5 5 0, # Vertice 2
-5 5 0, # Vertice 3
0 0 5] # Vertice 4
}

color Color {
color [ 1 0 0, # Vermelho aplicado ao vertice
0
0 1 0, # Verde aplicado ao vertice 1
0 0 1, # Azul aplicado ao vertice 2
1 1 0, # Amarelo aplicado ao vertice 3

0 1 1 ] # Cyan aplicado ao vertice 4


}

coordIndex [ 0, 1, 4, -1, # Face 0: lado


1, 2, 4, -1, # Face 1: lado
2, 3, 4, -1, # Face 2: lado
3, 0, 4, -1, # Face 3: lado
3, 2, 1, 0, -1 ] # Face 4: base

# Observa-se que as core em colorIndex sao mapeadas sobre


os vertices
# em coordIndex de maneira que: o vertice 0 - cor 3,
vertice 1 - cor 4,
# vertice 2 - cor 0, vertice 3 - cor 2 e vertice 4 - cor
1

colorIndex [ 3, 4, 1, -1,
4, 0, 1, -1,
0, 2, 1, -1,
2, 3, 1, -1,
2, 0, 4, 3, -1 ]

normal NULL

texCoord NULL

colorPerVertex TRUE # Como o valor default é mesmo TRUE, esse


campo poderia ser omitido
}

}
}
]
}

No exemplo seguinte, o campo colorIndex é omitido. Esse é um método


prático e rápido de indexar as cores e associá-las aos vértices, pois assim
procedendo, é como se o campo colorIndex fosse idêntico ao coordIndex.

Exemplo II.1.8 D - Especificação de um IndexedFaceSet colorido "por vértice" com


indexação de cores

#VRML V2.0 utf8

Group {
children [
Background {
skyColor 1 1 1
}
NavigationInfo {
type "EXAMINE"
}
Viewpoint {
position -2 -5 17
orientation 0.510051 -0.340034 0.790079 0.51
}
Transform {
children Shape {
appearance Appearance {
material Material {
}

texture NULL

textureTransform NULL

geometry IndexedFaceSet {
coord Coordinate {
point [ -5 -5 0,
5 -5 0,
5 5 0,
-5 5 0,
0 0 5 ]
}

color Color {
color [ 1 0 0,
0 1 0,
0 0 1,
1 1 0,
0 1 1 ]
}

coordIndex [ 0, 1, 4, -1,
1, 2, 4, -1,
2, 3, 4, -1,
3, 0, 4, -1,
3, 2, 1, 0, -1 ]

normal NULL

texCoord NULL

colorPerVertex TRUE
}

}
]
}

II.1.9 - IndexedLineSet Node


Este nodo possibilita a representação de contornos de objetos,
através da definição de seus vértices.
IndexedLineSet {
eventIn MFInt32 set_colorIndex
eventIn MFInt32 set_coordIndex
exposedField SFNode color NULL
exposedField SFNode coord NULL
field MFInt32 colorIndex []
field SFBool colorPerVertex TRUE
field MFInt32 coordIndex []
}

Campo Descrição
contém um nodo Coordinate, listando os vértices a
coord
serem usados
coordIndex corresponde a uma lista de índices dentro do nodo
Coordinate, indicando quais vértices são conectados
e em que ordem
pode conter um nodo Color com as cores a serem usadas
color ou "por segmento" ou "por vértice"
colorIndex estabelece uma lista de índices para o nodo Color
colorPerVertex Vide OBS. a seguir
Descrição
Evento
eventIn MFInt32
set_colorIndex atribui valores ao campo colorIndex
set_coordIndex atribui valores ao campo coordIndex
OBS: Caso o campo color seja NULL e haja um nodo Material definido no nodo
Appearance, afetando o IndexedLineSet, o campo emissiveColor de Material deverá
ser usado para desenhar as linhas. Porém, para o caso de color não ser NULL,
procede-se da seguinte maneira:
a) Se colorPerVertex é FALSE:
1- Se o campo colorIndex não está vazio, então, uma cor é usada
para cada linha do IndexedLineSet. Deve haver tantos índices no
colorIndex, quantas forem as linhas do IndexedLineSet. Além
disso, se o maior índice em colorIndex é N, então, deve haver N
+ 1 cores no nodo Color. O campo colorIndex não pode conter
valores negativos.
2- Se o campo colorIndex está vazio, as cores no nodo Color são
aplicadas a cada uma das linhas do IndexedLineSet em ordem.
Deve haver tantas cores quantas forem as linhas.
b) Se colorPerVertex é TRUE:
1- Se colorIndex não está vazio, as cores são aplicadas aos
vértices do IndexedLineSet da mesma maneira que o campo
coordIndex é usado para fornecer as coordenadas de cada vértice
no nodo Coordinate. O campo colorIndex deve conter o mesmo
número de índices do campo coordIndex e também "marcadores
de fim de linha (-1)" nos mesmos lugares em que aparecem no
campo coordIndex. Se o maior índice em colorIndex for N,
deverá haver N+1 cores no nodo Color.
2- Se colorIndex está vazio, então, o campo coordIndex é usado
para escolher as cores do nodo Color. Se o maior índice em
coordIndex for N, deverá haver N+1 cores no nodo Color.
Descreve-se, neste nodo, um objeto construído a partir de uma
série de segmentos de linhas formadas a partir de vértices posicionados em
coordenadas fornecidas. Esse nodo é essencialmente parecido com o
IndexedFaceSet, porém, aqui, em vez de polígonos, é visualizado um conjunto
de linhas. Os segmentos são definidos a partir de índices do campo
coordIndex. Um "indice - 1" indica o término de uma série de segmentos
conectados e que uma nova série será iniciada.
Os conjuntos de linhas não são afetados por luzes e a eles não
são associadas texturas. Também não são válidos em colisões (assunto a ser
explorado na Aula 3).

Nota: O exemplo seguinte foi extraído, com alterações, da referência


[2].

Exemplo II.1.9: Definição de um nodo IndexedLineSet

#VRML V2.0 utf8

Transform {
children Shape {
appearance Appearance {
material Material {
diffuseColor 1 0.8 0
emissiveColor 1 0.8 0
shininess 1
}

texture NULL

textureTransform NULL

geometry IndexedLineSet {
coord Coordinate {

point [0 -1 -1, # Vertice 0


0 1 0, # Vertice 1
0.4 -1 -0.9, # Vertice 2
0.7 -1 -0.7, # Vertice 3
0.9 -1 -0.4, # Vertice 4
1 -1 0, # Vertice 5
0.9 -1 0.4, # Vertice 6
0.7 -1 0.7, # Vertice 7
0.4 -1 0.9, # Vertice 8
0 -1 1, # Vertice 9
-0.4 -1 0.9, # Vertice 10
-0.7 -1 0.7, # Vertice 11
-0.9 -1 0.4, # Vertice 12
-1 -1 0, # Vertice 13
-0.9 -1 -0.4, # Vertice 14
-0.7 -1 -0.7, # Vertice 15
-0.4 -1 -0.9 ] # Vertice 16
}
color NULL

coordIndex [ 0, 1, -1, # Linha 0: une vertices 0 a 1


2, 1, -1, # Linha 1: une vertices 2 a 1
3, 1,-1,
4, 1, -1,
5, 1, -1,
6,1, -1,
7, 1, -1,
8, 1, -1,
9, 1, -1,
10, 1, -1,
11, 1,-1, # Linha 10: une vertices 11 a 1
12, 1, -1,
13, 1, -1,
14,1, -1,
15, 1, -1,
16, 1, -1 ]
}

rotation -1 0 0 1.37
scale 8 80 8
}

Maiores informações, ver IndexedLineSet no Tutorial.

II.1.10 - PointSet

Define-se aqui, um conjunto de pontos desconexos no espaço


3D. Este nodo só aparece no campo geometry de um nodo Shape.

PointSet {
exposedField SFNode color NULL

exposedField SFNode coord NULL

Campo Descrição
contém um nodo Coordinate onde estão listados os vértices a
coord
serem usados pelo PointSet
contém um nodo Color onde estão listadas as cores a serem
color
usadas pelo PointSet, uma cor para cada ponto
São freqüentemente utilizados quando se deseja representar as
luzes das pistas de pouso em aeroportos, estrelas, etc. Assim como o nodo
anterior, não são afetados por luzes e a eles nenhuma textura é associada.
Também não são válidos em colisões (tópico a ser discutido na Aula 3).

Caso um nodo Color seja especificado no campo color, ele


deve conter tantas cores quantos forem os pontos no nodo Coordinate do
campo coord . Cada cor é associada ao ponto correspondente: primeira cor
associada ao primeiro ponto e assim por diante.

Exemplo II.1.10: Definição de um nodo PointSet.

#VRML V2.0 utf8

Group {
children [

Background {
skyColor 0 0 0 # Fundo preto
}

Transform {
children Shape {
appearance NULL

geometry PointSet {

coord Coordinate {
# Cada um destes "pontos" corresponde a um pixel na cena !!!

point [ -0.1 0 9.7, # Ponto 0


0 0 9.7, # Ponto 1
0.1 0 9.7, # Ponto 2
0.2 0 9.7 ] # Ponto 3
}

color Color {
color [ 1 0 0, # Cor (vermelho) para o
ponto 0
1 1 0, # Cor (amarelo) para o
ponto 1
1 0 0, # Cor (vermelho) para o
ponto 2
1 1 0] # Cor (amarelo) para o
ponto 3

}
]
}

Maiores informações, consultar PointSet no Tutorial.

II.2 - Appearance Node


Este nodo só aparece no campo appearance de um nodo Shape
e é responsável pela definição das propriedades visuais das figuras
geométricas.

Appearance{

exposedField SFNode material NULL


exposedField SFNode texture NULL
exposedField SFNode textureTransform NULL
}

Campos Descrição
material contém um nodo Material
contém um nodo ImageTexture, MovieTexture ou
texture
PixelTexture.
contém um nodo TextureTransform. Caso o campo
textureTransform texture seja NULL, o campo textureTransform é
ignorado.

Caso o campo material seja NULL, a geometria associada ao


nodo Appearance não é iluminada, ou seja, as luzes são ignoradas durante a
sua renderização. Esse seria o caso para a especificação abaixo:
appearance Appearance {}
Contudo, se o campo material contém, por default, um nodo
Material (vazio, no caso), a geometria é iluminada usando os atributos do
nodo Material, como na especificação a seguir:

appearance Appearance {material Material{}}

III - Exercícios
1) Definir uma única cena onde apareçam os seguintes nodos:

• Box
• Cilindro
• Cone
• Esfera
• Texto

Procure alterar os parâmetros de tamanho, cor e posição


dos objetos e analisar as mudanças na cena, a fim de se familiarizar com a
linguagem.

2) Faça algumas alterações nos exemplos dados para cada uma


das primitivas (Box, Cilindro, Cone, Esfera e Texto).

3) Obtenha uma imagem como a apresentada aqui. Descreva-a


(programa VRML comentado).
OBS.: A figura é vista animada para que se possa vê-la sob
vários ângulos. NÃO há a necessidade de animar a cena, basta
reproduzi-la, utilizando-se o nodo Extrusion.