UNIVERSIDADE REGIONAL DE BLUMENAU
CENTRO DE CIÊNCIAS EXATAS E NATURAIS
CURSO DE CIÊNCIA DA COMPUTAÇÃO – BACHARELADO
MOTOR DE JOGOS 3D PARA O IPHONE OS
RAFAEL HIROKI TAKANO
BLUMENAU 2009
2009/2-17
RAFAEL HIROKI TAKANO
MJ3I: UM MOTOR DE JOGOS 3D PARA O IPHONE OS
Trabalho de Conclusão de Curso submetido à Universidade Regional de Blumenau para a obtenção dos créditos na disciplina Trabalho de Conclusão de Curso II do curso de Ciência da Computação — Bacharelado.
Prof. Paulo César Rodacki Gomes, Dr. - Orientador
BLUMENAU 2009
2009/2-17
MJ3I: UM MOTOR DE JOGOS 3D PARA O IPHONE OS
Por
RAFAEL HIROKI TAKANO
Trabalho aprovado para obtenção dos créditos na disciplina de Trabalho de Conclusão de Curso II, pela banca examinadora formada por:
______________________________________________________ Presidente: Prof. Paulo César Rodacki Gomes, Dr. – Orientador, FURB
______________________________________________________ Membro: Prof. Mauro Marcelo Mattos, Dr. – FURB
______________________________________________________ Membro: Prof. Dalton Solano dos Reis, Ms. – FURB
Blumenau, 16 de dezembro de 2009
Dedico este trabalho ao meu orientador e meus amigos que sempre me ajudaram quando precisei.
AGRADECIMENTOS
À minha família, que me formou como indivíduo.
Aos amigos que sempre estão por perto.
Ao mestre Barroso.
A Richard Dawkins, Darwin’s rottweiller.
Ao professor Ms. Dalton Solano dos Reis, que me apoiou desde o início do TCC antes
mesmo da escolha do assunto proposto.
Ao meu orientador, Dr. Paulo César Rodacki Gomes, por ter me incentivado e
acreditado na conclusão deste trabalho.
I am against religion because it teaches us to be satisfied with not understanding the world.
Richard Dawkins
RESUMO
Este trabalho descreve o desenvolvimento de um motor de jogos para a criação de jogos 3D na plataforma iPhone, denominado motor de jogos 3D para iphone OS (MJ3I). O motor é baseado na biblioteca OpenGL ES, para construção das formas geométricas e nas bibliotecas da plataforma do iPhone para realização da interação homem máquina (IHC), através da tela que permite múltiplos gestos. O motor permite que sejam desenvolvido jogos, sem a necessidade de implementar todos as rotinas básicas e necessárias de um jogo 3D. O motor não implementa rotinas mais complexas como cálculo de física, sistema de partículas ou mesmo o áudio.
Palavras-chave: Motor de jogos. iPhone. OpenGL.
ABSTRACT
This work describes the development of a game engine for the creation of 3D games on the Iphone plataform, called motor de jogos 3D para iphone OS (MJ3I). The engine is based in the OpenGL ES library, for the construction of the geometric shapes and the Iphone plataform libraries, to perform the Human-computer Interaction (HCI), through the screen that allow multiples gestures. The engine allows the game development, without the need to implemet all the basics necessaries routines of a 3D game. It does no implements advanced routines, like game physics, particle system and audio.
Key-words: Game engine. iPhone. OpenGL.
LISTA DE ILUSTRAÇÕES
Figura 1 - Gestos utilizados no iPhone: flick, tap e pinch ........................................................15
Figura 2 – Elementos básicos na criação de um jogo...............................................................17
Figura 3 – Estrutura hierárquica do grafo de cena....................................................................18
Figura 4 – Tela de edição da Unity...........................................................................................20
Figura 5 – Exemplo da utilização do M3GE ............................................................................22
Figura 6 – Visão da camada da biblioteca do motor ................................................................24
Figura 7 – Diagrama de casos de uso .......................................................................................25
Figura 8 – Diagrama de classes ................................................................................................26
Figura 9 – Diagrama de seqüência, apresentando a construção de um cubo............................31
Figura 10 – Tela onde são apresentados os templates padrões existentes................................33
Figura 11 – Cubo realizando rotação, conforme valores do GroupNode ..............................36
Figura 12 – Cubo rotacionado 45 graus em dois eixos.............................................................37
Figura 13 – Um cubo rebendo a transformação de translação no eixo X.................................37
Figura 14 – Utilização da escala em um cubo ..........................................................................38
Figura 15 – Colisão detectada ..................................................................................................40
Figura 16 – Modelo 3D importado para o iPhone ....................................................................42
Figura 17 – Aplicação exemplo 1.............................................................................................43
Figura 18 – Aplicação exemplo 2.............................................................................................44
Figura 19 – Aplicação exemplo 3.............................................................................................45
Figura 21 – Diagrama do grafo de cena ...................................................................................46
Figura 22 – Possui os objetos geométricos organizados conforme grafo de cena ...................47
LISTA DE SIGLAS
3D - Três Dimensões
API - Application Programming Interface
A-GPS - Assisted GPS
ES - Embedded System
GPS - Global Positioning System
IDE - Integrated Development Environment
IHC - Interação Homem Computador
LCD - Liquid Crystal Display
OpenAL - Open Audio Library
OpenGL - Open Graphics Library
RF - Requisito Funcional
RNF - Requisito Não-Funcional
SDK - System Development Kit
RGB – Red, Green e Blue
SUMÁRIO
1 INTRODUÇÃO..................................................................................................................12
1.1 OBJETIVOS DO TRABALHO ........................................................................................13
1.2 ESTRUTURA DO TRABALHO......................................................................................13
2 FUNDAMENTAÇÃO TEÓRICA ....................................................................................14
2.1 IPHONE ............................................................................................................................14
2.1.1Multi-toque......................................................................................................................14
2.1.2Global Positioning System (GPS) ...................................................................................15
2.1.3Acelerômetros .................................................................................................................15
2.1.4Sensores...........................................................................................................................16
2.2 OPENGL ...........................................................................................................................16
2.3 MOTOR DE JOGO ...........................................................................................................16
2.3.1Grafo de cena ..................................................................................................................18
2.3.2Detecção de colisão.........................................................................................................19
2.4 TRABALHOS CORRELATOS........................................................................................19
2.4.1Unity................................................................................................................................19
2.4.2SIO2 ................................................................................................................................20
2.4.3Oolong engine .................................................................................................................21
2.4.4M3GE: um Motor de Jogos 3D para Dispositivos Móveis com Suporte a Mobile 3D
Graphics API ...................................................................................................................21
3 DESENVOLVIMENTO....................................................................................................23
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO.......................23
3.2 ESPECIFICAÇÃO ............................................................................................................24
3.2.1Visão da biblioteca ..........................................................................................................24
3.2.2Diagrama de caso de uso.................................................................................................25
3.2.3Diagrama de classes ........................................................................................................26
3.2.3.1Geometrics ....................................................................................................................27
3.2.3.2Scene Graph..................................................................................................................27
3.2.3.3Wavefront Importer ......................................................................................................28
3.2.3.4Utils...............................................................................................................................29
3.2.4Diagrama de sequência ...................................................................................................30
3.3 IMPLEMENTAÇÃO ........................................................................................................32
3.3.1Técnicas e ferramentas utilizadas....................................................................................32
3.3.2Operacionalidade da implementação ..............................................................................32
3.3.2.1Início do projeto............................................................................................................32
3.3.2.2Construção do grafo de cena.........................................................................................34
3.3.2.3Realizando transformações no GroupNode ...............................................................35
3.3.2.4Controle da cena com toques na tela ............................................................................38
3.3.2.5Detecção de colisões.....................................................................................................39
3.3.2.6Importação de modelos 3D externos ............................................................................41
3.3.2.7Exemplos de aplicações ................................................................................................42
3.4 RESULTADOS E DISCUSSÃO ......................................................................................46
4 CONCLUSÕES..................................................................................................................48
4.1 EXTENSÕES ....................................................................................................................48
12
1 INTRODUÇÃO
Inicialmente o celular foi concebido com o propósito de permitir realizar ligações
telefônicas de qualquer lugar a qualquer momento, mas com a evolução das tecnologias foi
possível que o aparelho agregasse novas funcionalidades, desde ser utilizado para navegar na
internet, enviar e-mails e até para o entretenimento com jogos. Atualmente o celular de maior
destaque está sendo o iPhone, um smartphone produzido pela Apple Computer Inc., que em
74 dias atingiu a marca de 1 milhão de aparelhos vendidos, sendo que na segunda versão, o
iPhone 3G, somente foi necessário 1 semana para que atingisse esta marca (APPLE, 2008a).
O iPhone possui características básicas de qualquer smartphone, mas o que o está
destacando dos outros aparelhos é a possibilidade de suportar aplicações complexas voltadas
ao entretenimento. Este suporte é basicamente dividido em duas partes, o hardware e o
sistema operacional. O hardware possui soluções inovadoras para a Interface Humano-
Computador (IHC), utilizando acelerômetros, Global Positioning System (GPS) e tela multi-
toque. Estas tecnologias permitem um novo nível de interação do usuário com a aplicação. O
sistema operacional utilizado é o iPhone OS, baseado no sistema operacional Darwin, que
permite também o desenvolvimento utilizando a Application Programming Interface (API)
Open Graphics Library (OpenGL) versão Embedded System(ES). O OpenGL é um conjunto
de rotinas e padrões para o desenvolvimento de aplicativos gráficos, permitindo que sejam
criados aplicativos interativos que produzem imagens de objetos móveis em três dimensões.
Com a OpenGL é possível controlar a tecnologia da computação gráfica para produzir
imagens realísticas (WOO et al., 1999, p. xvii).
Recentemente a tecnologia evoluiu e a demanda por jogos mais realistas com suporte a
interação em tempo real aumentou. Junto a quantidade de pessoas interessadas, aumentaram
de uma pequena fração para um grande segmento da população, e muitas destas pessoas
também têm o interesse de não somente utilizar jogos mas também de desenvolvê-los. Possuir
uma boa história e uma boa jogabilidade são essenciais para um bom jogo, mas o problema
neste caso é a implementação (EBERLY, 2001, p. 2). Segundo Eberly (2001, p. 3) os motores
de jogos são bibliotecas de desenvolvimento responsáveis pelo gerenciamento do jogo, das
imagens, do processamento de entrada de dados e outras funções.
Baseado na crescente demanda por jogos, é proposto o desenvolvimento de um motor
para jogos 3D na plataforma iPhone (MJ3I), para que desenvolvedores com boas idéias de
jogos não tenham dificuldades em criar utilizando toda a tecnologia que a plataforma oferece.
13
1.1 OBJETIVOS DO TRABALHO
O objetivo deste trabalho é desenvolver um motor de jogos 3D para a plataforma
iPhone.
Os objetivos específicos neste trabalho são:
a) construir um grafo de cena para gerenciamento da renderização dos objetos;
b) definir técnicas para desenvolver o tratamento de colisão;
c) permitir a importação de objetos 3D para o motor;
d) implementar métodos para o tratamento de eventos;
e) implementar movimentação de câmera no ambiente 3D;
f) tratar regras para a iluminação e câmeras.
1.2 ESTRUTURA DO TRABALHO
Este trabalho é formado por quatro capítulos. O capítulo 2 apresenta as tecnologias
envolvidas, as partes do motor de jogos e apresentados os trabalhos correlatos. No capítulo 3 é
abordado a especificação do motor de jogos desenvolvido e apresenta sua operacionalidade
para o desenvolvimento de aplicativos. O capítulo 4 foca-se em apresentar as conclusões
gerais e possíveis futuras implementações.
14
2 FUNDAMENTAÇÃO TEÓRICA
Neste capítulo é exposta uma descrição mais detalhada das tecnologias que foram
empregadas no desenvolvimento do motor. Na seção 2.1 será apresentado a plataforma
utilizada e suas características. Na seção 2.2 será apresentado a biblioteca utilizada para criar
as imagens 3D e desenvolver o ambiente 3D. Na seção 2.3 serão apresentados comentários
sobre os motores de jogos 3D e algumas regras que deverão ser implementadas. Por fim na
seção 2.4 são apresentados os trabalhos correlatos ao tema em questão.
2.1 IPHONE
Segundo Apple (APPLE, 2008b) o iPhone, é um aparelho de telefonia celular que
possui uma série de inovações tecnológicas, entre elas a interface multi-toque que permite
toques na tela com mais de um ponto, o GPS que possibilita determinar a localização de onde
o dispositivo encontra-se, o acelerômetro que permite descobrir qual a posição do telefone em
referência a um eixo vertical, e mais dois sensores, de proximidade e quantidade de luz.
2.1.1 Multi-toque
Possuindo uma tela que detecta múltiplos toques e softwares inovadores, o iPhone
permite ser totalmente controlado pelos gestos multi-toque. A tela de multi-toque possui um
escudo que capta os toques utilizando campos elétricos e assim transmite as informações para
a tela de Liquid Crystal Display (LCD). Com o uso da API do iPhone é permitido o
reconhecimento e tratamento de gestos tais como: o “flick”, quando o dedo é passado
rapidamente no sentido horizontal; o “tap”, que é um simples toque na tela e o “pinch”, que
consiste no ato de tocar a tela em dois pontos e aproximá-los (APPLE, 2008b). A Figura 1
ilustra estes três tipos de gestos.
15
Figura 1 - Gestos utilizados no iPhone: flick, tap e pinch
2.1.2 Global Positioning System (GPS)
O GPS basicamente funciona com a informação obtida de satélites da órbita terrestre.
O receptor estima a distância considerando o tempo de demora para receber o sinal
proveniente do satélite, e assim é possível encontrar a localização. Porém, o iPhone utiliza o
Assisted GPS (A-GPS) que é uma solução para conseguir encontrar a posição mais
rapidamente, através de satélites GPS, rede sem fio em Hot Spots e torres de telefonia móvel.
Inicialmente tenta-se descobrir a localização via satélite, caso não seja possível é utilizada a
rede sem fio, e caso ainda não haja sinal de rede sem fio disponível, é utilizada a triangulação
de torres de telefonia celular (APPLE, 2008b).
2.1.3 Acelerômetros
O iPhone responde a movimentação utilizando um conjunto de acelerômetros
integrados. Por exemplo, quando o dispositivo é rotacionado da posição “retrato” para
“paisagem”, os acelerômetros detectam imediatamente esta mudança, podendo, por exemplo
alterar a posição da foto sendo visulizada, ou um web site em sua proporção mais adequada.
Também pode ser utilizado para o controle de jogos, entre outros.
Cada acelerômetro é baseado em três elementos: massa de silicone, mola de silicone e
corrente elétrica. O movimento do iPhone acaba gerando uma flutuação da corrente que passa
16
através das molas de silicone, e com estas variações de corrente é possível determinar qual é a
orientação em relação solo, pois o dispositivo possui três acelerômetros, um para cada eixo
cartesiano 3D (APPLE, 2008b).
2.1.4 Sensores
No dispositivo existem ainda outros dois sensores utilizados para captar informações
do exterior. O sensor de luz incluído é usado para detectar a luz do ambiente e diminuir a
iluminação de fundo do iPhone, desta forma economizando energia. Já o sensor de
proximidade foi criado para que não ocorra de ser tocado na tela ligada com a orelha durante
uma ligação, pois o sensor irá detectar se está próximo e automaticamente desabilita eventos
de toque na tela (APPLE, 2008b).
2.2 OPENGL
Conforme Woo et. al. (1999, p. 2), OpenGL é uma interface de gráficos do software
para o hardware. A OpenGL foi desenvolvida com o propósito de ser independente de
hardware. Para alcançar estas qualidades, não foram incluídos modos para interação com o
usuário. Similarmente, a biblioteca não disponibiliza comandos de alto nível para descrever
modelos 3D, somente oferece um grupo pequeno de primitivas geométricas tais como pontos,
linhas e polígonos.
Assim Munshi (2008, p. xxi) diz que OpenGL é um passo crítico nesta revolução de
computação móvel. Trazendo força da linguagem de shading OpenGL ES para diversas
plataformas móveis e embarcadas, OpenGL ES libera enorme poder de computação visual,
mas de uma forma programada para rodar em uma bateria de pequena capacidade.
2.3 MOTOR DE JOGO
O conceito de um motor de jogos é relativamente simples, ele existe para abstrair os
17
detalhes de processos comuns relacionados a jogos, como renderização, física e entrada, para
que assim os desenvolvedores (artistas, designers e programadores) possam se focar nos
detalhes que fazem do jogo único (WARD, 2008).
Segundo Eberly (2001, p. xxvii) um motor de jogos é uma entidade complexa que
consiste de mais que uma camada de renderização que desenha triângulos ou apenas uma
coleção de técnicas desorganizadas. Um motor de jogo deve lidar com problemas do
gerenciamento do grafo de cena, como o front-end que disponibiliza as entradas de volta para
o renderer, podendo ser um renderer baseado em software ou hardware. O motor também
deve oferecer a habilidade para processar objetos complexos se movimentando em um modo
fisicamente realístico. A Figura 2 apresenta o esquema das partes vitais de um jogo onde os
círculos contínuos são essenciais para qualquer jogo. É desejável que um motor de jogo
possua todos os elementos que estão pontilhados.
Input é onde o hardware faz a entrada dos dados, podendo ser um teclado, mouse, tela
touchscreen ou qualquer outro periférico de entrada. O Event_Handler se resposabiliza por
receber estes dados de entrada e trata-los para responder a ações no jogo, tais como mover um
carro, um personagem, etc. O item Game logic é a lógica do jogo, onde são realizados todos
os processamentos. Dynamics são as ações dinâmicas que o Game logic gera, que acaba
realizando alterações no Level_Data, que são os dados armazenados de todo o jogo. O
Level_data após sofrido alterações repassa para o Graphics, que pode ou apresentar a
resposta em forma gráfica para o Plataform, para o Audio ou pode enviar as alterações para
o Game logic onde pode realizar novos processamentos. Uma outra forma do Game logic
responder as ações do Event_Handler, seria para o Audio, onde o mesmo envia respostas
para a Plataform em forma de som.
Fonte: Whitted(1998, p. 47).
Figura 2 – Elementos básicos na criação de um jogo
18
2.3.1 Grafo de cena
O grafo de cena é responsável pela organização dos dados em um motor de jogo.
Segundo Pozzer (2007) os grafos de cena são estruturas de dados que utilizam da hierarquia
de objetos e atributos utilizados para especificar cenas complexas. De acordo com Eberly
(2005, p.150), o gerenciamento do grafo de cena é a camada do mais alto um nível da
renderização e pode ser visto como o front-end para o sistema de renderização. Conforme
Pozzer (2007), usar hierarquia dos objetos é o modo mais comum para se representar a cena,
onde as entidades básicas, como caixas, esferas e cilindros, são agrupadas para gerar objetos
mais complexos. Na implementação do grafo de cena pode-se utilizar uma hierarquia de
classes (Figura 3), onde a classe principal é a classe Node e as outras classes são descendentes.
Fonte: Pozzer (2007).
Figura 3 – Estrutura hierárquica do grafo de cena
Na figura 3 ainda são apresentadas algumas outras classes. A classe Camera define a
posição da câmera, modo de visualização, ponto de referência para visualizar. A classe Group,
é utilizada para agrupar elementos da cena, onde quando é realizado alguma transformação,
todos os elementos geométricos do grupo sofrem o mesmo. Na classe Appearance são
armazenadas as características que representam aparências de cor de objetos. Na classe
Light, são especificados as fontes luminosas da cena e por fim, Shape é a classe base de onde
todos os outros objetos geométricos são originados.
19
2.3.2 Detecção de colisão
Bobic (2000) afirma que desde o início da criação dos jogos os programadores tentam
simular o mundo de um modo mais preciso. Desde o jogo Pong, de 1972, já existia detecção
de colisão entre uma bola e dois retângulos, onde o jogador movia o retângulo para outra
posição e rebatia a bola para o oponente.
De acordo com Eberly (2005, p. 487), o conceito de detecção de colisão é a simulação
física do comportamento quando dois objetos colidem. A natureza do algoritmo utilizado
depende do tipo de objeto e qual informação é necessária pelo chamador da colisão. Eberly
(2005, p. 488) categoriza os algoritmos de detecção de colisão em duas partes: objetos
estacionários, onde os dois objetos não se movem e objetos móveis, usado quando os dois
objetos, ou somente um deles se move. Se ambos estão se movimentando é possível subtrair a
velocidade do primeiro da velocidade do segundo, para tratar o problema como se somente
existisse um objeto móvel.
2.4 TRABALHOS CORRELATOS
Existem projetos relacionados com o tema proposto. Entre eles, foram escolhidos
quatro que possuem mais afinidade com a área de estudo. Foram selecionados os seguintes
projetos: Unity (2008), SIO2 (2008), Oolong Engine (2008) e “Um Protótipo de Motor de
Jogos 3D para Dispositivos Móveis com Suporte a Especificação Mobile 3D graphics API for
J2ME” (PAMPLONA, 2005).
2.4.1 Unity
Unity (2008) é uma ferramenta comercial multi-plataforma voltada para o
desenvolvimento em jogos 3D. Esta ferramenta permite trabalhar com Direct X ou Open GL e
suporta modelos 3D, animações, texturas, scripts e sons criados em outros programas para
importação. Também suporta leitura de modelos 3D em vários formatos diferentes de
arquivos. Possui suporte para jogos em rede com vários usuários, com scripts de
20
sincronização e chamadas de procedimentos remotamente para os clientes disponíveis.
A engine destinada para os cálculos de física utilizada é o Angeia PhysiX uma das
mais avançadas atualmente. Unity suporta três linguagens de script: JavaScript, C# e um
dialeto de Python chamado Boo. Normalmente a interpretação dos scripts é lenta, mas
utilizados na ferramenta elas são compilados para código nativo e são quase tão rápidos
quanto C++.
A ferramenta possui opção para publicar o projeto no formato do iPhone, onde pode
ser criado o projeto e integrado ao aplicativo XCode para ser compilado e testado.
Fonte: Unity 3D (2008).
Figura 4 – Tela de edição da Unity.
2.4.2 SIO2
A SIO2 (2008) é um projeto open source de um motor de jogos para iPhone, podendo
ser feito o download da biblioteca gratuitamente no site. É disponibilizado para compra, um
certificado SIO2, com a aquisição o usuário tem atendimento priorizado pelo suporte, e tem
permissão para remover textos promocionais da aplicação, que são incluídos na versão
21
gratuita. A engine é escrita somente na linguagem C e compatível com OpenGL ES 1.1.
Possui tratamento de física, com detecção de colisão, sistemas de partículas e neblina. O
gerenciamento do áudio é realizado com a biblioteca OpenAL, possui controle de iluminação
e sombras, gerenciamento de texturas com filtros e transparências e animação.
Por final possui gerenciamento de cena, com tratamento de eventos, com a utilização
de scripts em linguagem LUA.
2.4.3 Oolong engine
Oolong (2008) é um motor de jogos escrito em C++ com algumas partes em Objective-
C. Suporta OpenGL ES 1.1 para os gráficos e Open Audio Library (OpenAL) para o áudio.
Possui gerenciamento de eventos como toques na tela e acelerômetro, utiliza para a
implementação de física 3D a biblioteca Bullet 3D.
Bullet 3D é uma biblioteca multi física que oferece a arte da detecção
de colisão, com dinâmica de corpos macios e rígidos. Esta biblioteca é
a mesma usada em jogos de empresas que produzem jogos para
Playstation3, Xbox e Nintendo Wii. (BULLET, 2009, tradução nossa).
2.4.4 M3GE: um Motor de Jogos 3D para Dispositivos Móveis com Suporte a Mobile 3D Graphics API
Segundo Pamplona (2005), o Mobile 3D Game Engine (M3GE) é um motor para jogos
desenvolvido em Java para dispositivos móveis. Possui as funcionalidades de: carregar e
desenhar um ambiente 3D a partir de um arquivo de configuração; criação de um número
indefinido de câmeras; tratamento de eventos do usuário; movimentação de personagens no
cenários com mapeamento de texturas e tratamento de colisão. O M3GE foi desenvolvida
como uma API auxiliar a já existente, a Mobile 3D Graphics API for J2ME (M3G).
A figura 5 apresenta uma demonstração do motor, em um jogo com a câmera em
quatro posições diferentes.
22
Fonte: Pamplona (2005).
Figura 5 – Exemplo da utilização do M3GE
23
3 DESENVOLVIMENTO
Este capítulo detalha as etapas do desenvolvimento da biblioteca. São apresentados os
requisitos, a especificação e a implementação do mesmo, mencionando as técnicas e
ferramentas utilizadas. Também são comentadas questões referentes à operacionalidade da
biblioteca e os resultados obtidos.
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO
Os requisitos apresentados encontram-se classificados em Requisito Funcional (RF)
e Requisito Não-Funcional (RNF), os quais são:
a) o sistema deverá possuir o gerenciamento dos objetos hierarquicamente (RF);
b) o sistema deverá realizar o controle de detecção de colisões existentes entre os
objetos (RF);
c) o sistema deverá permitir que sejam importados objetos 3D criados em outros
ambientes (RF);
d) o sistema deverá possuir controles para a entrada de dados no motor de jogos (RF);
e) o sistema deverá tratar regras para a iluminação e câmeras (RF);
f) o sistema deverá ser implementado na linguagem de programação Objective-C
(RNF);
g) o sistema deverá ser implementado com a ajuda das bibliotecas disponíveis no
iPhone SDK (RNF);
h) o sistema deverá ser implementado utilizando o ambiente de desenvolvimento
XCode 3.1 (RNF);
i) o sistema deverá utilizar a biblioteca OpenGL ES para a renderização baseado no
grafo de cena (RNF).
24
3.2 ESPECIFICAÇÃO
A especificação da biblioteca em questão foi desenvolvida seguindo a análise orientada
a objetos, utilizando a notação Unified Modeling Language (OMG, 2005). Sua a
representação lógica é apresentada através dos diagramas de casos de uso, classes e sequência,
os quais foram confeccionados utilizando as ferramentas OmniGraffle da OmniGroup (THE
OMNI GROUP, 2009) e o Netbeans (NETBEANS, 2009).
3.2.1 Visão da biblioteca
O MJ3I é uma camada intermediária que se localiza entre o a aplicação e o Open GL
ES, conforme figura 6. Apesar da biblioteca disponibilizar rotinas para o desenvolvimento do
jogo ainda é possível acessar o OpenGL ES diretamente. O motor de jogos além de se basear
no OpenGL ES para realizar a renderização também utiliza a biblioteca UIKit ,
disponibilizada pela própria Apple, que integrada com o iPhone OS é possível capturar os
toques na tela.
Figura 6 – Visão da camada da biblioteca do motor
25
3.2.2 Diagrama de caso de uso
O diagrama apresentado na figura 7 apresenta as principais ações que a aplicação terá
acesso com a biblioteca.
Figura 7 – Diagrama de casos de uso
O caso de uso Incluir modelos geométricos 3D no grafo de cena é utilizado
para incluir modelos no grafo de cena, que será o sistema para gerenciar todos os modelos
geométricos utilizados na aplicação.
No segundo caso de uso Aplicar transformações nos nodos do grafo de cena,
permite a aplicação realizar tranformações nos nodos do grafo, que são aplicados em todos os
modelos e outros nodos que estão conectados hierarquicamente com o nodo transformado. As
tranformações possíveis são: Translação, Rotação e Escala.
A partir do caso de uso Importar modelos 3D do arquivo, é possível que seja
incluído na aplicação um modelo 3D de um arquivo. O modelo pode ser desenvolvido em
outras aplicações voltadas a modelagem 3D, como Blender, 3D Studio max entre outros.
Como estas ferramentas são voltadas a criar modelos, o processo se torna mais rápido e
preciso, chegando a um maior nível de detalhe.
No caso Movimentar câmeras no plano, será permitido que a aplicação movimente
a câmera no plano 3D, e possibilita que seja selecionado qual é o ponto quem que a câmera
estará focada.
26
3.2.3 Diagrama de classes
A figura 8 apresenta as classes e estruturas desenvolvidas que formam toda a
biblioteca.
Figura 8 – Diagrama de classes
O projeto da biblioteca foi separado em quatro pacotes principais, Geometrics, Scene
Graph, Wavefront Importer e Utils, conforme apresentado na Figura 8.
27
3.2.3.1 Geometrics
A classe Vertex3d é a mais básica do pacote, possui os atributos x, y, e z para
armazenar as coordenadas do plano de três dimensões, também possui um método construtor
com os três parâmetros das coordenadas para facilitar na codificação.
Face é a classe onde é armazenado os quatro vértices para o desenho de uma face na
tela. Possui como atributo um array de Vertex3d, chamado de arrayV, com os dados das
coordenadas, o atributo é acessado através do método addVertex passando um objeto do tipo
Vertex3d como parâmetro. Como o OpenGL ES utiliza o modelo de cores RGB (Red, Green,
Blue) foi criado o array aRGB , destinado para armazenar os dados das cores da face. O
array possui o tamanho de três justamente para salvar o valor relativo a intensidade da cor
vermelha, verde e azul , podendo variar entre o mínimo de zero e o máximo de um. Ainda na
classe face existe o atributo mode do tipo GLenum, que é utilizado para definir o tipo de
primitiva que será renderizado, possuindo o valor de uma constante conforme pré-definido
pela biblioteca OpenGL ES (GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES,
GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and GL_TRIANGLES) .
A classe Cube, é responsável por criar formas geométricas de um cubo no plano 3D. O
processo de renderização do cubo é feito com a união de seis faces distintas. O início da
criação do cubo é no método construtor initWithSideSizevertexCenter onde é passado
dois parâmetros, o sizeValue que é do tipo GLfloat que será utilizado para definir qual será
o tamanho do cubo, e também o vertexCenter, que é um objeto do tipo Vertex3d que é
definido um ponto central no plano onde o cubo será renderizado. A partir dos parâmetros
informados é possível definir o tamanho do cubo e sua posição no plano 3D.
3.2.3.2 Scene Graph
Neste pacote é contido as classes responsáveis para realizar a construção do grafo de
cena, utilizado para o gerenciamento no ambiente 3D. É composto por duas classes,
GroupNode e Leaf.
A classe GroupNode é representado conforme figura 8, possui como atributo um array
de dados de nome leaves do tipo NSMutableArray que será utilizado para armazenar os
objetos geométricos (objetos que herdarem da interface Leaf) e outros objetos do tipo
28
GroupNode. Os outros atributos existentes na classe são utilizados como parâmetros para
realizar as transformações nos objetos geométricos existentes incluídos no GroupNode.
O método addLeaf é utilizado para adicionar novos objetos geométricos no array
leaves, o parâmetro utilizado é um objeto do tipo Leaf. O método draw não possui
parâmetros e o seu retorno é nulo. O que é feito neste método é buscar todos os objetos que
foram incluídos no array leaves e é executado o método draw destes objetos adicionados.
Por fim a classe possui o método transform, que executa as transformações, baseado nos
valores dos atributos da classe.
A interface Leaf na verdade possui o método draw, esta interface será utilizada para
que as classes que herdam possuam o método draw e possam ser adicionada ao grafo de cena,
também possui o atributo bb, tipo BoundingBox, e o método getBb, para obter o atributo, que
será abordado com mais detalhes na seção 3.2.1.4 .
3.2.3.3 Wavefront Importer
Optou-se por realizar a importação de modelos 3D no formato WaveFront, por possuir
compatibilidade com vários softwares de modelagem. Para importar os modelos foi incluído
no MJ3I classes já existentes desenvolvidas por Jeff LaMarche, co-autor do livro “Beginning
iPhone Development: Exploring the iPhone SDK”.
Para adequação do objeto geométrico importado para o ambiente 3D, com o grafo de
cena desenvolvido, foi criada a classe WaveFrontModel, conforme figura 8, que possui
herança com a interface Leaf, desta forma o objeto pode ser incluído no grafo de cena. A
classe é composta pelo atributo all do tipo WaveFrontOBJScene, que é utilizada para a
importação do arquivo. Também possui os métodos draw e getBB, herdados da classe Leaf,
para renderizar e obter o BoundingBox, respectivamente. Por fim existe o método construtor
initWithModel onde é passado como parâmetro um objeto tipo NSString com o nome do
arquivo wavefront, que deve estar previamente incluído na pasta Resources do projeto.
29
3.2.3.4 Utils
Este pacote possui algumas rotinas complementares para o motor de jogos. É composto
pelas classes TouchesHandler, Camera e Bounding Box, conforme figura 8.
A classe TouchesHandler é responsável pelo tratamento dos toques múltiplos na tela
para que seja traduzido, para gestos conhecidos no iPhone, como o flick e pinch. Estas rotinas
não estão previamente implementadas no sistema operacional do iPhone, somente existem
dentro do framework UIKit, utilizado para o desenvolvimento da interface gráfica. A classe é
formada pelo atributo touchState, que apresenta qual é o estado do gesto em forma de um
número inteiro. Cada gesto possui um valor inteiro já pré definido e que é fixo. Caso o
atributo possua o valor zero (0), o evento realizado por último é um toque simples na tela,
caso seja valor um (1), o gesto é um flick e caso seja de valor dois (2), o gesto é um pinch. Os
métodos handlerBegan, handlerMoved e handlerEnded são utilizados como entrada dos
dados de toque na tela, e devem ser incluídos nos métodos touchesBegan, touchesMoved e
touchesEnded da aplicação que utilizará o motor de jogos. A entrada de informações destes
métodos possibilita a realização do processamento e definição de qual é o valor do atributo
touchState.
A classe Camera implementa o controle da câmera, o objetivo desta classe é facilitar a
movimentação e controle da janela de visualização do openGL ES no espaço 3D. De um
ponto de vista mais abstrato a classe é como se fosse uma câmera no mundo real, onde o que
define a imagem é o que está sendo filmado pela câmera e de onde está sendo filmado, e são
justamente estes os dados que são passados como parâmetros na chamada do método de
movimentação da câmera. No método gluLookAt, os três primeiros parâmetros (eyeX, eyeY e
eyeZ), são utilizados para definir no espaço 3D a posição do ponto onde a camera estará
visualizando, os seguintes próximos três parâmetros (centerX, centerY e centerZ), definem
onde fica a posição da janela de visualização e por final, os o conjunto de parâmetros (upX,
upY e upZ), é utilizado para informar qual é a direção do vetor para cima.
BoundingBox é a classe utilizada para os controles de detecção de colisão, onde são
armazenados os dados de limites da dimensão de algum objeto geométrico, para a facilitação
do cálculo de colisão. A classe possui o atributo arrayV que é uma array de 8 posições do
tipo Vertex3d, é neste atributo que possui os dados dos vértices do plano 3D para a formação
30
de um paralelepípedo de um objeto geométrico, que é utilizado como limite nos cálculos de
colisão com outros objetos. Para a inclusão de novos valores limites existe o método
addVertex onde o parâmetro é um objeto do tipo Vertex3d. O último método da classe é o
findCollision que possuirá como parâmetro um objeto do tipo GroupNode. O parâmetro do
tipo GroupNode é utilizado para buscar no grafo de cena os objetos do tipo Leaf descendentes
que possuam BoundingBox informados nos atributos, e entre estes são realizadas análises para
verificar se algum BoundingBox possui pelo menos um vértice dentro do limite do
paralelepípedo no BoundingBox que esteja executando o método, caso possua é detectada a
colisão e o método retorna um objeto do tipo Leaf que possui o BoundingBox que colidiu.
3.2.4 Diagrama de sequência
O diagrama da figura 9 apresenta o processo para gerar a posição dos vértices de um
cubo. As classes utilizadas são: Cube, Face e Vertex3d.
31
Figura 9 – Diagrama de seqüência, apresentando a construção de um cubo
32
3.3 IMPLEMENTAÇÃO
Esta seção apresenta as bibliotecas e ferramentas utilizadas para o desenvolvimento do
motor de jogos proposto, junto com uma descrição da sua operacionalidade, com trechos do
código fonte para um melhor entendimento.
3.3.1 Técnicas e ferramentas utilizadas
As tecnologias utilizadas para o desenvolvimento da proposta foram as seguintes:
a) a linguagem utilizada para realizar a implementação foi a Objective-C, que é uma
linguagem derivada do C em que foram adicionadas algumas capacidades do
Smalltalk;
b) a integrated development environment (IDE) utilizado para a codificação da
biblioteca foi o xCode, disponibilizado pela Apple no suite de ferramentas de
desenvolvimento com o mesmo nome;
c) para depurar a biblioteca, foi utilizado o Iphone Simulator, que funciona integrado
com a IDE do xCode;
d) a API utilizada para a geração das imagens gráficas no espaço 3D foi o Open GL
ES, desenvolvida para sistemas embarcados.
3.3.2 Operacionalidade da implementação
Para utilizar o motor de jogos inicialmente é aconselhado a escolha da ferramenta de
desenvolvimento xCode, por ser completa, integrada com simulador, e possuir todo suporte
oficial da Apple.
3.3.2.1 Início do projeto
Ao iniciar uma implementação visando a utilização da MJ3I, pode–se optar em utilizar
o template “OpenGL ES Application”, que é um template já padrão existente no System
33
Development Kit (SDK) do iPhone, conforme figura 10.
Figura 10 – Tela onde são apresentados os templates padrões existentes
O template pode ser utilizado como um ponto de partida para a aplicação que utiliza
OpenGL ES, pois já possui incluído uma classe de tela onde pode ser renderizado a cena e um
temporizador para permitir a animação da cena.
Neste template é necessário realizar algumas configurações para funcionamento com a
MJ3I, no método initWithCoder é necessário adicionar a linha de código,
glEnable(GL_DEPTH_TEST), para a configuração do OpenGL ES, conforme quadro 1. - (id)initWithCoder:(NSCoder*)coder { if ((self = [super initWithCoder:coder])) { // Get the layer CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; eaglLayer.opaque = YES; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; if (!context || ![EAGLContext setCurrentContext:context]) { [self release]; return nil; } animationInterval = 1.0 / 60.0; } glEnable(GL_DEPTH_TEST); return self; }
Quadro 1 – Apresenta a linha de comando glEnable( GL_DEPTH_TEST )
O método glEnable é originado da biblioteca do OpenGL ES e tem como finalidade
habilitar capacidades do GL. O parâmetro passado é uma constante que define qual
capacidade será habilitada, no caso o GL_DEPTH_TEST irá fazer comparações de
34
profundidade e atualizar o buffer de profundidade. Mesmo que já exista um buffer de
profundidade o mesmo não será atualizado se o GL_DEPTH_TEST não estiver habilitado.
Continuando no método initWithCoder, é sugerido que no final do método, seja
realizado uma chamada a um novo método com o objetivo de instanciar todos os objetos que
irão existir no plano 3D, para que somente seja instanciado uma vez logo após a criação da
própria janela de visulização do OpenGL ES.
3.3.2.2 Construção do grafo de cena
O primeiro objeto a se instanciar é da classe GroupNode, que é o nó raiz do grafo de
cena, e apartir deste nó que serão incluídos os objetos geométricos e outros nós descendentes.
Após ter o nó raiz instanciado, pode-se utilizar o método addLeaf para adicionar os objetos
que serão renderizados. No quadro 2 é apresentado um exemplo de como pode ser iniciado o
grafo de cena e incluída a figura geométrica de um cubo. -(void)load{ rootNode = [[GroupNode alloc] init]; Cube *cubeTmp = [[Cube alloc] initWithSideSize: 0.5f vertexCenter: [[Vertex3d alloc] initWithValueX: 0.0f valueY: 0.0f valueZ: 0.0f]]; [rootNode addLeaf:cubeTmp]; }
Quadro 2 – Alocação do nó raiz e do cubo
Utilizando o método construtor do cubo initWithSizevertexCenter, somente é
necessária a utilização de dois parâmetros, o tamanho do lado do cubo e a posição inicial de
onde o cubo será renderizado. A posição inicial do cubo é no plano 3D, desta forma foi
passado como parâmetro um objeto do tipo Vertex3d que contém as informações das
coordernadas x, y, e z.
Para apresentar em tela o cubo ainda é necessário reestruturar o método drawView, já
existente proveniente do template. Este é o método onde é realizado todas as renderizações,
por padrão a implementação do método traz uma rotina para renderizar um quadrado 2D
girando. Esta implementação deve ser substituída por dois métodos que devem ser utilizados,
gluLookAt, para a câmera, e draw para o nó.
O método gluLookAt deve ser utilizado, passando os parâmetros da posição do objeto
a ser visualizado, que no caso é a mesma posição utilzada ao instanciar o cubo, e deve ser
informado a posição da câmera. O segundo método a ser utilizado é o draw, este método é
35
originado do objeto Node que possui o cubo adiciondo. No quadro 3 é apresentado a
implementação de ambos. - (void)drawView { [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glViewport(0, 0, backingWidth, backingHeight); glMatrixMode(GL_MODELVIEW); glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0.0, 1.0, 0.0); [rootNode draw]; glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; }
Quadro 3 – Método drawView reimplementado
3.3.2.3 Realizando transformações no GroupNode
Como o cubo foi adicionado a um nó do grafo de cena, pode-se adicionar operação de
rotação, translação ou escala. Para adicionar uma operação basta alterar o valor do atributo
referente a transformação do GroupNode desejado. As transformações são implementadas ao
executar o método draw do GroupNode, conforme apresentado no quadro 4.
36
- (void) draw{ glPushMatrix(); glTranslatef(tX, tY, tZ); glScalef(sX, sY, sZ); glRotatef(rA, rX, rY, rZ); NSEnumerator * enumerator = [leaves objectEnumerator]; id element; while(element = [enumerator nextObject]) { [element draw]; } glPopMatrix(); }
Quadro 4 – Método draw da classe GroupNode
Antes de realizar as transformações foi utilizado o método glPushMatrix para que
seja empilhada a matriz atual, e após as alterações e renderização a matriz foi desempilhada,
desta forma as transformações somente são aplicadas nos objetos geométricos descendentes
do GroupNode.
Para realizar a transformação de rotação, é necessário alterar o atributo rA, valor do
ângulo da rotação em graus e definir qual o valor dos eixos cartesianos utilizados para realizar
a rotação, rX, rY e rZ. Na figura 11 é apresentado o resultado da rotação de um GroupNode
que possui um cubo na array leaves, com valores variados de rA e valores fixos para rX, rY e
rZ.
Figura 11 – Cubo realizando rotação, conforme valores do GroupNode
37
A rotação é realizada somente baseado no eixo cartesiano X, mas é possível também
realizar rotações baseadas em mais de um eixo, conforme apresentado na figura 12 onde o
cubo é rotacionado em dois eixos, X e Z com ângulo de 45 graus.
Figura 12 – Cubo rotacionado 45 graus em dois eixos
A translação pode ser definida alterando os atributos tX, tY e tZ do GroupNode. Estes
atributos são iniciados com o valor zero, alterando o tX será alterado a posição conforme eixo
cartesiano X, o atributo tY é referente ao eixo cartesiano Y e o tZ é referente ao eixo Z. Na
figura 13 é exemplificado uma translação variando o valor de tX.
Figura 13 – Um cubo rebendo a transformação de translação no eixo X
38
A última transformação possível é a escala, esta é definida pelos atributos sX, sY e sZ.
O valor inicial dos atributos é de 1, são os atributos que especifica o fator de escala dos eixos
X, Y e Z. Considerando que 1 é o “elementro neutro” da escala geométrica, para dobrar o
tamanho em algum eixo, ou em todos, o valor deve ser 2 e caso desejo seja diminuir o
tamanho pela metade o valor deve ser 0,5 . Na figura 14 é exemplificado o uso de escala e
seus resultados visuais.
Figura 14 – Utilização da escala em um cubo
3.3.2.4 Controle da cena com toques na tela
Para a utilização da classe TouchesHandler, é necessário possuir alguns métodos já
criados na classe principal que possui a view, para receber os eventos de toque na tela. Estes
métodos tem nomeclaturas padrões do iPhone OS e são executadas em três momentos
diferentes da interação com a tela do iPhone. Ao iniciar o toque na tela o método utilizado é o
touchesBegan(NSSet *), após tocar na tela e realizar movimentos mantendo contato com a
tela, o método executado é o touchesMoved(NSSet *) e por final, ao remover o contato com
a tela será utilizado o método touchesEnded(NSSet *).
39
Todos os três métodos tem o mesmo parâmeto que será recebido, que é um objeto do
tipo NSSet, um agrupador de objetos não ordenados. Os objetos que podem ser incluídos no
NSSet são do tipo UITouch, estes objetos possuem o método locationInView que retorna um
CGPoint, uma estrutura onde são armazenados dois pontos no espaço cartesiano da tela, x e y.
Ligado ao NSSet é possível existir mais de um objeto tipo UITouch, pois como a tela no
iPhone suporta toques múltiplos, se houver no caso mais que um toque, será enviado ao
evento um objeto do tipo UITouch para cada toque em tela.
No método touchesBegan deve ser alterado e incluído uma chamada para o método
handlerBegan do objeto TouchesHandler, que realiza o processamento para definir qual o
tipo de gesto em tela foi realizado. O mesmo deve ser feito para o touchesMoved que deve ser
incluído a chamada do handlerMoved e no touchesEnded incluído o handlerEnded. Após a
inclusão dos métodos do TouchesHandler é possível realizar a leitura do atributo
touchState e realizar as implementações necessárias em resposta de cada gesto realizado,
conforme apresentado no quadro 5. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [th handlerBegan:touches]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [th handlerMoved:touches]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [th handlerEnded:touches]; if (th.touchState == 0) { //Touch - do something } else if (th.touchState == 1 ){ //Flick - do something } else if (th.touchState == 2 ){ //Pinch - do something } }
Quadro 5 – Utilização da classe TouchesHandler
3.3.2.5 Detecção de colisões
A detecção de colisão do motor MJ3I é baseada na classe BoundingBox, que é
40
responsável por informar os limites das dimensões do objeto geométrico no plano, e o
GroupNode que realiza a rotina para detectar colisões entre BoundingBox de diferentes
objetos.
Inicialmente ao incluir algum objeto geométrico no GroupNode, deve ser instanciado
também o atributo bb, existente na interface Leaf, e definir os valores do tamanho da
bounding box, adicionando os valores limites através do método addVertex do objeto
BoundingBox.
Após o objeto geométrico possuir uma BoundingBox e estiver incluído em algum
GroupNode do grafo de cena. É possível utilizar o método detectCollision do GroupNode,
este método possui como parâmetro um objeto do tipo Leaf, como todo objeto que herde da
interface Leaf possui um método getBb é possível obter o BoundingBox que pode ser
comparado com todos os BoundingBox dos objetos agregados ao GroupNode que executou o
método detectCollision. Na figura 15 é apresentado a colisão entre dois cubos.
Figura 15 – Colisão detectada
41
3.3.2.6 Importação de modelos 3D externos
Uma outra parte funcional do MJ3I está na possibilidade de importar modelos 3D de
arquivos externos para o software aplicativo. Neste caso, o formato de arquivo utilizado é o
obj (IPHONE DEVELOPMENT, 2008). Inicialmente para realizar a importação do modelo,
deve-se incluir o arquivo de modelo desejado na pasta Resources do projeto no ambiente de
desenvolvimento xCode.
Para auxiliar na importação do arquivo e se adequar ao padrão dos objetos
geométricos do motor de jogos, e sua respectiva compatibilidade com o grafo de cena, é
necessário utilizar a classe WaveFrontModel, pois esta classe herda da interface Leaf e assim
os objetos gerados podem ser incluídos ao grafo de cena. Para instanciar o objeto utiliza-se o
método construtor initWithModel que possui como parâmetro um objeto do tipo NSString,
este parâmetro é o nome do arquivo de modelo que foi previamente incluído na pasta
Resources.
Após instanciar a classe e definido o modelo, basta incluir no grafo de cena, da mesma
forma que é incluído qualquer outro objeto geométrico, através do método addLeaf do
GroupNode. Na figura 16 é apresentado um modelo importado.
42
Figura 16 – Modelo 3D importado para o iPhone
3.3.2.7 Exemplos de aplicações
Foi desenvolvido três aplicações exemplo para explorar as funcionalidades
desenvolvidas do motor.
43
Figura 17 – Aplicação exemplo 1
A primeira aplicação, conforme figura 17, foi incluído um cubo que realiza a
transformação de rotação. A interface para realizar a rotação no modelo é realizada através de
toques na tela, onde a tela foi separada em quatro quadrantes: superior, inferior, direita e
esquerda. Caso seja realizado um gesto de tap no quadrante superior ou inferior será realizado
uma rotação em função do eixo X de 1 grau, caso seja no quadrante esquerdo ou direto a
rotação será realizada em função do eixo Y. Se o gesto utilizado for um flick ao invés do tap,
a rotação será de 30 graus.
Na segunda aplicação o foco foi a movimentação da câmera junto com a importação de
modelos 3D. Na figura 18 é apresentado a aplicação, e a mesma foi igualmente controlada por
toques na tela em quatro quadrantes.
44
Figura 18 – Aplicação exemplo 2
Toques na tela, no quadrante superior e infeior, irão movimentar a câmera no plano
horizontal, nos eixos X e Z. Caso seja realizado toques na tela no esquerdo ou direito o centro
da visão da câmera que será alterado de lugar, girando em torno da câmera para a esquerda ou
direita. O toque duplo na tela na parte superior ou inferior irá fazer com que a câmera altere
sua posição em função do eixo Y.
Na terceira aplicação, conforme figura 19, o controle separou a tela em dois
quadrantes: direita e esquerda.
O toque no quadrante da esquerda, fará com que os cubos realizem translação para a
direita, e o objeto geométrico na parte inferior da tela realize uma rotação em função do eixo
Z para a esquerda, desta forma irá causar a impressão de que o objeto geométrico esteja se
movendo para a esquerda. O toque no quadrante da direita irá fazer com que os objetos
realizem as mesmas transformações mas no sentido inverso do toque do quadrante da
esquerda.
45
Figura 19 – Aplicação exemplo 3
46
3.4 RESULTADOS E DISCUSSÃO
O presente trabalho apresentou o projeto e desenvolvimento de um motor de jogos para
o iPhone OS, construindo uma estrutura para o controle e gerenciamento dos objetos
geométricos na cena. A estrutura é gerada em forma de árvore permitindo que possua n
objetos por nó e que a árvore possua h níveis. Como resultado é possível gerenciar cenas
coma vários objetos geométricos e controlar suas respectivas transformações. Na figura 17 é
apresentado o diagrama de um grafo de cena.
Figura 20 – Diagrama do grafo de cena
Na figura 18 é apresentado o resultado final em tela da organização apresentada no
diagrama do grafo de cena.
47
Figura 21 – Possui os objetos geométricos organizados conforme grafo de cena
Existe a possibilidade de realizar melhorias na rotina de importação de modelos.
Inicialmente poderia se tomar dois rumos para melhorar o desempenho. Um deles seria criar
um formato novo para leitura do modelo, o qual seria limitado para importar somente os
dados essenciais de um modelo mais simples, como somente permitir utiliziar modelos com
faces de três vértices. Uma segunda opção seria que ao realizar a exportação do modelo 3D
desenvolvido em uma ferramenta de terceiros, já exportasse os vértices no formato de array
para o código fonte do programa, na linguagem Objective-C, criando já a classe e mantendo
os vértices do modelo como uma com valores fixos, desta forma não existindo a necessidade
da leitura de um arquivo externo e conversão dos dados do modelo para a aplicação.
Um dos problemas encontrados foram no compilador, que existiam erros no código
fonte que poderiam ser apresentados em tempo de compilação, porém somente era
apresentado em tempo de execução, como por exemplo quando existe uma primeira classe
que, em uma segunda classe a primeira é referenciada e é utilizado algum método da primeira,
caso seja referenciado o método incorretamente o compilador somente irá apresentar o erro
em tempo de execução
48
4 CONCLUSÕES
O presente trabalho apresentou o projeto e desenvolvimento de um motor de jogos para
o iPhone OS. Foi desenvolvido o grafo de cena para controle e gerenciamento da cena,
tratamento de gestos em tela controle de câmera, detecção de colisão e importação de modelos
3D, dos requisitos propostos inicialmente só “um” requisito foi parcialmente cumprido, “tratar
regras para a iluminação e câmeras (RF)”, não foi completado, pois demandou um tempo
maior para o desenvolvimento.
Os resultados finais foram satisfatórios, pois foi possível realizar a renderização da
cena. Se houver a necessidade de mais desempenho, poderia se ter optado em uma estrutura
menos fundamentada em orientação a objetos. Na rotina de importação de modelos 3D, uma
das principais partes em relação a desempenho, acredita-se em no mínimo outros dois
caminhos que iriam melhorar a desempenho.
Quanto as tecnologias utilizadas, a IDE de desenvolvimento xCode, se tornou
suficiente e eficiente para o desenvolvimento. A integração com o simulador do iPhone
facilita muito no desenvolvimento.
Como limitação o MJ3I não possui rotinas para tratamento de física, que é algo que
com o tempo cada vez mais o usuário final exige em um jogo.
Como vantagem o motor de jogos 3D para iPhone, possui uma arquitetura de fácil
entendimento por ter sido optado pela utilização da orientação a objetos e a utilização da
linguagem Objective-C que possui um melhor suporte oficial da Apple para o
desenvolvimento na plataforma iPhone OS.
4.1 EXTENSÕES
Como sugestão para um trabalho futuro, seria a inclusão de novas rotinas nas
funcionalidades já existentes, como no grafo de cena onde pode-se incluir uma rotina para
remover objetos do grafo para manipular o mesmo, ou o uso de indexação no grafo para
49
agilização nas buscas.
Como melhoria poderia ser desenvolvido uma rotina de importação de modelos com
um foco maior em performance. Também poderia ser incluído tratamentos de novos gestos na
classe de TouchesHandler, com a adição de controles utilizando o acelerômetro do iPhone.
Outras rotinas que poderiam ser incluídas no motor de jogos, seria para realizar o
tratamento de física no jogo, possivelmente com a utlização da biblioteca Bullet, um projeto
open source. O tratamento de áudio no jogo com bibliotecas como OpenAL também seriam
uma boa opção para apresentar as rotinas com um nível melhor de realidade.
50
REFERÊNCIAS BIBLIOGRÁFICAS
APPLE. Apple sells one million iPhone 3Gs in first weekend. [S.l.], 2008a. Disponível em: <http://www.apple.com/pr/library/2008/07/14iphone.html>. Acesso em: 17 mar. 2009.
______. Iphone features. [S.l.], 2008b. Disponível em: <http://www.apple.com/iphone/features/>. Acesso em: 22 mar. 2009.
BOBIC, Nick. Advanced collision detection techniques. [S.l.], 2000. Disponível em: <http://www.gamasutra.com/features/20000330/bobic_01.htm>. Acesso em: 26 mar. 2009.
BULLET. Bullet physics library. [S.l.], 2009. Disponível em: <http://code.google.com/p/bullet/>. Acesso em: 26 mar. 2009.
EBERLY, David H. 3D game engine architecture: engineering real-time applications with wild magic. San Francisco: Morgan Kaufmann Publishers, 2005. p. 149.
_____________. 3D game engine design: a pratical approach to real-time computer graphics. San Diego: Morgan Kaufmann Publishers. 2001. p. xxvii.
IPHONE DEVELOPMENT. Application development for the iPhone using Apple’s official SDK. [S.l.], 2008. Disponível em: <http://iphonedevelopment.blogspot.com/2008/12/wavefront-obj-loader-another-update.html />. Acesso em: 15 jul. 2009.
MUNSHI, Aaftab; GINSBURG, Dan; SHREINER, Dave. Open GL ES 2.0: programming guide. Upper Saddle River: Addison-wesley, 2008. p. xxi
NETBEANS. Netbeans IDE. [S.l.], 2009. Disponível em: <http:// http://netbeans.org/>. Acesso em: 5 nov. 2009.
OMG. UML - Unified Modeling Language specification. Version 2.0. [S.l.], 2005. Disponível em: <http://www.uml.org/>. Acesso em: 5 nov. 2009.
OOLONG. Oolong engine. [S.l.], 2008. Disponível em: <http://code.google.com/p/oolongengine/>. Acesso em: 26 mar. 2009.
PAMPLONA, Vitor F. Um protótipo de motor de jogos 3D para dispositivos móveis com suporte a especificação mobile 3D graphics API for J2ME. 2005. 83 f. Trabalho de Conclusão de Curso (Bacharelado em Ciências da Computação) - Centro de Ciências Exatas e Naturais, Universidade Regional de Blumenau, Blumenau.
51
POZZER, Cesar T. Grafo de cena [S.l.], 2007. Disponível em: http://www-usr.inf.ufsm.br/~pozzer/disciplinas/cga_2_grafo_cena.pdf . Acesso em: 20 mar. 2009.
SIO2. SIO2 interactive. [S.l.], 2008. Disponível em: <http://www.sio2interactive.com/HOME/HOME.html>. Acesso em: 26 mar. 2009.
THE OMNI GROUP. OmniGraffle. [S.l.], 2009. Disponível em: <http://www.omnigroup.com/applications/OmniGraffle/>. Acesso em: 5 nov. 2009.
UNITY 3D. Unity: features. [S.l.], 2008. Disponível em: <http://unity3d.com/unity/features/iphone-publishing>. Acesso em: 25 mar. 2009.
WARD, Jeff. What is a game engine? [S.l.], 2008. Disponível em: <http://www.gamecareerguide.com/features/529/what_is_a_game_.php?page=1>. Acesso em: 25 mar. 2009.
WOO, Mason et al. OpenGL programming guide: the official guide to learning OpenGL. Upper Saddle River: Addison-wesley, 1999.
WHITTED, Turned et al. IEEE Computer Graphics and Applications. Designing a PC game engine, v. 18, p. 46-53, Jan. 1998.