J'ai écrit un physique simple modeler qui me permet de faire rebondir les balles autour de l'écran. Vous pouvez cliquer et faire glisser pour lancer une balle, ou vous pouvez générer des boules de centaines et de les regarder interagir avec d'autres personnes.
[Lien vers la plus grande version]
Il a été un peu de fun au programme de travail et je veux aller plus loin, si je peux. Je sais qu'ils disent que la pré-maturité d'optimisation est la racine de tous les maux, mais je suis en train de frapper les performances réelles barrières et je veux savoir si quelqu'un qui est expérimenté dans le jeu/le développement de simulateurs peuvent m'aider.
Problème:
Pour l'instant, mon programme s'étouffe si vous ajoutez trop de ballons (il n'arrive pas à gérer plus de 800 sur ma machine). Si vous le faites, la simulation n'est pas réaliste et toutes les boules se chevauchent les uns les autres sur le fond.
Le problème est dans la détection de collision. Dans la plupart des cas naïf, la détection de collision est un O(N^2) problème. Chaque boule vérifie chaque autre balle. Cela devient de la mauvaise performance, assez rapidement (même après 100 balles que vous allez faire 10k les tests de collision par itération de la boucle).
Si vous regardez ici, vous pouvez voir une capture d'écran de l'endroit où j'ai ajouté plusieurs centaines de balles. Le simulateur ne peut pas tenir en place et ils commencent à se chevaucher les uns les autres.
[Lien vers la plus grande version]
Actuellement, j'ai de détecter les collisions par la recherche de chevauchement des balles. Si je trouve deux balles qui se chevauchent, je me sépare d'eux par leur distance minimale de la traduction (DMT), ou de les pousser dehors. J'utilise ensuite un physique simple équation d'ajuster leur impulsion des vecteurs et ils s'en vont dans des directions différentes après la collision.
Il fonctionne très bien, sauf si il y a trop de balles la distance minimale de la traduction devient perceptible. Ils commencent à se chevauchent par de grandes quantités et constamment bousculer les autres sur le fond. Il y a pire plus je l'augmentation de la "gravité". La pression sur eux est augmenté et le montant qu'ils sont compressés/se chevauchent les uns les autres les augmentations.
Encore une fois, je n'ai pas de questions jusqu'à ce que j'ai touché un nombre considérable de N le nombre de boules.
Optimisation De La Méthode:
La Détection De Collision -
Balayage et taillez - (aka. De tri et de Balayage)
J'utilise un tri d'insertion sur mes couilles à chaque itération de la boucle le long de leur axe x. En raison de la nature de l'Insertion de Sorte que je peux exploiter la cohérence temporelle de mon simulateur. Un cadre à l'autre, les boules de postes de changer légèrement de sorte que le tri n'a pas beaucoup de travail à faire. Cela apporte Linéaire amorti Sortes d'exécution de O(N) ou linéaire plutôt que la moyenne des temps d'exécution de O(N^2).
Puisque les boules sont triés, je fais quelques vérifications préalables à ma deuxième boucle avant de vérifier les collisions. Maintenant je n'ai qu'à vérifier les boules à proximité les uns des autres (parce qu'ils sont classés le long de l'axe des x), et j'sortir de la seconde boucle à chaque fois que je case une balle contre un autre balle dont xmin est plus grand que le xmax de l'actuel ballon. Donc il saute des milliers de contrôles.
Quand je l'ai fait, cela a été une énorme amélioration de la vitesse. Cependant, je voudrais tout de même être en mesure de traiter plus de 600 à 800 balles. J'ai lu sur les Moteurs de Physique que de la poignée facilement la détection de collision entre 10k objets en même temps, donc j'aime à penser que je pourrais atteindre 1-2k avec un peu de travail.
Après l'exécution d'un profiler , il est apparu que la Détection de Collision est de manger d'environ 55% de mon temps alors que le rendu était en train de manger d'environ 45%. Donc, ce sont mes deux plus cher.
Question:
Pouvez-vous penser à une meilleure algorithmes ou des techniques qui permettraient de mon simulateur d'être capable de gérer plus de balles?
Code:
Ensemble Du Projet:
svn checkout http://simucal-projects.googlecode.com/svn/ballbounce/trunk/
ou, cliquez ici pour parcourir les fichiers manuellement dans votre navigateur.
Sections d'Intérêt:
- Pastebin: checkCollisions() - w/ Balayage et de Pruneau
- Pastebin: resolveCollision() - Cher vrai contrôle des collisions et de la résolution si toujours pas retirée par Balayage et de Pruneau.
- Pastebin: render() - Rendu seul, mange environ 45% de mon temps.