Simulação do navegador de física



Neste artigo, quero descrever soluções existentes para criar aplicativos com simulações de física, comparar seu desempenho e as ferramentas fornecidas.

1. Introdução


Os seguintes mecanismos serão considerados no artigo:

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

O objetivo principal era escolher o mecanismo mais produtivo, conveniente e leve para o desenvolvimento de jogos e aplicativos usando simulações de física.

Ammo.js


É uma porta do mecanismo de física Bullet em javascript, usando o compilador Emscripten e, de acordo com os desenvolvedores, tem funcionalidade quase idêntica. A funcionalidade do Ammo.js é realmente extensa. Para trabalhar com isso, você precisa de uma biblioteca separada para visualização. O mais usado é o Three.js. Além disso, cada ciclo de redesenho precisará sincronizar manualmente a posição e a rotação de cada objeto na cena com seu modelo físico, o mecanismo não fará isso automaticamente.

Quanto ao desempenho, não é muito alto, mas não haverá reduções visíveis de fps na maioria dos projetos.

Às vezes, a API pode ser bastante confusa e a documentação realmente não ajuda.
Em geral, uma ferramenta muito boa que continua a se desenvolver e ser desenvolvida.

Cannon.js


O Cannon.js é um mecanismo de física leve de código aberto. Ao contrário do anterior, ele foi originalmente escrito em javascript e permite que você use todos os seus recursos e otimizações. De fato, é difícil dizer se isso é um sinal de mais ou menos, pois o código compilado pode ser muito mais eficiente do que escrito do zero. No entanto, o cannon.js é considerado mais compacto, mais produtivo e também mais fácil de entender em comparação com o ammo.js, mas não possui muitas funções. Na prática, seu desempenho geralmente é aproximadamente o mesmo.

O processo de trabalho com o mecanismo é bastante simples:

//   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; })(); 

Uma biblioteca gráfica de terceiros também é necessária para o trabalho, e cada ciclo de renderização precisará mover manualmente o objeto correspondente na cena para o local do objeto físico.

 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; 

No momento, o mecanismo praticamente não está se desenvolvendo, a última atividade no repositório de projetos há mais de dois anos, e naquele momento o mecanismo estava apenas começando a se desenvolver, portanto, em alguns lugares, pode não ser possível.

Oimo.js


Oimo.js é uma versão do mecanismo OimoPhysics reescrita em javascript puro. Comparado a outras soluções, possui desempenho e precisão muito bons, mas suporta apenas geometria primitiva (cubos e esferas). Ele está incluído no Babylon.js, uma estrutura para renderização de gráficos 2D e 3D, portanto, nenhuma biblioteca adicional é necessária.

 //   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() ); 

Uma grande desvantagem do mecanismo não é a documentação de alta qualidade, mas os desenvolvedores continuam trabalhando nele.

No momento, o motor continua a se desenvolver.

box2dweb


box2dweb é a porta javascript box2d. Como o nome indica, é especializado em simular física 2D. Apesar disso, o box2dweb é uma ferramenta bastante poderosa que não fica atrás de suas contrapartes tridimensionais. Por exemplo, o mecanismo inclui sistemas extremamente convenientes para detectar colisões e simular conexões (restrição).

Quanto ao desempenho, você precisa realmente tentar escrever um código não ideal para que apareçam os rebaixamentos de fps.

Das vantagens, também vale mencionar a simplicidade da API e a documentação conveniente.

Unity3d


O Unity3D é um popular mecanismo de jogo multiplataforma. Inclui um editor simples de arrastar e soltar e um extenso kit de ferramentas para criar conteúdo 3D A versão mais recente do mecanismo para escrever a lógica do jogo suporta C #.

O Unity possui uma simulação física incorporada, pois isso usa o mecanismo PhysX incorporado da NVIDIA. O PhysX fornece ampla funcionalidade para simular a física de sólidos, líquidos e tecidos e possui um desempenho muito bom, embora muitas vantagens sejam canceladas ao trabalhar em aceleradores gráficos diferentes da NVIDIA. Um fato extremamente agradável é que, desde 3 de dezembro de 2018, o código-fonte do mecanismo está disponível sob a licença aberta BSD-3; no entanto, o mecanismo é muito complexo para tentar reescrevê-lo ou entender seu dispositivo, portanto, a documentação ajudará aqui melhor.

O Unity acabou nesta lista, pois é possível criar um projeto no WebGL. Para fazer isso, basta selecionar o item apropriado nas configurações de compilação.



No entanto, a versão WebGL do Unity, devido às especificidades de sua arquitetura (traduzindo código de C # para C ++ e depois para JavaScript), apresenta vários problemas de desempenho, consumo de memória e capacidade de trabalho em dispositivos móveis, e não parece que os desenvolvedores farão isso algo para fazer em breve. Portanto, essa opção não é popular e não a considerarei em detalhes.

Comparação de desempenho


Vamos comparar o desempenho dos mecanismos pela maneira como eles lidam com o processamento de colisões de um grande número de objetos. O navegador usado é o Firefox 64.0.2 x64.
Enginefps ao processar 100 objetosfps ao processar 500 objetosfps ao processar 1000 objetos
ammo.js40-5025-2715-25
cannon.js30-4020-2515-20
oimo.js45-5535-4035-40

De acordo com os resultados do teste, o Oimo.js mostra o melhor desempenho.

Certamente, esses resultados não fornecem uma avaliação adequada da produtividade, pois dependem de muitos fatores de terceiros, mas um estudo completo exigiria muito mais tempo, e eu não estabeleci esse objetivo. Além disso, é perceptível que o desempenho de todos os mecanismos comparados é bastante pequeno, portanto essas soluções não são adequadas para escrever longe de todos os jogos, mas são adequadas para criar pequenas demos.

Conclusão


Em geral, a escolha de um mecanismo específico depende da tarefa. Se você precisar de um mecanismo fácil de entender e aprender, o Cannon.js ou o Oimo.js. é adequado. Se mais funcionalidade for necessária, é melhor usar o Ammo.js. Em certas situações, se um ótimo desempenho não for necessário, você pode tentar usar o Unity.

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


All Articles