Qual é a melhor maneira de lidar com colisões simultâneas em um mecanismo de física?

13

Estou escrevendo um mecanismo de física 2D em javascript para que eu possa aprender mais sobre física em videogames. Eu o faço funcionar corretamente para colisões rígidas de corpos, exceto se algum corpo colidir com dois ou mais corpos ao mesmo tempo.

Atualmente, para cada par de corpos em colisão (A, B), modifico suas velocidades e velocidades angulares com base no impulso de colisão e as deslizo uma para a outra para que não penetrem. Porém, a detecção de colisões e os cálculos de impulso para outras colisões envolvendo A estarão errados.

Que abordagens posso explorar para que meu mecanismo funcione para mais de 3 objetos colidindo?

Cam
fonte
2
Relacionados: gamedev.stackexchange.com/questions/15836/… e gamedev.stackexchange.com/questions/26181/… e tenho certeza de que há mais, simplesmente não consigo encontrar o momento.
MichaelHouse

Respostas:

11

Eu uso a seguinte abordagem (semelhante ao algoritmo de divisão de massa de Tonge http://www.richardtonge.com/ ):

  • detectar todos os pares de colisão em sua cena / contexto. Seja (A, B) esse par. Aplique uma ideia de divisão fantasma / massa: se A estiver em contato com M corpos e B estiver em contato com N outros corpos, defina temporariamente a massa de A para m_A/Me a de B param_B/N
  • calcular contribuições da força de reação / restituição para cada par (A, B) e armazenar essas contribuições nos acumuladores de A e B
  • calcular velocidades de restituição de impulsos (como você declarou) e armazená-las da mesma maneira (como resíduos de velocidade deltaV em seus próprios acumuladores para cada par (A, B))
  • calcular deslocamentos de penalidade (novamente, acumule deslocamentos, não os aplique instantaneamente!)
    • redefinir as massas de todos os corpos previamente designados como partes em pares de colisão ( m_A = m_A * Me m_B = m_B * N)

Essa abordagem é semelhante à maneira como o algoritmo iterativo de Jacobi funciona com sistemas lineares simultâneos de equações. E não é garantido que converja, mas no meu simulador ele faz o trabalho sem problemas .. em 3D (sim, uma dimensão extra acrescenta o dobro da dificuldade!).

Advertência : corrija as posições e velocidades somente após o término da fase de detecção / manuseio de colisão! Dessa forma, você atualiza simultaneamente seus atores que colidem. Além disso, as forças de restituição devem ser levadas em consideração na próxima vez em que você integrar posições e velocidades.

EDIT: Bem, acho que você está usando o método de integração Verlet já abusado (esse se tornou um nome familiar entre os entusiastas do gamedev). Neste espectro de manipulação e integração de colisões, você pode dar uma olhada aqui .

ATUALIZAÇÃO: Algumas das informações sobre como abordar a colisão (e a auto-colisão por essa questão de fato) podem ser encontradas nestes documentos:

A abordagem que propus não é, de longe, uma contribuição original, muitos jogos a utilizam com resultados plausíveis e foi melhor empregada por Jakobsen em seu mecanismo de jogo Hitman.

De uma experiência um tanto prática, as forças de penalidade (semelhantes às molas lineares ou exponenciais que obtêm sua contribuição da distância de penetração) não resolvem adequadamente as penetrações quando outras forças dos corpos que colidem conseguem ser maiores que elas. Foi por isso que escolhi combinar três abordagens (quase redundantes): forças de reação newtonianas (você empurra a parede, a parede empurra para trás), velocidades derivadas de impulso (bolas de sinuca colidindo) e um "natural" afasta geometricamente os corpos uns dos outros "solução. Juntos, eles parecem fornecer tudo: livrar-se da maioriaartefatos de interpenetração feios, corpos em colisão tendem a interagir um com o outro a longo prazo (devido a velocidades e forças de restituição - pelo menos as forças que tendem a arrastar os corpos em um cenário de colisão são canceladas e os corpos se afastam) . Por fim, para entender melhor esses conceitos simples, mas comuns, sugiro analisar esses slides .

Meu epíteto de "método abusado", que descreve as etapas de integração do Verlet, visa uma crença na cultura popular de que este é o Santo Graal dos métodos de integração. É apenas marginalmente melhor do que seu primo simplético de Euler (também chamado por alguns Euler semi-implícito). Existem métodos de integração muito mais complicados (e todos ostentam o nome implícito). Poderosos mecanismos de jogo os utilizam, mas os desenvolvedores independentes não têm tempo para experimentar com eles, pois o Verlet, quando ajustado a um cenário específico, realmente faz maravilhas. Além disso, não há absolutamente nenhum método de integração que possa lidar com restrições rígidas sem envolver um pouco de trapaça (não é possível encontrar o link, mas o documento ao qual estou me referindo deve ser chamado "X.Provot -" Restrições à Deformação em uma Massa modelo para descrever comportamento rígido de tecido "

teodron
fonte
Obrigado (+1)! O que são 'velocidade de restituição' e 'deslocamentos de penalidade'? Além disso, por que você diz que a integração de verlet é 'abusada'? Você acha que esse é um método ruim de usar?
Cam
As velocidades de restituição são exatamente aquelas que você obtém dos impulsos, a única diferença é que eu as computo como resíduos (ou seja, armazeno a diferença entre a velocidade baseada em impulso e a velocidade atual, mantendo a velocidade atual intacta para cálculos posteriores). Os deslocamentos de penalidade são vetores com um comprimento determinado pelo quanto dois objetos se interpenetram e é o vetor de comprimento mínimo que pode converter um objeto completamente fora do outro. Normalmente, adiciono esse deslocamento a cada objeto, dividindo o comprimento por 2).
Teodron
1
Resposta brilhante! Eu tenho outra questão. Digamos que eu acumule as velocidades de restituição, elas não serão um número muito realista? Se eu tratar cada colisão com o objeto A separadamente e somar os efeitos em cada objeto, A não terá seu impulso espalhado entre os objetos? Em vez disso impulso total será aplicado a cada um o que parece errado para mim intuitivamente
Cam
Essa é uma pergunta muito boa. De um ponto de vista, parece plausível que os impulsos contribuam de maneira aditiva para a velocidade resultante. Aqui está o meu raciocínio (talvez com defeito!): Imagine três bolas de sinuca / sinuca colidindo. Um deles deve receber contribuições dos outros dois dessa maneira aditiva. Inicialmente, pensei em pesar essas contribuições e calcular uma média ponderada para a velocidade final, mas como queria resultados rápidos, pulei essa ideia. Em suma, a bola em colisão deve receber contribuições de velocidade das duas restantes. Talvez um livro de texto do ensino médio possa ajudar.
Teodron
3
Talvez eu não entenda o que você explicou, porque o exemplo a seguir ainda me preocupa: considere um retângulo horizontalmente longo caindo direto para baixo e suponha que o piso seja irregular (composto por vários triângulos lado a lado). Se houver n triângulos, usando seu método acumulativo, o retângulo retornará n vezes a velocidade que deveria! Como essa situação pode ser resolvida?
Cam
1

Sugiro que, em vez de mudar as velocidades, você altere as forças que atuam sobre um objeto. Não os "cutuque", faça-o sem problemas e utilizando o código já existente. Ao fazer isso, os corpos não mudam imediatamente (e rapidamente, suponho) suas velocidades.

Confira Box2DJS para um exemplo: http://box2d-js.sourceforge.net/index2.html .

jcora
fonte
-1

Resolvi analiticamente a equação de impulso para grupos de corpos em colisão. O único problema que enfrentei foi a falta de variáveis ​​para encontrar força relativa de interação entre os contatos de um grupo, que eu preenchi com a profundidade da interseção dos corpos.

A solução para contatos de grupo não é muito mais difícil que o contato único. Infelizmente, perdi um trabalho com cálculos, impossibilitado de compartilhá-lo aqui.

Edit: Provavelmente eu vim com algo assim /physics/296767/multiple-colliding-balls

George Vinokhodov
fonte