Dans un moteur physique que je développe (pour apprendre) en utilisant love-2d , j'ai implémenté des résolutions de collision de cette manière:
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
...
Comme vous pouvez le voir à la fin de l'animation gif, il y a une décroissance FPS lorsque tous les collisionneurs sont presque mis à la terre sur un objet statique.
En effet, le nombre de résolutions de collision augmente à mesure que les objets passent plus de temps à se toucher lorsqu'ils s'installent. Cependant, de nombreux calculs sont "inutiles" car les objets se sont déjà installés dans des positions stables les uns contre les autres.
Quelle est la meilleure pratique (si tout va bien n'exige pas un diplôme de physique) pour éviter ces détections de collision "inutiles"?
Edit: astuces DMGregory acceptées et arriver à ce résultat (pas encore optimal)
(Rouge = statique, Bleu = actif, Vert = endormi)
la source
Réponses:
Je soupçonnais que OP connaissait déjà cette approche, je l'ai donc mentionnée dans un commentaire comme point de départ, mais je vais essayer de l'étoffer un peu plus ...
La plupart des moteurs physiques divisent les objets dynamiques en deux groupes, « éveillé » et « endormi ».
Les objets dorment lorsqu'ils sont assis au repos et se réveillent lorsqu'ils sont déplacés ou accélérés par une influence extérieure.
Un objet endormi se comporte comme un objet statique à bien des égards - son mouvement n'est pas intégré dans le temps (car il est au repos, il n'a donc aucun mouvement) et le moteur ignore les collisions entre des objets endormis ou statiques.
Un objet endormi assis sur un sol statique ne tombe pas à travers lui, malgré l'absence de réponse à la collision, car toute intégration de mouvement est ignorée pour les objets endormis, y compris la gravité.
Ainsi, seules les collisions impliquant au moins un objet dynamique éveillé doivent être vérifiées:
Cela peut réduire considérablement le nombre d'objets qui nécessitent une simulation active, en particulier dans les piles qui, comme illustré dans la question, ont beaucoup de collisions mutuelles pour vérifier peu ou pas de mouvement net.
Dormir n'aide que lorsque les objets atteignent effectivement le repos, ce qui peut prendre un certain temps.
Certaines choses que vous pouvez faire pour vous reposer plus tôt:
Ayez une vitesse ou un élan minimum non nul et fixez à zéro tout ce qui tombe en dessous. (Il s'agit essentiellement d'un epsilon, couramment utilisé pour comparer les flotteurs)
Utilisez la friction, l'amortissement et les collisions inélastiques pour retirer l'énergie du système et l'aider à se reposer plus rapidement dans l'ensemble.
Augmentez la friction / l'amortissement / l'inélasticité de manière sélective pour les objets se déplaçant lentement pour leur donner ce dernier coup de pouce pour se reposer, sans affecter le comportement des corps plus énergétiques.
la source