Realidade Virtual Aula 3 Remis Balaniuk Conteúdo • Nessa aula serão apresentados os conceitos básicos de geometria 3D ao mesmo tempo em que será apresentada a biblioteca Chai3D no Borland Builder. • Os conceitos de geometria são genéricos e independem do Chai • O Chai será apresentado paralelamente aos conceitos para facilitar a sua compreensão. Chai • A biblioteca Chai pode ser obtida no endereço: http://www.chai3d.org • Após o download do arquivo zip o seu conteúdo deve ser extraído, gerando uma árvore de diretórios contendo fontes, executáveis e exemplos do Chai no Borland Builder e no MS Visual. • Nós usaremos o Borland Builder 6.0 • Crie um diretório ‘Aulas RV’ abaixo de chai3d/examples • Copie do site da disciplina o diretorio `aula1’ em baixo de ‘Aulas RV’ • Clique em aula1.bpr no diretório aula1 para abrir o projeto aula1 Elementos do BBC++ • Note no main.cpp as seguintes características: – A aplicação é toda construída em torno de um formulário (Form1) que contém um painel (Panel1) que corresponde à área preta do formulário e onde aparecerão as imagens gráficas. – A classe TForm1 é uma especialização de TForm, que é uma classe do BBC++ – O método FormCreate é chamado assim que a aplicação é executada, e nesse método as estruturas do Chai são definidas. Elementos do BBC++ • Note também: – O Timer adicionado à aplicação é um recurso do BBC++ e define um objeto que quando ativo (Enabled=true) executa repetidamente o método Timer1Timer a um intervalo definido de tempo (configurado para 20ms nessa aplicação). – Nessa aplicação o timer é usado só para dar um ‘refresh’ na tela, ou seja, atualizar o seu conteúdo. – O grupo TGroupBox *GroupBox7 e e o botão TButton *Button2 também são recursos do BBC++ e o método ToggleGirarButtonClick é chamado quando se clica no botão. – Esses recursos de botão e outros são configurados no BBC++ na base do ‘drag-and-drop’ e configurados ao se clicar no ícone correspondente. Elementos do Chai • As demais estruturas da aplicação são do Chai e correspondem à definição da cena gráfica. • Junto com a explicação de cada estrutura vamos conhecer os conceitos geométricos básicos que essas estruturas implementam. Introdução • Em Computação Gráfica é importante distinguir o modelo de sua representação • O modelo, também chamado de topologia, é a composição de pontos, que são ligados por segmentos de reta, que delimitam polígonos, que por sua vez formam as superfícies dos objetos. • Ainda como parte do modelo, uma série de propriedades são atribuídas a essas entidades, tais como cor, material, textura, etc. • A posição de um objeto é definida pela posição de seus pontos no espaço, e essa posição é parte da representação daquele objeto. • O mesmo objeto pode ser representado em diferentes posições, orientações e tamanho sempre com a mesma topologia. Exemplo do mesmo modelo em representações diferentes Introdução • A representação de uma cena virtual pode conter diversos modelos. • A definição de uma cena virtual começa pela definição de um mundo (cWorld no Chai): // cria uma nova cena world = new cWorld(); Introdução • Esse mundo é a raiz de uma estrutura hierárquica sob a qual todos os componentes da cena virtual serão conectados. • Uma das propriedades da cena é a cor de fundo // define cor de fundo world->setBackgroundColor(0.0f,0.0f,0.0f); Cores • Note que a definição de cores se faz seguindo o padrão RGB (Red Green Blue). • Nesse padrão os 3 números definem a proporção entre vermelho, verde e azul que compõem a cor desejada • Exemplo: – – – – (0.0,0.0,0.0) = preto (1.0,1.0,1.0) = branco (0.0,0.0,1.0) = azul (0.5,0.0,0.5) = vermelho + azul em iguais proporções que dá uma cor próxima do lilas. Câmeras e viewports • Para que esse mundo possa ser observado, uma ou mais câmeras devem ser criadas: // cria uma camera camera = new cCamera(world); world->addChild(camera); • Note que toda estrutura criada daqui para frente deve ser adicionada à cena (addChild) • A câmera permite a observação da cena. • Para que a imagem ‘vista’ pela câmera possa ser mostrada é preciso ligar a câmera a uma janela de exibição (chamada de viewport no Chai) • janelas (viewports no Chai) são criadas assim: // cria um display para apresentar a cena viewport = new cViewport(Panel1->Handle, camera, true); • Note que a viewport esta associada a um painel da aplicação Borland e a uma câmera. • Várias viewports e várias câmeras podem ser criadas para a mesma cena, permitindo visualiza-la de diferentes ângulos simultanemente. cVector3d • Em geometria 3D usamos com frequência vetores tridimensional, ou seja, uma estrutura numérica com 3 reais. • Esse tipo de vetor é utilizado para representar posições, direções e outras informações. • A classe cVector3d é definida por 3 valores: x,y e z, e um conjunto de métodos que permitem efetuar as principais operações vetoriais, tais como adição, produtos, normalização, cálculo do comprimento, etc. Posições 2D e 3D • Posições no espaço são descritas por meio de vetores representando um deslocamento com relação à origem de um sistema de coordenadas. •A figura abaixo a direita representa o chamado “sistema de coordenadas da mão direita” para espaços 3D Sistema de coordenadas do Chai • Exemplo de posição no Chai y+ (2.5,2.0,1.5) 1.5 z- x- x+ 2.5 2 z+ y- Direções • Um vetor 3D pode também ser usado para indicar uma direção: y+ (-0.7, 0.0, 0.7) z- x- x+ z+ y- Direções • Um vetor 3D usado para indicar direção é normalmente unitário, ou seja, seu comprimento é igual a 1. y+ (-0.7, 0.0, 0.7) z- x- x+ z+ y- Direções • O comprimento l de um vetor 3D (x, y z) é calculado como: – . l x y z 2 2 2 y+ (-0.7, 0.0, 0.7) z- x- x+ z+ y- Direções • Um vetor 3D (x, y z) não unitário pode ser ‘normalizado’, ou seja, transformado em unitário fazendo-se: – (x/l, y/l. z/l) y+ (-0.7, 0.0, 0.7) z- x- x+ z+ y- Câmeras • Uma câmera é definida por 3 informações (todas as 3 codificadas em vetores 3D): – Sua posição no espaço – O ponto para onde está ‘olhando’ (lookat) – E a postura da camera, ou seja, se esta em pé, de lado, de cabeça para baixo, etc (up) Câmeras • Exemplo: // posicao da camera cVector3d pos = cVector3d(0,0,3.0); // para onde a camera esta olhando cVector3d lookat = cVector3d(0,0,0); // define postura cVector3d up(0.0, 1.0, 0.0); // define posicao da camera camera->set(pos, lookat, up); y+ z- x- x+ z+ y- Luzes • Para ser visível a cena precisa conter pelo menos uma fonte de luz. • Luzes são definidas pela sua posição e tipo: // cria uma fonte de luz e liga ao mundo light = new cLight(world); light->setEnabled(true); light->setPos(cVector3d(2,1,1)); • Por default uma luz é difusa, ou seja, emite em todas as direções. • É possível definir luzes direcionais (spotlights): – light->setDirectionalLight(true); • Nesse caso é preciso definir também a direção do foco. • Diversas outras propriedades das luzes podem também ser definidas. Elementos gráficos • Os objetos de uma cena tridimensional são normalmente definidos por ‘meshes’. • Um mesh é uma rede de vértices conectados por arestas definindo polígonos. • Um mesh define uma superfície tridimensional. • Quando totalmente fechada essa superfície pode representar um objeto volumétrico object = new cMesh(world); world->addChild(object); Elementos gráficos • Vértices são implementados no Chai pela classe cVertex. • Além da posição 3D, um objeto da classe cVertex possui uma série de propriedades, como cor, posição na textura, além de uma série de métodos. • Exemplo: int p1 = object->newVertex(-0.5, 0.0, 0.0); object->getVertex(p1)->setColor(1.0,0,0,1); – Note que o método newVertex da classe cMesh cria um novo vértice e retorna um sequencial correspondente à posição do novo vértice na lista de vértices do mesh. – getVertex retorna o ponteiro para o vértice na posição indicada pelo parâmetro. – setColor é um método da classe cVertex que permite configurar a sua cor. Elementos gráficos • Com os vértices se pode definir polígonos. • O polígono mais utilizado para compor os meshes é o triângulo, por esse ter a propriedade de ter necessariamente seus vértices coplanares. • No Chai os triângulos são implementados pela classe cTriangle. Elementos gráficos • Uma forma mais prática de adicionar triângulos a um mesh é usando o método abaixo: int p1 = object->newVertex(-0.5, 0.0, 0.0); int p2 = object->newVertex( 0.5, 0.0, 0.0); int p3 = object->newVertex( 0.0, 0.0, 0.5); //cria o triangulo no mesh object->newTriangle(p1, p3, p2); • Note que primeiro foram criados os vértices para depois criar o triângulo passando como parâmetro os sequenciais dos vértices. Elementos gráficos • Um polígono tem direção, que é chamada de ‘normal’. • A normal de um polígono indica para onde esse está voltado. • Essa informação define como a luz incidirá em cada polígono do mesh. • No exemplo abaixo o triângulo da esquerda será iluminado pela luz e ficará visível na cena, enquanto o da direita vai ficar sem cor (com a cor de fundo da cena). Luz Elementos gráficos • Para que as normais de todos os triângulos de um mesh sejam atualizadas use o seguinte método: // compute normals object->computeAllNormals(true); • As normais do mesh precisam ser recalculadas sempre que esse se movimentar na cena, pois isso muda a orientação dos triângulos com relação às fontes de luz. Elementos gráficos • O cálculo da normal de um triângulo é influenciado pela ordem dos vértices na criação do triângulo. • A normal estará ‘saindo’ do triângulo (apontando em sua direção) se ao você olhá-lo de frente ver os vértices no sentido anti-horário. Elementos gráficos • Exemplo: considere o código abaixo cVector3d p1(-0.5, 0, 0); cVector3d p2( 0.5, 0, 0); cVector3d p3( 0, 0.5, 0); //caso 1 - esse triangulo ficara voltado para y+ object->newTriangle(p1, p2, p3); //caso 2 - esse triangulo ficara voltado para yobject->newTriangle(p1, p3, p2); y+ y+ p3 z- normal x- z- x+ p1 z+ p3 p2 y- Caso 1 x- x+ p1 p2 Caso 2 Projeto aula1 • O projeto aula1 implementa uma aplicação simples no qual um triângulo é visualizado por uma câmera que pode rodar em torno dele ao clicar num botão. • Note os seguintes detalhes: – a posição da câmera é recalculada cada vez que o botão é acionado. O ângulo de rotação é incrementado a cada clique. – quando a câmera passa para o lado de trás do triângulo esse desaparece da cena pois seu fundo não recebe incidência de luz. – a cor do triângulo é uma combinação das 3 cores básicas definidas em cada um vértices – o refresh periódico da janela controlado pelo timer. Exercícios • Adapte o projeto aula1 de forma a: – Mostrar um quadrado na tela no lugar do triângulo. – Tornar o quadrado visível dos dois lados. – Adicionar um botão que suba e desça a câmera e outro que a afaste e aproxime. – Adicionar um botão que inicie um movimento contínuo de rotação da câmera ao redor do objeto.