En un motor de física que estoy desarrollando (para aprender) usando love-2d , implementé resoluciones de colisión de esta manera:
FixedUpdate(dt) // I use fixed timestep
foreach collide c1 in allNotStaticColliders
c1.integartePhysic // i.e. apply gravitational force..
foreach collider c2 "near" c1 // "near"= I use spatial hashing
if collide(c1,c2)
resolve collision (c1,c2) // the heavy operation
collison callbacks c1
collison callbacks c2
...
Como puede ver al final de la animación gif, hay una disminución de FPS cuando todos los colisionadores están casi conectados a tierra sobre un objeto estático.
Esto se debe a que el número de resoluciones de colisión aumenta a medida que los objetos pasan más tiempo tocándose a medida que se asientan. Sin embargo, muchos de los cálculos son "inútiles" porque los objetos ya se han asentado en posiciones estables entre sí.
¿Cuál es la mejor práctica (es de esperar que no requiera un título en física) para evitar estas detecciones de colisión "inútiles"?
Editar: sugerencias DMGregory aceptadas y llegar a este resultado (aún no es óptimo)
(Rojo = estático, Azul = activo, Verde = durmiendo)
fuente
Respuestas:
Sospeché que OP ya conocía este enfoque, así que lo mencioné en un comentario como solo un punto de partida, pero intentaré desarrollarlo un poco más ...
La mayoría de los motores de física dividen los objetos dinámicos en dos grupos, " despierto " y " dormido ".
Los objetos duermen cuando se sientan en reposo y se despiertan cuando son movidos o acelerados por alguna influencia externa.
Un objeto dormido se comporta como un objeto estático en la mayoría de los aspectos: su movimiento no está integrado con el tiempo (porque está en reposo, por lo que no tiene movimiento) y el motor ignora las colisiones entre objetos que están dormidos o estáticos.
Un objeto dormido que se sienta en un piso estático no lo atraviesa, a pesar de la falta de una respuesta de colisión, porque se omite toda integración de movimiento para los objetos dormidos, incluida la gravedad.
Por lo tanto, solo se deben verificar las colisiones que involucran al menos un objeto dinámico despierto:
Esto puede reducir drásticamente la cantidad de objetos que necesitan una simulación activa, especialmente en pilas que, como se ilustra en la pregunta, tienen muchas colisiones mutuas para verificar si hay poco o ningún movimiento neto.
Dormir sólo ayuda una vez que los objetos realmente llegan a descansar, sin embargo, que podría tomar un tiempo.
Algunas cosas que puede hacer para descansar antes:
Tenga una velocidad o impulso mínimo distinto de cero y sujete a cero todo lo que caiga por debajo de él. (Esto es básicamente un épsilon, comúnmente usado para comparar carrozas)
Utilice la fricción, la amortiguación y las colisiones inelásticas para agotar la energía del sistema y ayudarlo a descansar más rápido en general.
Aumente la fricción / amortiguación / inelasticidad de forma selectiva para los objetos que se mueven lentamente para darles ese empujón final para que descansen, sin afectar el comportamiento de los cuerpos más enérgicos.
fuente