No mercado de realidade virtual existem algumas ferramentas comercias de desenvolvimento. O uso destas ferramentas, entretanto, em face de seu custo elevado, ainda não é uma realidade no meio acadêmico brasileiro. Na maioria dos grupos de pesquisa em realidade virtual do Brasil, a falta de ferramentas de desenvolvimento tem limitado os trabalhos principalmente pelos seguintes aspectos:
·Falta de leitores de modelos tridimensionais de objetos;
·Falta de drivers de leitura de dispositivos de realidade virtual;
·Dificuldade de modificação de uma aplicação para a troca de um dispositivo de realidade virtual por outro diferente;
·Dificuldade de gerenciamento de ambientes gráficos tridimensionais com elevado número de faces;
·Dificuldade no desenvolvimento de técnicas de interação em ambientes de realidade virtual;
·Pouca portabilidade do código gerado para aplicações de realidade virtual;
·Dificuldade em adequar aplicações pré-existentes de computação gráfica para ambientes com dispositivos de realidade virtual;
·Dificuldade na exibição de imagens em múltiplas telas.
Em face deste cenário foi desenvolvida uma arquitetura de suporte à criação de aplicações de realidade virtual, a SmallVR. Este desenvolvimento baseia-se em experiências prévias de desenvolvimento de bibliotecas de suporte a dispositivos de realidade virtual, no desenvolvimento de bibliotecas gráficas tridimensionais e no desenvolvimento de aplicações de realidade virtual com outras bibliotecas gráficas existentes.
Além do desenvolvimento de projetos em disciplinas, esta ferramenta tem sido utilizada no desenvolvimento projetos de pesquisa, bem como em escolas técnicas do SENAI-RS, sem custo e sem a necessidade de um longo tempo de aprendizagem.
Este artigo está organizado da seguinte forma. Primeiramente, faz-se um resumo das características de algumas ferramentas de desenvolvimento para aplicações de realidade virtual, apresentando os pontos em que se julga, estas poderiam ser melhoradas a fim de torná-las adequadas ao ambiente acadêmico brasileiro. A seguir inicia-se a apresentação da arquitetura da SmallVR, propriamente dita. Em primeiro lugar apresenta-se a modelagem do grafo de cenas que permite montar estruturas hierárquicas que descrevem objetos geométricos. Na seção 5 apresentam-se as formas de representar objetos geométricos. Na seção 6 são apresentados os controladores de dispositivo. A seguir são descritas as formas de exibição de cenas em múltiplas telas e alguns comentários à cerca de funções utilitárias disponíveis na biblioteca. Por fim, são apresentadas algumas considerações finais.
·Manter a estrutura de programação usada com as bibliotecas OpenGL e GLUT e com isto aproveitar os conhecimentos já adquiridos em projetos de pesquisa e disciplinas anteriores;
·Permitir a utilização de diferentes dispositivos de realidade virtual com poucas (ou sem) modificações no código e permitir a inclusão de novos dispositivos de forma simples;
·Manter o controle do processo de rendering dos objetos gráficos com o programador;
·Não possuir um número muito grande de funções e ser de fácil assimilação;
·Ser de rápido aprendizado, possibilitando sua utilização em um curto espaço de tempo, em especial em disciplinas de graduação e pós-graduação;
·Ser portável e poder ser compilada e executada em ambiente Windows e Ser simples a ponto de permitir um rápido aprendizado do uso da ferramenta.
Ferramentas como WorldToolKit, Vega, dVise, Multigen e Performer foram descartadas pois são comerciais por isto não podem ser livremente utilizadas em nossos ambientes acadêmicos. A ferramenta Performer possui uma versão gratuita, entretanto esta só roda em ambiente Linux. As ferramentas MRObjects e MrToolkitnão tem seus fontes disponíveis e não possuem mais suporte de seus autores.Além disto, estas bibliotecas tiram o “controle” da aplicação das mãos dos usuários, impedindo-o de ter um controle mais detalhado da mesma.
A biblioteca VRJuggler[2] mostrou-se bastante interessante, suprindo a maioria das necessidades apresentadas acima. Porém, em face de seu tamanho, tempo necessário à sua aprendizagem, falta de uma documentação mais simples e também pelo fato de que o usuário fica sem o controle do processo de rendering dos objetos, esta biblioteca não foi utilizada. Neste aspecto específico, esta ferramenta usa uma filosofia que, em sua documentação, está descrita como “No main() - Don't call me, I'll call you” ou “você não me chama, eu chamarei você”.
A biblioteca Simple Virtual Enviroment Toolkit [6] testada em projetos de interação em ambientes virtuais, supre praticamente todas as nossas necessidades de programação. Porém o fato de não ser livre para distribuição, inviabilizou seu uso em nossos ambientes acadêmicos.
Foi avaliada também a biblioteca DIVERSE[5]. Esta biblioteca, entretanto, por não possuir ainda suporte à plataforma Windows e OpenGL, esta biblioteca não atendia um dos importantes requisitos previamente definidos.
As ferramentas VRUT[10] e ALICE[1]são bastante simples de ser usadas, e permitem a criação rápida de ambientes virtuais simples. Entretanto, em face de sua simplicidade e por usarem uma linguagem interpretada como Python, dificultam o desenvolvimento de aplicações mais complexas, que demandem velocidade de execução e que precisem usar a biblioteca gráfica OpenGL.
De todas as ferramentas utilizadas, a que mais se aproximou dos requisitos necessários foi a MAVERIK [4]. Usada durante todo um semestre letivo por um grupo de mais de vinte alunos, demonstrou, entretanto, que o tempo de aprendizagem necessário à sua utilização, a falta de suporte a um formato de objetos mais largamente utilizado em modeladores gráficos e a dificuldade no uso de dispositivos de realidade virtual em ambientes que não o UNIX, acabaram dificultando seu uso em nosso ambiente.
SmVR_GeometricObject
*RootObject;
void display(
void ) { glClear(
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); RootObject->Render() glutSwapBuffers(); } void InitGLUTCallbacks(void) { // definição das funções de callback da GLUT glutDisplayFunc
( display ); glutReshapeFunc
( reshape ); glutKeyboardFunc
( keyboard ); glutSpecialFunc
( arrow_keys ); } void main() { // inicialização da GLUT glutInit(
&argc, argv ); glutInitDisplayMode
(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutInitWindowPosition
(0,0); glutInitWindowSize(
700, 500 ); glutCreateWindow(
"SmallVR Test" ); RootObject
= SmVR_Init(); InitGLUTCallbacks (); glutMainLoop ( ); } |
Com o uso de hierarquia, por sua vez, pode-se estabelecer quais objetos fazem parte (são filhos) de quais objetos. Com isto, as transformações geométricas aplicadas a um nível mais alto de uma hierarquia, afetam a todos os objetos existentes em níveis inferiores da hierarquia.
Na arquitetura da SmallVR os nodos do GS são objetos geométricos representados por objetos da classe SmVR_CGeometricObject. Cada um destes objetos tem um (e somente um) pai e uma lista de zero ou mais filhos.A descrição de alguns dos métodos e atributos desta classe é apresentada a seguir.
Para a montagem de um grafo de cenas são necessários basicamente dois métodos. Um que insira um objeto como filho de outro e um que o retire desta condição. Na Figura 2 pode-se observar a descrição de uma parte da classe SmVR_CGeometricObjectonde aparece a definição dos métodos AddChild e RemoveChild.
Em
adição a estes dois métodos há outros que servem
para fornecer informações sobre um dado objeto dentro do
grafo de cena. A Tabela
1
apresenta estes métodos e sua função.
class
SmVR_CGeometricObject
{
public: // Métodos int AddChild(SmVR_CGeometricObject*o); int RemoveChild(SmVR_CGeometricObject*o); }; |
|
Tabela 1 - Métodos de consulta ao Grafo de Cena
|
|
|
|
SmVR_CGeometricObject
*GetParent();
|
|
Informa
o pai de um objeto
|
|
SmVR_CGeometricObject
*GetFirstChild()
|
|
Informa
o primeiro filho de um objeto
|
|
SmVR_CGeometricObject
*GetBrother();
|
|
Informa
o irmão objeto
|
|
SmVR_CGeometricObject
*FindChildObject(char *name);
|
|
Busca
um filho de um objeto
|
|
Para permitir esta dualidade a classe SmVR_CGeometricObject mantém duas referências à descrição da geometria dos objetos: uma é um apontador para um objeto da classe SmVR_CobjFromFile, e outra é um apontador para uma função (a ser fornecida pela aplicação) que exibe um objeto. A especificação de qual das duas formas de representação de objetos será usada é feita através dos métodos construtores da classe SmVR_CGeometricObject (Tabela 2).
Tabela 2
– Construtores da Classe CGeometryObject
|
|
SmVR_CGeometricObject (char *name,
FunctionPointer *f)
|
Construtor com função
de exibição
|
SmVR_CGeometricObject (char *name,
SmVR_CobjFromFile *obj)
|
Construtor com nome de arquivo
|
Ferramentas de desenvolvimento como SVE, MRObjects, ALICE, MAVERIK e VRUT também permitem que se carreguem objetos em vários formatos. Entretanto, estas ferramentas tiram do usuário o acesso às faces do objeto e reduzem o controle que o programador pode exercer sobre a geometria do objeto. Em geral, o programador informa o nome de um arquivo onde está o objeto e este é armazenado e um formato interno da ferramenta. A partir disto, as faces não podem mais ser facilmente acessadas. Do ponto de vista da técnica de programação este “encapsulamento” é de fato interessante. Entretanto, esta filosofia causa dificuldades quando a tarefa a ser realizada necessita acessar os vértices ou as faces que compõem o objeto. No caso da SmallVR, como a classe que trata dos objetos é fornecida pelo próprio usuário, o acesso à sua estrutura de dados do objeto também fica à seu alcance.
Para a carga de objetos no formato 3DS, pode-se usar um exemplo como o da Figura 3.
|
|
Dentro desta função devem ser inseridos somente funções de desenho de primitivas OpenGL, ficando vetado o uso de funções de transformações geométricas. Estas transformações geométricas devem ser definidas fora desta rotina através de funções específicas da biblioteca. Esta restrição deve-se ao fato de que é necessário manter consistentes as matrizes de transformações de todos os objetos, o que não é possível caso a matriz seja alterada diretamente por comandos OpenGL.
No exemplo da Figura 4 observa-se a criação de um objeto geométrico a partir de uma rotian criada pelo programador.
int
DesenhaTeste(void *p) {
|
Tabela 3
- Métodos de Transformações geométricas
|
|
void SetTranslation(tx, ty, tz)
|
Define um deslocamento para o objeto
a partir de sua posição atual
|
void SetRotation(ang,
x,y,z)
|
Define uma rotação
sobre o objeto a partir de um ângulo e do eixo ao redor de rotação
|
void SetScale(ex, ey, ez)
|
Define um fator de escala a ser
aplicado ao objeto
|
Existem ainda métodos capazes de acessar diretamente a matriz de transformações lendo-a ou modificando-a de maneira absoluta. A Tabela 4 mostra estes métodos.
Tabela 4
- Métodos de acesso absoluto à matriz de transformações
|
|
void SetTransformationMatrix (M)
|
Define uma nova matriz de transformações
para o objeto
|
void GetTransformationMatrix
(M)
|
Lê matriz de transformações
atual do objeto
|
SejamMPai, MFilho as matrizes de transformação dos objeto pai e do objeto filho, respectivamente. Assim a equação,
NovaMFilho
= MFilho * MPai-1
obtém NovaMFilho que representa a nova matriz do filho em relação ao pai.
Ao remover um objeto da lista de filhos de um outro objeto, a nova matriz do objeto-filho é obtida por:
NovaMFilho = MFilho * MPai
Após a criação do objeto controlador (da classe derivada de SmVR_CDevice), é necessário informar um objeto-sensor que será afetado por cada um dos sensores do dispositivo. Isto é feito através do método Bind. Na Figura 5 pode-se observar um trecho de código onde se cria um objeto controlador de um dispositivo e se associa um objeto da classe SmVR_CGeometricObject ao sensor físico deste dispositivo. A classe SmVR_CCyberTrackII que aparece no exemplo é derivada da classe SmVR_CDevice e implemeta seus métodos virtuais.
Após a criação desta associação entre sensor físico e objeto-sensor, pode-se definir qualquer objeto geométrico como sendo filho destes objetos-sensores. Isto fará com que este objeto geométrico acompanhe todos os movimentos do sensor.
A atualização dos dados a partir dos sensores é feita através da chamada do método UpdateAllSensors da classe SmVR_CDevice. Esta chamada não é feita de forma automática pela biblioteca a cada frame, pois, dependendo da aplicação e do tempo de resposta do dispositivo, isto pode não ser interessante. A finalização do uso do sensor é feita na destrutora da classe SmVR_CDevice.
// cria um objeto controlador do
dispositivo
SmVR_CDevice
*CT = new SmVR_CCyberTrackII();
// Inicializa o dispositivo CT->Init("COM1"); // Cria um objeto geométrico para representar o dispositivo TrackerObject
= new SmVR_CGeometricObject("TrackerObject"); RootObject->AddChild(TrackerObject); // Vincula o objeto a um dos sensores do dispositivo CT->Bind(0,
TrackerObject); // cria um objeto geométrico SmVR_CGeometricObject*o1; o1 = new SmVR_CGeometricObject ("Teste", Draw); // adiciona ‘o1’ ao objeto que representa o tracker TrackerObject->AddChild(o1); |
Para o futuro estamos avaliando a viabilidade e a adequação de usar-se, no lugar de nosso grafo de cena proprietário, uma ferramenta como OpenSG. Isto entretanto, só será feito se a modificação não trouxer maiores dificuldades na utilização da biblioteca.
[3]Bierbaum, A.; Just, C.; Hartling, P.; Meinert, K.; Baker, A. Cruz-Neira, C. "VR Juggler: A Virtual Platform for Virtual Reality Application Development". IEEE VR 2001, Proceedings, Yokohama, Japan, March 2001.
[4]Hubbold R.; Cook, J.; Keates, M., Gibson, S.; Howard, T.; Murta, A. West, A.; Pettifer, S. GNU/MAVERIK : A micro-kernel for large-scale virtual environments. Presence: Teloperators and Virtual Environments, 10:22-34, February 2001
[5]Kelso,J. Arsenault, L.; Satterfield, S.; Kriz, R. “DIVERSE: A Framework for Building Extensible and Reconfigurable Device Independent Virtual Environments”. IEEE VR 2002, Proceedings, Orlando, EUA, March 2002.
[6]Kessler, G. Drew, Doug A. Bowman, and Larry F. Hodges. "The Simple Virtual Environment Library, an Extensible Framework for Building VE Applications." PRESENCE, 9 (2), Apr. 2000. pp 187-208.
[7]Möller,
T. “A fast triangle-triangle intersection test”. Journal of Graphics Tools,
2(2):25-30, 1997. Disponível
em http://www.acm.org/jgt/papers/Moller97
.
[8]Morley,
M. “Frustum
Culling in OpenGL”. Disponível
em http://www.markmorley.com/opengl/frustumculling.html
[9]Reiners
D. OpenSG – Basic Concepts. OpenSG
2002 Fórum. Disponível em http://www.opensg.org/OpenSGPLUS/symposium/Papers2002
[10]VRUT
- Virtual Reality Utilities. Disponível
em http://www.recveb.ucsb.edu/vrut/