Simulation du navigateur physique



Dans cet article, je veux décrire les solutions existantes pour créer des applications avec des simulations physiques, comparer leurs performances et les outils fournis.

Présentation


Les moteurs suivants seront pris en compte dans l'article:

Ammo.js
Cannon.js
Oimo.js
box2dweb
Unity3D WebGL

L'objectif principal était de choisir le moteur le plus productif, le plus pratique et le plus léger pour développer des jeux et des applications à l'aide de simulations physiques.

Ammo.js


Il s'agit d'un portage du moteur physique Bullet en javascript utilisant le compilateur Emscripten et, selon les développeurs, a des fonctionnalités presque identiques. La fonctionnalité d'Ammo.js est vraiment étendue. Pour l'utiliser, vous avez besoin d'une bibliothèque distincte pour la visualisation. Le plus couramment utilisé est Three.js. De plus, chaque cycle de redessin devra synchroniser manuellement la position et la rotation de chaque objet sur la scène avec son modèle physique, le moteur ne le fait pas automatiquement.

Quant aux performances, elles ne sont pas trop élevées, mais il n'y aura pas de baisses fps notables dans la plupart des projets.

L'API peut parfois être assez déroutante et la documentation n'aide pas vraiment.
En général, un très bon outil qui continue de se développer et de se développer.

Cannon.js


Cannon.js est un moteur de physique léger open source. Contrairement au précédent, il a été écrit à l'origine en javascript et vous permet d'utiliser toutes ses fonctionnalités et optimisations. En fait, il est difficile de dire s'il s'agit d'un plus ou d'un moins, car le code compilé peut être beaucoup plus efficace qu'il n'est écrit à partir de zéro. Néanmoins, cannon.js est considéré comme plus compact, plus productif et aussi plus facile à comprendre que ammo.js, mais il n'a pas autant de fonctions. En pratique, leurs performances sont souvent à peu près les mêmes.

Le processus de travail avec le moteur est assez simple:

//   var world = new CANNON.World(); world.gravity.set(0, 0, -9.82); //   (   ) //        var radius = 1; var sphereBody = new CANNON.Body({ mass: 5, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Sphere(radius) }); world.addBody(sphereBody); var fixedTimeStep = 1.0 / 60.0; var maxSubSteps = 3; //    var lastTime; (function simloop(time){ requestAnimationFrame(simloop); if(lastTime !== undefined){ var dt = (time - lastTime) / 1000; world.step(fixedTimeStep, dt, maxSubSteps); } lastTime = time; })(); 

Une bibliothèque graphique tierce est également requise pour le travail, et chaque cycle de rendu devra déplacer manuellement l'objet correspondant sur la scène à l'emplacement de l'objet physique.

 mesh.position.x = body.position.x; mesh.position.y = body.position.y; mesh.position.z = body.position.z; mesh.quaternion.x = body.quaternion.x; mesh.quaternion.y = body.quaternion.y; mesh.quaternion.z = body.quaternion.z; mesh.quaternion.w = body.quaternion.w; 

Pour le moment, le moteur ne se développe pratiquement pas, la dernière activité dans le référentiel du projet il y a plus de 2 ans, et à ce moment-là, le moteur commençait à peine à se développer, donc à certains endroits, il peut ne pas fonctionner.

Oimo.js


Oimo.js est une version du moteur OimoPhysics réécrite en pur javascript. Comparé à d'autres solutions, il a de très bonnes performances et précision, mais il ne prend en charge que la géométrie primitive (cubes et sphères). Il est inclus dans Babylon.js, un cadre pour le rendu de graphiques 2D et 3D, donc aucune bibliothèque supplémentaire n'est requise.

 //   world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2, worldscale: 1, random: true, info: false, gravity: [0,-9.8,0] }); //    var body = world.add({ type:'sphere', size:[1,1,1], pos:[0,0,0], rot:[0,0,90], move:true, density: 1, friction: 0.2, restitution: 0.2, belongsTo: 1, collidesWith: 0xffffffff; }); var body = world.add({ type:'jointHinge', body1: "b1", body2: "b1", }); world.step(); //           myMesh.position.copy( body.getPosition() ); myMesh.quaternion.copy( body.getQuaternion() ); 

