Um mecanismo de física é um simulador usado para criar um ambiente virtual que incorpora leis de um mundo físico. Esse ambiente virtual pode incluir objetos com forças associadas aplicadas a eles (como gravidade) além de interações entre objetos, como colisões. Um mecanismo de física simula física newtoniana em um ambiente simulado e gerencia essas forças e interações.
Uma das mais propaladas aplicações de um mecanismo de física é no segmento de mercado de entretenimento e jogos (ver a Figura 1), no qual o mecanismo de física oferece uma simulação em tempo real do ambiente de jogo (incluindo o jogador e outros objetos que possam estar presentes). Antes de seu uso em jogos, mecanismos de física tinham alguns usos na área científica, de simulações em larga escala de corpos celestes a simulações climáticas, e até simulações em pequena escala para visualizar o comportamento de nanopartículas e suas forças associadas.
Figura 1. Um mecanismo de física no contexto de um aplicativo de jogo
Uma diferença importante entre essas aplicações é que, embora mecanismos de física focados em jogos se concentrem em aproximações em tempo real, a variedade científica se concentra mais em cálculos precisos para maior precisão. Mecanismos de física científicos podem contar com a capacidade de processamento de supercomputadores, enquanto os de jogos podem ser executados em plataformas com recursos consideravelmente mais restritos (como dispositivos de jogos portáteis e celulares). Mecanismos de física de jogos reduzem a escala da simulação ao evitar coisas como movimento browniano, o que, por sua vez, minimiza as complexidades de processamento da simulação. A faixa de conceitos matemáticos e físicos que integram esses mecanismos está fora do escopo deste artigo, porém, links para mais informações podem ser encontrados em Recursos.
Existem vários tipos de física de jogos, dependendo do requisito, mas todos são variações do mesmo tema. Em jogos, podemos encontrar física de boneca de trapo (que simula o comportamento de um sistema articulado complexo) e sistemas de partículas (que modela o comportamento de muitas partículas pequenas e grandes em resposta a eventos como uma explosão). Um dos primeiros mecanismos de física de software foi o computador ENIAC, que era usado para simular peças de artilharia com variáveis de massa, ângulo, propulsão e vento. A Wikipédia tem uma introdução interessante para esse aplicativo — consulte Recursos para o link.
Um dos principais usos de mecanismos de física (em especial a variedade em tempo real e de baixa precisão) é no desenvolvimento de tempos de execução de jogos. Com base na popularidade dessas estruturas de software, há muitas opções de software livre dentre as quais escolher. Este artigo explora alguns dos mecanismos de física de software livre disponíveis e ilustra seu uso em aplicativos simples.
Box2D é um mecanismo de física simples com um uso amplo. Foi originalmente projetado por Erin Catto como um mecanismo de demonstração para uma apresentação sobre física dada na Game Developers Conference em 2006. Box2D foi originalmente chamado de Box2D Lite, mas o mecanismo foi expandido para aprimorar a API, além de incluir detecção de colisão contínua. Box2D foi escrito em C++, e sua portabilidade é demonstrada pelas plataformas na qual é usado (Adobe® Flash®, Apple iPhone e iPad, Nintendo DS e Wii e Google Android). Box2D fornece a física por trás de vários jogos portáteis populares, incluindo Angry Birds e Crayon Physics Deluxe.
Box2D fornece uma simulação de corpo rígido que oferece suporte a figuras geométricas como círculos ou polígonos. Box2D pode unir figuras com juntas e inclui até mesmo motores e polias de juntas. Em Box2D, o mecanismo pode aplicar gravidade e fricção e gerenciar detecção de colisões e a dinâmica resultante.
Box2D é definido como uma API complexa que oferece diversos serviços. Esses serviços permitem a definição de um mundo habitado por vários objetos e atributos. Com os objetos e atributos definidos, simulamos em seguida o mundo em etapas de tempo discretas. Este aplicativo de amostra (baseado no aplicativo de amostra de Erin Catto) explora uma caixa arremessada em um mundo com gravidade.
A Listagem 1 ilustra o processo de criação de um mundo simples ocupado por uma caixa (com inércia para cima) e um plano do chão. O mundo e um vetor de gravidade para o mundo são definidos usando as funções de gravidade e mundo. O parâmetro true para o mundo simplesmente diz que se trata de um corpo em repouso e, portanto, não requer simulação.
Com o mundo definido, é especificado o corpo do chão no mundo e sua posição. O chão é uma caixa que é estática, o que o Box2D sabe por que a caixa tem massa zero (por padrão) e, portanto, não colide com outros objetos.
Em seguida, criamos um corpo dinâmico, que tem uma posição, velocidade linear inicial e ângulo. Essa configuração é semelhante à criação do corpo do chão, mas são definidos atributos adicionais para o corpo dinâmico. Esses atributos incluem a densidade do objeto e a fricção. O novo corpo dinâmico é incluído no mundo criando o suporte com CreateFixture.
Com o mundo e seus objetos definidos, podemos passar para a simulação. Começamos definindo a etapa de tempo da simulação (neste caso, 60 Hz). Também definimos o número de iterações a serem executadas, o que determina quantas vezes iterar cálculos de velocidade e posição (pois resolver um modifica os outros). Quanto mais iterações, maior a precisão obtida— e mais tempo é gasto nos cálculos.
Por fim, executamos a simulação, o que envolve realizar uma etapa na simulação por meio de uma chamada para o método Step para o mundo. Quando a chamada retorna para a etapa de tempo atual, as forças aplicadas sobre os objetos na última etapa são limpas e é obtida a posição e ângulo atuais do corpo dinâmico. Essas variáveis retornadas são emitidas para a saída padrão (stdout) para visualização. Continuamos a simulação até o corpo dinâmico ficar em repouso.
Listagem 1. Aplicativo simples usando Box2D (adaptado de HelloWorld de Erin Catto)
#include <Box2D/Box2D.h>
#include <cstdio>
int main()
{
// Define the gravity vector.
b2Vec2 gravity(0.0f, -10.0f);
// Construct a world object, which will hold and simulate the rigid bodies.
// Allow bodies to sleep.
b2World world(gravity, true);
// Define the ground body.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0.0f, -10.0f);
b2Body* groundBody = world.CreateBody(&groundBodyDef);
// Define the ground box shape.
b2PolygonShape groundBox;
groundBox.SetAsBox(50.0f, 10.0f);
// Add the ground fixture to the ground body.
groundBody->CreateFixture(&groundBox, 0.0f);
// Define the dynamic body. Set its position and call the body factory.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(0.0f, 4.0f);
bodyDef.linearVelocity.Set(5.0f, 5.0f);
bodyDef.angle = 0.25f * b2_pi;
b2Body* body = world.CreateBody(&bodyDef);
// Define another box shape for your dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(1.0f, 1.0f);
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
// Add the shape to the body.
body->CreateFixture(&fixtureDef);
float32 timeStep = 1.0f / 60.0f;
int32 velocityIterations = 6;
int32 positionIterations = 2;
do {
world.Step(timeStep, velocityIterations, positionIterations);
world.ClearForces();
b2Vec2 position = body->GetPosition();
float32 angle = body->GetAngle();
printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
} while (body->IsAwake());
return 0;
}
|
Box2D foi criado para não depender do renderizador (visualização gráfica). Uma renderização simples da posição da caixa (da Listagem 1,) é mostrada na Figura 2. Observe o comportamento da posição da caixa quando a gravidade a puxa para o chão e ela fica em repouso, e a colisão.
Figura 2. Renderização simples da posição da caixa da Listagem 1
Bullet é um mecanismo de física de 3D de software livre que oferece suporte a dinâmica de corpos moles e rígidos e detecção de colisão em 3D. Bullet foi desenvolvido por Erwin Coumans quando ele estava na Sony Computer Entertainment. O mecanismo é suportado por um grande número de plataformas, tais como Sony Playstation 3, Xbox 360®, iPhone e Wii. Inclui suporte para os sistemas operacionais Windows®, Linux® e Mac OS, bem como várias otimizações voltadas para a Cell Synergistic Processing Unit no Playstation 3 e a estrutura OpenCL no PC.
Bullet é um mecanismo de física de produção que tem amplo suporte em jogos e filmes. Alguns dos jogos que já usaram Bullet foram Red Dead Redemption, da Rockstar, e Free Realms (MMORPG), da Sony. Bullet também foi usado para efeitos especiais em alguns filmes comerciais, como "Esquadrão Classe A" (Weta Digital) e "Shrek 4" (DreamWorks).
Bullet inclui simulação de corpo rígido com detecção de colisão discreta e contínua, incluindo suporte para corpos moles (como tecidos ou outros objetos deformáveis). Como um mecanismo de produção, Bullet inclui API e SDK completos.
O exemplo de Bullet na Listagem 2 é o programa "Hello World" da distribuição do Bullet. Ele implementa uma simulação semelhante à demonstrada no exemplo do Box2D (mas, neste caso, em vez de uma caixa, uma esfera é usada como objeto em queda). Como seria de esperar, esta implementação é um pouco mais complexa que o exemplo anterior, devido à maior variedade e complexidade da API.
Este aplicativo simples é dividido em três segmentos: configuração, simulação e limpeza. A fase de configuração cria o mundo com o qual a fase de simulação trabalha. A fase de limpeza simplesmente desaloca os vários objetos no mundo.
Para criar o mundo, são necessários a definição de um algoritmo de fase ampla (uma otimização para identificar objetos que não devem colidir), uma configuração de colisão e um resolvedor de restrição (que incorpora gravidade e outras forças bem como colisões, e define como os objetos interagem). Também é preciso definir gravidade como o eixo y por meio de uma chamada para setGravity. Com esses elementos definidos, criamos o mundo. Os dois próximos segmentos na fase de configuração definem o corpo do chão estático e o corpo da esfera dinâmico.
A simulação é realizada chamando o método stepSimulation. Esse método define um intervalo de 60 Hz e simula a física por trás da queda da esfera para o chão sob a influência da gravidade. Após cada etapa da simulação, a altura da esfera (o parâmetro y) é emitida. O loop pela simulação permite que a esfera colida com o chão e entre em repouso.
A fase final é uma limpeza simples, que libera os objetos e outros elementos da memória.
Como mostrado, embora um volume considerável de configuração seja necessário para a simulação, após o ambiente ser definido, o mecanismo faz todo o trabalho pesado nos bastidores para nós. Bullet inclui uma API massiva, permitindo ajuste fino do ambiente e de seu comportamento, bem como um grande número de chamadas de retorno para eventos que ocorrem na simulação (como colisões e sobreposições).
Listagem 2. Simulação simples da queda de uma esfera usando Bullet
#include <iostream>
#include <btBulletDynamicsCommon.h>
int main (void)
{
// Setup
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btDefaultCollisionConfiguration* collisionConfiguration =
new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(
dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,-10,0));
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);
btCollisionShape* fallShape = new btSphereShape(1);
btDefaultMotionState* groundMotionState = new
btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
btRigidBody::btRigidBodyConstructionInfo
groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);
btDefaultMotionState* fallMotionState =
new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
btScalar mass = 1;
btVector3 fallInertia(0,0,0);
fallShape->calculateLocalInertia(mass,fallInertia);
btRigidBody::btRigidBodyConstructionInfo
fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld->addRigidBody(fallRigidBody);
// Simulation
for (int i=0 ; i<300 ; i++) {
dynamicsWorld->stepSimulation(1/60.f,10);
btTransform trans;
fallRigidBody->getMotionState()->getWorldTransform(trans);
std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
}
// Cleanup
dynamicsWorld->removeRigidBody(fallRigidBody);
delete fallRigidBody->getMotionState();
delete fallRigidBody;
dynamicsWorld->removeRigidBody(groundRigidBody);
delete groundRigidBody->getMotionState();
delete groundRigidBody;
delete fallShape;
delete groundShape;
delete dynamicsWorld;
delete solver;
delete collisionConfiguration;
delete dispatcher;
delete broadphase;
return 0;
}
|
Lista de mecanismos de física de software livre
Box2D e Bullet são dois exemplos de mecanismos de física úteis e amplamente usados. Mas há muitos outros exemplos que se concentram em diferentes aspectos da simulação física (desempenho ou precisão), além de usarem muitas licenças diferentes. Box2D e Bullet usam a licença Zlib (que oferece suporte a seu uso em aplicativos comerciais). Tabela 1 contém uma lista dos mecanismos de física de software livre mais comuns e as licenças que usam. Além disso, embora a maioria dos mecanismos suporte C++ ou C, muitos também suportam ligações para outras linguagens, como Ruby ou Python.
Tabela 1. Mecanismos de física de software livre
| Mecanismo | Tipo | Licença |
|---|---|---|
| Box2D | 2D | Zlib |
| Bullet | 3D | Zlib |
| Chipmunk | 2D | Massachusetts Institute of Technology (MIT) |
| Chrono::Engine | 3D | GPLv3 |
| DynaMo | 3D | GPL |
| Moby (Physsim) | 3D | GPLv2 |
| Newton Game Dynamics | 3D | Zlib |
| Open Dynamics Engine | 3D | BSD |
| Open Physics Abstraction Layer | Não disponível | BSD/LGPL |
| OpenTissue | 3D | Zlib |
| Physics Abstraction Layer (PAL) | Não disponível | BSD |
| Tokamak | 3D | BSD/Zlib |
Chipmunk, desenvolvido por Scott Lembcke com base em Box2D, inclui vários recursos para física 2D, incluindo suporte direto para
C bem como Objective-Chipmunk para suportar ligações para iPhone. Outras ligações incluem Ruby, Python e Haskell.
Tokamak é um SDK de física 3D criado em C++ por David Lam. Inclui algumas otimizações que minimizam a largura de banda de memória e, portanto, o tornam ideal para dispositivos menores móveis. Um recurso interessante do Tokamak é o suporte para quebra de modelo, no qual objetos compostos podem quebrar numa colisão, criando assim múltiplos objetos na simulação.
Embora listados como mecanismos de física, as camadas de abstração oferecem um recurso interessante que não deve ser ignorado. O PAL oferece uma interface unificada ao longo de vários mecanismos de física em um único aplicativo, permitindo que um desenvolvedor use facilmente o mecanismo de física certo para o aplicativo em particular sem os esforços da migração. A arquitetura de plugin do PAL suporta vários mecanismos de física de software livre líderes, como Box2D, Bullet, Newton Game Dynamics, OpenTissue, Tokamak e vários outros. Também suporta mecanismos comerciais como Havok, que é popular no desenvolvimento de jogos. A desvantagem de PAL é que ele pode restringir a funcionalidade oferecida por um mecanismo de física em particular, pois seu foco é em uma abstração comum.
A aceleração de hardware para física tem evoluído nos últimos anos, acompanhando uma tendência em graphics processing units (GPU). Uma GPU é um coprocessador de hardware que acelera cálculos para aplicativos de computação gráfica. GPUs evoluíram para general-purpose computing on graphics processing units (GPGPU), permitindo que sejam usadas em tarefas mais genéricas de aceleração. Um movimento por uma physics processing unit (PPU) para acelerar cálculos de mecanismo de física foi potencialmente retardado pelo uso de GPGPUs mais acessíveis. Exemplos de GPGPUs incluem a tecnologia Stream da ATI e a arquitetura Common Unified Device Architecture (CUDA) da NVIDIA.
Mecanismos de física dispensam o desenvolvimento de software complexo para implementar física e detecção de colisão em software. Em vez disso, o tempo pode ser investido no aplicativo em particular (jogo ou simulação). Embora seja útil entender a matemática por trás desses mecanismos, isso não é necessário para usá-los e aproveitá-los. A seção Recursos inclui links para vários mecanismos de física de software livre que podem ser usados facilmente em sistemas Linux e Windows. Cada um inclui demos ilustrativos de amostra para ajudar a entender suas APIs e conceitos, de modo que seja possível levar a física para seu aplicativo.
Aprender
-
Wikipédia: Physics engines: Saiba como mecanismos de física estão sendo segregados em classes de mecanismos para seus domínios de problema em particular. A Wikipédia é um ótimo recurso para saber mais sobre mecanismos de física, física de boneca de trapo, sistemas de partícula e simulação de computador. É possível saber mais sobre o mecanismo de física usado no Second Life além de algumas compensações pelo ambiente virtual.
-
Rigid Body Dynamics: Leia esta série de Chris Hecker se estiver interessado no funcionamento de um mecanismo de física. Essa série apareceu inicialmente em Game Developer Magazine.
- Building an Advanced Particle System, de John Van Der Burg, em Gamasutra: Saiba mais sobre o desenvolvimento de um sistema de partículas. Sistemas de partículas são uma aplicação interessante de um mecanismo de física, e partículas são geralmente um problema difícil com base na escala exigida.
-
Real-Time Collision Detection: Para saber mais sobre detecção de colisão, confira o livro de Christer Ericson, que abrange os detalhes do desenvolvimento de simulações realistas.
-
Demos on demand do developerWorks: Acompanhe demos que abrangem desde a instalação de produto e configuração para iniciantes a funcionalidade avançada para desenvolvedores experientes.
-
Zona de software livre: Visite a zona de softwares livres do developerWorks para amplas informações práticas, ferramentas e atualizações de projeto para ajudá-lo a desenvolver com tecnologias de software livre e usá-las com produtos IBM.
-
Eventos técnicos e webcasts do developerWorks: Mantenha-se atualizado com relação à tecnologia mais recente.
-
Podcasts do developerWorks: Ouça entrevistas e discussões interessantes para desenvolvedores de software.
Obter produtos e tecnologias
- Vários mecanismos de física focados em 2D podem ser encontrados no domínio de softwares livres. Opções incluem Box2D de Erin Catto (disponível pela licença Zlib) bem como Chipmunk de Scott Lembcke (disponível na licença do MIT). Para entender a API deles, confira a documentação do Box2D e documentação do Chipmunk.
- Um grande número de mecanismos de física focados em 3D está disponível como software livre. Opções incluem DynaMo, OpenTissue, Chrono::Engine e Tokamak. Também é possível aproveitar uma camada de abstração (como PAL) para suportar mais de um mecanismo de física sem o esforço de migração.
- Aceleração de hardware é uma área crescente de pesquisa e desenvolvimento. De GPUs
a GPGPUs (e PPUs), há um esforço considerável para aumentar a precisão e velocidade das simulações físicas. Aceleração comercial pode ser encontrada no
PhysXda NVIDIA, CUDA e tecnologia Stream da AMD/ATI .
-
Avalie os produtos IBM da maneira que for melhor para você: faça download da versão de teste de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na SOA Sandbox aprendendo a implementar Arquitetura Orientada a Serviços de forma eficiente.
Discutir
- Participe dos comunidade do My developerWorks. Conecte-se a outros usuários do developerWorks, ao mesmo tempo que explora os blogs, fóruns, grupos e wikis direcionados a desenvolvedores.

M. Tim Jones é arquiteto de firmware integrado e autor de Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming (agora em sua segunda edição), AI Application Programming (em sua segunda edição) e BSD Sockets Programming from a Multilanguage Perspective. Seu conhecimento em engenharia varia do desenvolvimento de kernels para naves espaciais geossíncronas até a arquitetura de sistemas embarcados e o desenvolvimento de protocolos de rede. Tim é arquiteto de plataforma da Intel e autor em Longmont, Colorado.