Não. A detecção de colisão nem sempre é O (N ^ 2).
Por exemplo, digamos que temos um espaço de 100x100 com objetos com tamanho 10x10. Poderíamos dividir esse espaço em células de 10x10 com uma grade.
Cada objeto pode estar em até 4 células da grade (pode caber em um bloco ou estar "entre" células). Poderíamos manter uma lista de objetos em cada célula.
Só precisamos verificar colisões nessas células. Se houver um número máximo de objetos por célula da grade (digamos, nunca há mais de 4 objetos no mesmo bloco), a detecção de colisão para cada objeto é O (1) e a detecção de colisão para todos os objetos é O (N).
Essa não é a única maneira de evitar a complexidade de O (N ^ 2). Existem outros métodos, mais adequados para outros casos de uso - geralmente usando estruturas de dados baseadas em árvore.
O algoritmo que descrevi é um tipo de particionamento espacial , mas existem outros algoritmos de particionamento espacial. Consulte Tipos de estruturas de dados de particionamento de espaço para obter mais algoritmos que evitam a complexidade temporal O (N ^ 2).
O Box2D e o Bullet suportam mecanismos para reduzir o número de pares verificados.
No manual , seção 4.15:
O processamento de colisão em uma etapa da física pode ser dividido em fase estreita e fase larga. Na fase estreita, calculamos pontos de contato entre pares de formas. Imagine que temos N formas. Usando força bruta, precisaríamos executar a fase estreita para pares N * N / 2.
A classe b2BroadPhase reduz essa carga usando uma árvore dinâmica para gerenciamento de pares. Isso reduz bastante o número de chamadas em fase estreita.
Normalmente você não interage diretamente com a fase ampla. Em vez disso, o Box2D cria e gerencia uma fase ampla internamente. Além disso, o b2BroadPhase foi projetado com o loop de simulação do Box2D em mente, portanto, provavelmente não é adequado para outros casos de uso.
Do Bullet Wiki :
Existem vários tipos de algoritmos de fase larga que aprimoram o ingênuo O (n ^ 2) que apenas retorna a lista completa de pares. Essas larguras otimizadas às vezes introduzem ainda mais pares não colidentes, mas isso é compensado pelo tempo de execução geralmente melhorado. Eles têm características de desempenho diferentes e nenhum supera os outros em todas as situações.
Árvore AABB dinâmica
Isso é implementado pela btDbvtBroadphase no Bullet.
Como o nome sugere, esta é uma árvore AABB dinâmica . Uma característica útil dessa fase larga é que a estrutura se adapta dinamicamente às dimensões do mundo e seu conteúdo. É muito bem otimizado e é uma banda larga de uso geral muito boa. Ele lida com mundos dinâmicos, onde muitos objetos estão em movimento, e a adição e remoção de objetos é mais rápida que o SAP.
Varredura e remoção (SAP)
No Bullet, este é o intervalo de classes do AxisSweep. Essa também é uma boa fase geral de uso geral, com a limitação de exigir um tamanho fixo do mundo, conhecido antecipadamente. Essa fase larga tem o melhor desempenho para mundos dinâmicos típicos, onde a maioria dos objetos tem pouco ou nenhum movimento. O btAxisSweep3 e o bt32AxisSweep3 quantizam os pontos inicial e final de cada eixo como números inteiros, em vez de números de ponto flutuante, para melhorar o desempenho.
O link a seguir é uma introdução geral à fase larga e também uma descrição do algoritmo Sweep and Prune (embora o chame de "Sort and Sweep"):
http://www.ziggyware.com/readarticle.php?article_id=128
Além disso, dê uma olhada na página da wikipedia:
http://en.wikipedia.org/wiki/Sweep_and_prune