Un gros inconvénient du moteur n'est pas une documentation de très haute qualité, mais les développeurs continuent de travailler dessus.

Pour le moment, le moteur continue de se développer.

box2dweb


box2dweb est le port javascript box2d. Comme son nom l'indique, il est spécialisé dans la simulation de la physique 2D. Malgré cela, box2dweb est un outil assez puissant qui ne traîne pas derrière ses homologues en trois dimensions. Par exemple, le moteur comprend des systèmes extrêmement pratiques pour détecter les collisions et simuler les connexions (contrainte).

En ce qui concerne les performances, vous devez vraiment essayer d'écrire du code non optimal pour que les tirages fps apparaissent.

Parmi les avantages, il convient également de mentionner la simplicité de l'API et la documentation pratique.

Unity3d


Unity3D est un moteur de jeu multiplateforme populaire. Comprend un simple éditeur de glisser-déposer pratique et une boîte à outils complète pour créer du contenu 3D. La dernière version du moteur d'écriture de la logique de jeu prend en charge C #.

Unity a une simulation physique intégrée, pour cela utilise le moteur PhysX intégré de NVIDIA. PhysX fournit des fonctionnalités étendues pour simuler la physique des solides, des liquides et des tissus, et a de très bonnes performances, bien que de nombreux avantages soient annulés lorsque vous travaillez sur des accélérateurs graphiques autres que NVIDIA. Un fait extrêmement agréable est que depuis le 3 décembre 2018, le code source du moteur est disponible sous la licence ouverte BSD-3, mais le moteur est trop complexe pour essayer de le réécrire par vous-même ou pour comprendre son appareil, donc la documentation vous aidera mieux ici.

Unity s'est retrouvé sur cette liste, car il est possible d'y construire un projet sous WebGL. Pour ce faire, sélectionnez simplement l'élément approprié dans les paramètres de génération.



Néanmoins, la version WebGL d'Unity, en raison des spécificités de son architecture (traduction du code de C # en C ++ et plus loin en JavaScript), a un certain nombre de problèmes de performances, de consommation de mémoire et de capacité de travail sur les appareils mobiles, et il ne semble pas que les développeurs vont le faire quelque chose à faire bientôt. Par conséquent, cette option n'est pas populaire et je ne l'examinerai pas en détail.

Comparaison des performances


Comparons les performances des moteurs par la façon dont ils traitent le traitement des collisions d'un grand nombre d'objets. Le navigateur utilisé est Firefox 64.0.2 x64.
Moteurfps lors du traitement de 100 objetsfps lors du traitement de 500 objetsfps lors du traitement de 1000 objets
ammo.js40-5025-2715-25
cannon.js30-4020-2515-20
oimo.js45-5535-4035-40

Selon les résultats des tests, Oimo.js affiche les meilleures performances.

Bien sûr, ces résultats ne fournissent pas une évaluation adéquate de la productivité, car ils dépendent de nombreux facteurs tiers, mais une étude à part entière nécessiterait beaucoup plus de temps, et je ne me suis pas fixé un tel objectif. De plus, il est à noter que les performances de tous les moteurs comparés sont plutôt faibles, donc ces solutions ne conviennent pas pour écrire loin de chaque jeu, mais sont bien adaptées pour créer de petites démos.

Conclusion


En général, le choix d'un moteur particulier dépend de la tâche. Si vous avez besoin d'un moteur facile à comprendre et à apprendre, Cannon.js ou Oimo.js.est bien adapté. Si plus de fonctionnalités sont nécessaires, il est préférable d'utiliser Ammo.js. Dans certaines situations, si de grandes performances ne sont pas requises, vous pouvez essayer d'utiliser Unity.

Source: https://habr.com/ru/post/fr436192/


All Articles