SmallVR - Virtual Reality Toolkit
Prof. Márcio Sarroglia Pinho

Detecção de Colisão


1. Colisão entre Objetos Geométricos

A colisão entre objetos geométricos pode ser feita de várias formas. A maneira mais "ingênua" testa todos os polígonos que formam um objeto contra todos os polígos de outro.
Esta técnica funciona bem para objetos simples com poucas faces, mas acaba tornando o processo de detecção muito lento se os objetos tiverem muitas faces.
Se você necessitar testar colisão entre triângulos, por exemplo, um bom algoritmo é o "A Fast Triangle-Triangle Intersection Test", de Tomas Möller (Journal of Graphics Tools, 2(2), 1997), também disponível disponível em versão eletrônica em http://www.acm.org/jgt/papers/Moller97.

Existem por outro lado, algoritmos muito mais eficientes para a detecção de colisão que entretanto acabam por exigir que o programador duplique sua estutura de dados dentro da rotinas da biblioteca que implementa os métodos. Exemplos destas bibliotecas podem ser encontrados em:

 
Gamasutra  http://www.gamasutra.com/features/20000330/bobic_01.htm 
QuickCD http://www.ams.sunysb.edu/~jklosow/quickcd/ 
FreeSOLID http://www.win.tue.nl/~gino/solid/ 
OpCode http://www.codercorner.com/Opcode.htm
RAPID
http://www.cs.unc.edu/~geom/collide/index.shtml
Outras http://www.ams.sunysb.edu/~jklosow/quickcd/QCD_resources.html
http://www.stanford.edu/~jgao/collision-detection.html
http://www.cs.unc.edu/~geom/collide/index.shtml


2. Teste de Colisão na SmallVR com a RAPID

Na SmallVR utilizamos a  biblioteca RAPID para os testes de colisão. Para acionar o uso da RAPID em objetos Wavefront é necessário apenas incluir o parâmetro USE_RAPID no construtor do SmVR_COBJFromFile, como no exemplo abaixo:
  SmVR_CObjFromFile *ObjectFromFile = new SmVR_COBJLoader(USE_RAPID);
  ObjectFromFile->Load("exemplo.obj");
Para a detecção de colisão utiliza-se o seguinte método Collided, conforme o exemplo abaixo:
  // Cria um objeto
  SmVR_CGeometricObject *Objeto1 = new SmVR_CGeometricObject("Objeto1",ObjectFromFile);
  // Cria outro objeto
  SmVR_CGeometricObject *Objeto2 = new SmVR_CGeometricObject("Objeto2",ObjectFromFile);
  // Coloca os dois objetos no grafo de cena da SmallVR
  RootObject->AddChild(Objeto1);
  RootObject->AddChild(Objeto2);
  // Testa colisão entre os objetos
  Objeto1->Collided(Objeto2);

Atenção: A RAPID não permite que sejam feitas escalas nos objetos usados por ela. Se for desejável utilizar objetos com escalas diferentes dos originais, sugere-se que estes objetos tenham sua escala alterada em algum software de modelagem 3D, como o AccuTrans 3D, e então utilizados no ambiente.


Exercício 1:   Testando Colisão entre objetos
   
Copie o arquivo Colisao.cpp,
grave-o no sub-diretório TestFiles. Copie ainda o arquivo Objetos.zip e descompacte-o no subdiretório TestFiles/Objetos3D.

Abra o prpjeto da SmallVR e carregue adicione o arquivo Colisao.cpp e compile.
Modifique o programa  de maneira a testar se há ou não colisão entre o sofá e o piso. Como sugestão, coloque teclas para mover o sofá e imprima na tela se há um colisão ou não.