Realidade Virtual
Aula 9
Remis Balaniuk
Colisões
• Aprendemos como representar e mover objetos
tridimensionais.
• Aprendemos também a aplicar as leis da Física
aos objetos.
• Entretanto, no mundo real dois objetos não
podem ocupar o mesmo espaço, embora no
mundo virtual isso pode acontecer.
• Para isso precisamos saber como detectar e
tratar as sobreposições de volume, ou colisões,
de forma a recriar o que seria o comportamento
real.
Colisões
• O tratamento das colisões se dá em duas
etapas:
– Detecção
– Tratamento
• A detecção é um processo contínuo, que se
repete a cada passo de tempo da simulação, e
que verifica se os volumes dos objetos
tridimensionais se interceptam dadas as
posições e orientações em que se encontram.
Colisões
• O tratamento calcula a reação imposta aos
objetos para que se separem, respeitando
obviamente as propriedades físicas e
geométricas do fenômeno.
• Para um estudo aprofundado de detecção de
colisões e para obter código pronto algumas
referências úteis são:
• http://www.cs.unc.edu/~geom/V_COLLIDE/
• http://www.ams.sunysb.edu/~jklosow/quickcd/Qu
ickCD.html
• Nessa disciplina nos limitaremos a um estudo
superficial do assunto e disponibilizaremos
código implementado no Chai.
Colisões
• A detecção de colisões entre objetos
formados por grande número de vértices e
polígonos pode ser um processo muito
custoso, comprometendo inclusive a
performance em tempo real da simulação.
• A detecção de colisões representa
normalmente uma grande parte do esforço
computacional de uma simulação em 3D.
Colisões
• O tratamento de colisões exige um
cuidado especial pois muito do realismo
da simulação depende dele.
• Grandes penetrações ou reações
desproporcionais prejudicam o realismo e
a estabilidade.
Colisões
• A situação mais simples a ser considerada
numa colisão é a de um ponto que se
move na cena.
• Se a trajetória que esse ponto faz no
espaço atravessa um polígonos que
definem uma superfície ou objeto da cena,
então houve colisão.
p1
p0
Colisões
• Então o teste básico de colisão ponto-mesh
consiste em testar para cada triângulo do mesh
se o segmento p0->p1 intercepta o triângulo e
onde (ponto de colisão).
• Note que a colisão só pode ser detectada
quando já houve penetração, ou seja, uma vez
que p1 está dentro do objeto, o que fisicamente
não é muito correto.
• Note também que a detecção não pode perder
nenhum pedaço da trajetória do ponto, uma vez
que a penetração só é detectada no segmento
exato em que a superfície é atravessada.
Colisões
• O teste de intersecção entre um segmento de
reta e um triângulo é implementado no Chai no
método a seguir pertence à classe cTriangle:
inline bool computeCollision(
const cVector3d& a_rayOrigin,
const cVector3d& a_rayDir,
cGenericObject*& a_colObject,
cTriangle*& a_colTriangle,
cVector3d& a_colPoint,
double& a_colSquareDistance);
Colisões
• Um método de “força bruta” iria então
testar, triângulo a triângulo do mesh se a
colisão ocorreu.
• Esse teste bruto seria muito custoso em
objetos complexos, sendo que na enorme
maioria dos casos, no tempo e no espaço,
a colisão não esta acontecendo e esta
muito longe de acontecer.
Colisões
• Para economizar testes
inúteis pode se recorrer
aos chamados “volumes
englobantes”:
• Um volume englobante
(bounding volume) é uma
figura geométrica simples
(esfera ou paralelepipedo)
que envolve o objeto todo
ou uma parte dele.
Colisões
• Antes de começar testes
nos triângulos diretamente,
pode-se testar se existe
colisão com o volume
englobante.
• Se o teste der falso não há
o que fazer, se der
verdadeiro pode-se
aprofundar o teste.
Colisões
• Os volumes englobantes são organizados em
forma de árvore, as chamadas octtrees.
• Na raiz da árvore está o volume que engloba
todo o objeto.
• Nas folhas estão volumes que englobam cada
triângulo.
• Cada teste começa na raiz e desce em direção
às folhas, parando se algum teste falhar.
Colisões
• 3 tipos principais de volumes englobantes
são utilizados:
– Esferas
– Paralelepipedos (caixas) alinhadas aos eixos
do sistemas de coordenadas : AABB – axis
aligned bounding boxes.
– Caixas orientadas (rotacionadas
arbitrariamente): OBB – oriented bounding
boxes.
Colisões
• 2 critérios principais devem ser levados em
consideração ao escolher uma dessas formas:
– Ajuste às formas dos objetos
– Rapidez nos testes de intersecção.
• As esferas são as mais rápidas nos testes de
intersecção (um teste de distância ao centro)
mas são as piores no ajuste à forma dos
objetos.
• As caixas orientadas são as que melhor se
ajustam aos objetos mas a que exigem maior
custo no teste de intersecção.
Colisões
• As colisões entre meshes são ainda mais
complexas.
• A sequência de testes entre os meshes é a
seguinte:
– Detecção de colisão entre volumes envolventes
(raizes das duas árvores e suas subárvores)
– Detecção de colisão entre volumes envolventes das
primitivas que compõem o objeto (folhas)
– Detecção entre primitivas (triângulos) que compõem
os objetos.
Colisões no Chai
• Não é escopo desse curso aprendermos a
implementar detecção de colisões, pois esse é
um tópico complexo, envolvendo conhecimento
aprofundado de geometria.
• O Chai implementa (até o momento) a detecção
de colisões entre segmentos de reta e meshes.
• Isso se deve à prioridade dada no Chai para
implementações com interface háptica, nas
quais se toca os objetos com um ponto.
Colisões no Chai
• O Chai possui uma série de métodos associados à detecção de
colisões.
• Dois métodos foram implementados: as árvores de esferas e as AABBs.
• Para nosso uso o que importa é adicionar à um objeto (cMesh) um
detector de colisões.
• Isso se faz com os métodos:
//! Set up an AABB collision detector for this mesh and
(optionally) its children
virtual void createAABBCollisionDetector(bool
a_affectChildren, bool a_useNeighbors);
//! Set up a sphere tree collision detector for this
mesh and (optionally) its children
virtual void createSphereTreeCollisionDetector(bool
a_affectChildren, bool a_useNeighbors);
Colisões no Chai
• Esses métodos deve ser chamados quando
todos os vértices e triângulos do objeto tiverem
sido criados.
• No momento da chamada será criado o detector
de colisões (cCollisonAABB ou
cCollisionSpheres) e criada a octree de volumes
englobantes.
• Note que a árvore de volumes é construída no
sistema de coordenadas do objeto, de forma
que durante os movimentos do objeto a árvore
não precisa ser reconstruída, mas o segmento
de reta a ser testado precisa ser transformado
para o sistema de coordenadas local.
Colisões no Chai
• Para detectar a colisão entre um segmento de retas e um objeto
usamos o método da classe cGenericObjet:
// Compute collision detection using collision trees
virtual bool computeCollisionDetection(
cVector3d& a_segmentPointA,
cVector3d& a_segmentPointB,
cGenericObject*& a_colObject,
cTriangle*& a_colTriangle,
cVector3d& a_colPoint,
double& a_colSquareDistance,
const bool a_visibleObjectsOnly,
int a_proxyCall,
cGenericPointForceAlgo* force_algo=0);
• Se houver mais de uma colisão é retornada a mais próxima do início
do segmento (a_segmentPointA).
Colisões no Chai
• O mesmo método também é definido para
o mundo (cWorld) de forma que se
pedirmos a detecção de colisão entre um
segmento de reta e o mundo obteremos a
detecção encontrada mais próxima do
início do segmento.
Colisões no Chai
• Como não existe uma detecção meshmesh no Chai, implementei uma solução
“quebra-galho” nas classes dynamicObject
e dynamicWorld.
• A classe dynamicObject implementa um
objeto dinâmico rígido enquanto que a
classe dynamicWorld implementa um
mundo composto por objetos dinâmicos e
estáticos.
Colisões no Chai
• Na classe dynamicObject implementei o método abaixo
que testa a colisão entre o objeto atual e outro passado
como parâmetro:
bool dynamicObject::testCollision(cMesh
*otherOne, cVector3d& contactNormal,
cVector3d& contactPoint, double&
penetration);
• O método retorna TRUE se encontrou uma colisão e
retorna em contactPoint o ponto de contato, em
contactNormal a normal no ponto de contato e em
penetration a penetração do contato dentro do outro
objeto.
Colisões no Chai
• Na classe dynamicWorld implementei o
método:
void checkCollisions();
• Esse método verifica e trata todas as
colisões entre objetos dinâmicos e o resto
da cena virtual (outros objetos dinâmicos
ou estáticos).
Tratamento de colisões
• Como dito anteriormente, após detectar as
colisões é preciso trata-las de forma a simular o
comportamento de objetos reais em colisão.
• O objetivo do tratamento é impedir a
interpenetração e dos objetos.
• Esse tratamento pode ser simplificado,
simplesmente bloqueando (parando os objetos),
embora o mais correto seja recalcular suas
trajetórias de forma a conservar a energia
(quantidade de movimento) do sistema.
Tratamento de colisões
• Basicamente existem duas formas de
alterar a trajetória de um objeto devido a
uma colisão:
– Calcular a força (e torque) de repulsão
causada pela colisão e integrá-la ao estado
dos objetos em colisão
– Calcular diretamente uma mudança nas
velocidades linear e angular de ambos os
objetos.
Tratamento de colisões
• O método que calcula a força de repulsão
se baseia no fato que durante a colisão os
objetos armazenam energia elástica devido
à deformação e que essa energia se traduz
numa força que é aplicada aos objetos
durante a colisão.
• Esse método faz bastante sentido quando
os objetos se deformam durante a colisão,
sendo que dependendo do material de que
são feitos os objetos, a deformação pode
ser totalmente elástica, ou seja, o objeto vai
voltar ao seu formato normal após a colisão
e portanto nenhuma energia vai se perder
no processo, ou inelástica, no qual o objeto
se deforma definitivamente o que dissipa
parte da energia do sistema durante a
colisão.
Tratamento de colisões
• O método que recalcula as velocidades
diretamente, chamado de Impulso, se aplica a
objetos rígidos, para os quais a colisão é
considerada instantânea e nos quais não faria
tanto sentido calcular forças de repulsão.
• Esse método foi proposto num artigo que pode
ser encontrado no link abaixo:
• http://graphics.stanford.edu/courses/cs468-03winter/Papers/ibds.pdf
Tratamento de colisões
• Vamos focar no estudo e implementação do
Impulso, já que estamos lidando somente com
objetos rígidos.
• O cálculo do impulso leva em consideração as
seguintes variáveis:
– Impulso (p):
• O objetivo do método é calcular um vetor correspondente ao
impulso que deve ser aplicado nos objetos (p e –p) alterando
suas velocidades linear e angular.
– Coeficiente de restituição (e):
• Indica quanto da energia cinética dos objetos vai se perder
durante a colisão.
• e=1 indica que a colisão é totalmente elástica, ou seja,
nenhuma energia vai se perder.
• e=0 indica que a colisão é totalmente plastica e que os
objetos após a colisão não vão se separar.
Tratamento de colisões
• Massa do objeto i: mi
• Ji : matriz de inércia do objeto i
• vi : velocidade linear do centro de
massa do objeto i
• wi : velocidade angular do centro de
massa do objeto i
• ui : velocidade absoluta do objeto i
no ponto de contato
• ri : posição do ponto de contato
relativa ao centro de massa do
objeto i
Tratamento de colisões
• O impulso (p e –p) mais as velocidades iniciais
dos objetos (linear e angular) se combinam para
definir as novas velocidades dos objetos após a
colisão.
• Um dado importante para tratar a colisão é a
normal do ponto de colisão.
• A colisão é implementada como sendo DE um
objeto de origem PARA outro de destino.
• A normal da colisão deve corresponder à normal
do ponto de colisão na superfície do objeto de
destino (apontando para o objeto de origem).
Tratamento de colisões
• Implementação:
– No projeto9 as classes dynamicWorld e
dynamicObject foram definidas de forma a
contemplar a dinâmica dos objetos e as
colisões entre eles.
– Um objeto da classe dynamicWorld pode
conter objetos dinâmicos e estáticos e
gerenciar a interação entre eles.
Tratamento de colisões
– Na classe dynamicWorld foram implementados os métodos:
void checkMeshMeshCollision(dynamicObject *mesh1,
cMesh *mesh2);
void CollisionResponse(double e,double ma,
double mb,
cMatrix3d Ia,cMatrix3d Ib,
cVector3d ra,cVector3d rb,cVector3d n,
cVector3d vai, cVector3d vbi,
cVector3d wai, cVector3d wbi,
cVector3d& vaf, cVector3d& vbf,
cVector3d& waf, cVector3d& wbf);
– Nesse último método são passados os dados dos objetos em
colisão e se obtem as novas velocidades a serem atribuídas aos
objetos.
• vaf e vbf serão as novas velocidades lineares dos objetos 1 e 2
• waf e wbf serão as novas velocidades angulares dos objetos 1 e 2.
Tratamento de colisões
– Detalhamento do parâmetros de CollisionResponse:
double e – coeficiente de restituição (entre 0 e 1 - 1:
colisão elástica, 0: colisão plástica)
double ma – massa do objeto 1
double mb – massa do objeto 2
cMatrix3d Ia – matriz de inércia do objeto 1
cMatrix3d Ib - matriz de inércia do objeto 2
(as matrizes de inércia devem ser transformadas para o
sistema de coordenadas global – ver proximo slide)
cVector3d ra – vetor indo do centro de massa do objeto 1
ao ponto de colisão
cVector3d rb - vetor indo do centro de massa do objeto 1
ao ponto de colisão
cVector3d n – normal no ponto de colisão
cVector3d va – velocidade linear do objeto 1
cVector3d vbi - velocidade linear do objeto 2
cVector3d wai - velocidade angular do objeto 1
cVector3d wbi – velocidade angular do objeto 2
Tratamento de colisões
• Para transformar a matriz de inércia de um objeto para o
sistema de coordenadas global faça:
– IG = Rt . IL . R
– Ou seja, a matriz de inércia no sistema global é igual à matriz de
rotação do objeto transposta, multiplicada pela matriz de inércia
local, multiplicada pela matriz de rotação do objeto.
• Essa transformação foi implementada no método:
cMatrix3d dynamicObject::
getInertiaMatrix(bool transform2Global);
Download

Rvaula9 - GEOCITIES.ws