O que será visto nesta aula:
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.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.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:
|
|
|
|
|
|
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:
#
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.
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.
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.
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.
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.
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:
#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.
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 |
xDimension | número de vértices ao longo da direção x. Seu valor deve ser superior a 1. |
xSpacing | distância entre dois vértices na direção x. Não pode ser um valor negativo. |
zDimension | número de vértices ao longo da direção z. Seu valor deve ser superior a 1. |
zSpacing | distância entre dois vértices na direção z. Não pode ser um valor negativo. |
height | "lista dos valores das alturas", uma para cada vértice, e enumerada por linha (direção x) em ordem crescente. |
color | pode conter um nodo Color, caso se queira prover cores para cada quadrilátero da rede ou para cada vértice, em vez de para toda a rede, o que se faria usando o nodo Material. |
colorPerVertex | 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 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. |
normal | caso não especificado, o browser gera normais automaticamente, mas abre-se aqui a possibilidade de se definir um nodo Normal para se especificar, explicitamente, as normais a serem geradas. |
normalPerVertex | ignorado se normal for NULL. É TRUE quando se provê uma normal por vértice e FALSE, quando por quadrilátero. |
texCoord | pode conter um nodo TextureCoordinate (vide Aula 2) para se definir, explicitamente, uma textura para "a rede" |
ccw | por default, as normais (e consequentemente as elevações) são definidas 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. |
solid | estabelece a possibilidade de se ver o lado de dentro da elevação (caso em que se atribui à variável o valor FALSE) ou se apenas o exterior (o mais usual) é interessante (TRUE). |
creaseAngle | ângulo entre as arestas de duas faces (quadriláteros) consecutivos, o que proporciona o controle sobre a suavidade das curvas (minimizar o "facetamento" da figura). |
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.
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 |
crossSection | caminho ou figura no plano 2D descrito como uma série de vértices no plano xz e que sofrerá a extrusão |
spine | caminho no espaço 3D, ao longo do qual, a figura definida em crossSection sofrerá a extrusão. Também é descrito como uma série de vértices no sistema local de coordenadas |
scale | 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 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 |
orientation | 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 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 |
beginCap | indica se a extremidade da figura que sofre a extrusão aparece tampada ou não |
endCap | indica se a outra extremidade da figura que sofre a extrusão aparece tampada ou não |
ccw | indica se os vértices em crossSection foram listados no sentido horário 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) |
convex | indica se todas as faces são convexas.Caso a figura em crossSection não seja convexa e tanto beginCap como endCap sejam TRUE, então, atribua FALSE a convex |
creaseAngle | o ângulo entre as arestas das faces, de modo a suavisar as bordas, ou seja, 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.
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 |
coord | contém um nodo Coordinate onde estão listados os vértices do IndexFaceSet |
coordIndex | lista de polígonos cada qual especificado como uma lista de índices no nodo Coordinate |
texCoord | pode conter um nodo TextureCoordinate, a fim de se especificar, explicitamente, uma textura para o nodo IndexedFaceSet |
texCoordIndex | estabelece uma lista de índices para o nodo 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. |
normal | pode conter um nodo Normal a fim de que as normais sejam especificadas explicitamente |
normalIndex | estabelece uma lista de índices para o nodo Normal |
normalPerVertex | indica se as normais são providas "por vértice" (TRUE) ou "por face" (FALSE). O valor deste campo é ignorado se o campo normal for NULL |
ccw | indica se os vértices de cada face, quando vista de frente, são listados no sentido anti-horário (TRUE) ou horário (FALSE) |
solid | indica se as faces são sólidas, em outras palavras, 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 |
creaseAngle | ângulo segundo o qual permite-se suavizar as bordas das figuras (ângulo de uma pequena curvatura entre arestas adjacentes), diminuindo o seu "facetamento" |
Evento | Descrição
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 |
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.
#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
}
}
}
]
}
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 |
coord | contém um nodo Coordinate, listando os vértices a serem usados |
coordIndex | corresponde a uma lista de índices dentro do nodo Coordinate, indicando quais vértices são conectados e em que ordem |
color | pode conter um nodo Color com as cores a serem usadas ou "por segmento" ou "por vértice" |
colorIndex | estabelece uma lista de índices para o nodo Color |
colorPerVertex | Vide OBS. a seguir |
Evento |
Descrição
eventIn MFInt32 |
set_colorIndex | atribui valores ao campo colorIndex |
set_coordIndex | atribui valores ao campo coordIndex |
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.
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.
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 |
coord | contém um nodo Coordinate onde estão listados os vértices a serem usados pelo PointSet |
color | contém um nodo Color onde estão listadas as cores a serem usadas pelo PointSet, uma cor para cada ponto |
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.
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 |
texture | contém um nodo ImageTexture, MovieTexture ou PixelTexture. |
textureTransform | contém um nodo TextureTransform. Caso o campo texture seja NULL, o campo textureTransform é ignorado. |
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{}}
1) Definir uma única cena onde apareçam os seguintes nodos:
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.