12/5/2011 Angry Birds Angry Birds uses the open source Box2D rigid body engine from: The Box2D Physics Engine http://box2d.org Ian Parberry 2 License.txt Copyright (c) 2006‐2010 Erin Catto http://www.gphysics.com This software is provided 'as‐is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. 3 4 5 6 1 12/5/2011 7 8 Box2D Core Concepts Shape: A 2D geometric object, eg. a circle or polygon. Rigid Body:A chunk of matter that is so strong that the distance between any two bits of matter on the chunk is constant. In the following discussion we use “body” interchangeably with “rigid body”. Fixture:A shape with material properties including density, friction, and restitution. 9 10 Box2D Core Concepts Box2D Core Concepts Constraint: A physical connection that removes Contact Constraint:A special constraint degrees of freedom from bodies. In 2D a body designed to prevent penetration of rigid bodies has 3 degrees of freedom (two translation and and to simulate friction and restitution. You do one rotation). If we take a body and pin it to the not create contact constraints; they are created wall (like a pendulum) we have constrained the automatically by Box2D. body to the wall. At this point the body can only rotate about the pin, so the constraint has removed 2 degrees of freedom. 11 12 2 12/5/2011 Box2D Core Concepts Box2D Core Concepts Joint: A constraint used to hold two or more bodies World: A collection of bodies, fixtures, and together. Box2D supports several jointtypes: constraints that interact together. Box2D revolute, prismatic, distance, and more. Some joints supports the creation of multiple worlds, but may have limits and motors. this is usually not necessary or desirable. Joint Limit: Restricts the range of motion of a joint. For example, the human elbow only allows a certain Solver:A device that resolves contact and joint range of angles. constraints. The Box2D solver is a high Joint Motor: Drives the motion of the connected performance iterative solver that operates in bodies according to the joint's degrees of freedom. (cid:1841)(cid:4666)(cid:1866)(cid:4667)time, where (cid:1866)is the number of For example, you can use a motor to drive the constraints. rotation of an elbow. 13 14 Box2D Core Concepts Tunneling Continuous Collision: The solver advances bodies in time using discrete time steps. Without intervention this can lead to tunneling. (cid:1872)(cid:3404)0 (cid:1872)(cid:3404)1 (cid:1872)(cid:3404)2 (cid:1872)(cid:3404)3 15 16 Tunneling Modules Box2D deals with tunnelingin Box2D is composed of 3 modules: two steps as follows: 1. The common module has code for Common 1. Interpolate the motion of allocation, math, and settings. the bodies to find their 2. The collision module defines first time of impact (TOI). shapes, a broad‐phase, and Collision (cid:1872)(cid:3404)2 (cid:1872)(cid:3404)3 collision functions/queries. 2. Move bodies to their first TOI and then resolve the 3. The dynamics module provides Dynamics the simulation world, bodies, collision. (cid:1872)(cid:3404)2.2 TOI fixtures, and joints. 17 18 3 12/5/2011 Units of Length Units of Angle • Beware of floating‐point round‐off error. • Box2D stores angles in radians. They are not • Bix2D been tuned to work well with meters‐ automatically normalized. kilogram‐second (MKS) units. In particular, • Use b2Body::SetAngleto normalize Box2D works well with moving objects angles. between 0.1 and 10 meters. • It may be tempting to use pixels as your units. Unfortunately this will lead to loss of precision resulting in a poor simulation and possibly weird behavior. 19 20 Factories Factory Functions Creation functions: • Box2D functions that create things such as bodies or joints are called factory functions. b2Body* b2World:: CreateBody(const b2BodyDef* def); • These are probably named from the software b2Joint* b2World:: engineering technique design patterns. CreateJoint(const b2JointDef* def); • For example, to create a b2Bodyor a Destruction functions: b2Joint, call the b2Worldfactory void b2World::DestroyBody(b2Body* body); functions on the next slide. void b2World::DestroyJoint(b2Joint* joint); • Box2D takes care of memory management. 21 22 Definitions Shortcut • Fixtures are created and destroyed by using There is also shortcut to create a fixture directly b2Body’s CreateFixtureand from its shape and density. DestroyFixturefunctions. • CreateFixturehas a single parameter of b2Fixture* b2Body::CreateFixture( type b2FixtureDefthat describes the fixture’s const b2Shape* shape, float32 density); properties. Factories do not retain references to the b2Fixture* b2Body::CreateFixture( const b2FixtureDef* def); definitions, so you can create definitions in local variables. void b2Body::DestroyFixture( b2Fixture* fixture); 23 24 4 12/5/2011 User Data Example • The b2Fixture, b2Body, and b2Joint For example, it is typical to attach an actor classes allow you to attach user data as a pointer to the rigid body on that actor. This sets up a circular reference. If you have the actor, voidpointer. you can get the body. If you have the body, you • This is handy when you are examining Box2D can get the actor. data structures and you want to determine how they relate to the entities in your game GameActor* actor = GameCreateActor(); b2BodyDef bodyDef; engine. bodyDef.userData = actor; actor->body = box2Dworld->CreateBody(&bodyDef); 25 26 Examples Caveat Here are some examples of cases where you • Keep in mind that user data is optional and you would need the user data: can put anything in it. • Applying damage to an actor using a collision • However, you should be consistent. For example, result. if you want to store an actor pointer on one body, • Playing a scripted event if the player is inside you should keep an actor pointer on all bodies. an axis‐aligned box. Don't store an actor pointer on one body, and a • Accessing a game structure when Box2D foo pointer on another body. Casting an actor notifies you that a joint is going to be pointer to a foo pointer may lead to a crash. destroyed. • User data pointers are NULLby default. 27 28 Creating a Physics World How to Create a Body Every Box2D program begins with the creation 1. Define a body with position, damping, etc. of a b2Worldobject. b2Worldis the physics 2. Use the world object to create the body. manager that takes care of objects, simulation, 3. Define fixtures with shape, friction, density, etc. and associated memory management. 4. Create fixtures on the body. b2Vec2 gravity(0.0f, -10.0f); Remember these, we’ll use them in an example on b2World world(gravity); the next 2 slides. Warning: The version 2.2.1 documentation says that the b2Worldconstructor has 2 parameters, but the code seems to allow only 1 parameter. 29 30 5 12/5/2011 Creating a Ground Body groundBody Creating a Ground Body groundBody 1. Define a body with position. 3. Define fixtures with shape, friction, density, etc. b2BodyDef groundBodyDef; b2PolygonShape groundBox; groundBodyDef.position.Set(0.0f, -10.0f); groundBox.SetAsBox(50.0f, 10.0f); 2. Use the world object to create the body. 4. Create fixture on the body using that definition. b2Body* groundBody = groundBody->CreateFixture(&groundBox, 0.0f); world.CreateBody(&groundBodyDef); (The second parameter is the shape density in kg/m(cid:2870). A static body has zero mass by definition, so the density is not used in this case.) 31 32 Creating a Dynamic Body Shape First we create the bodyusing CreateBody. Next we create and attach a polygon shape using a By default bodies are static, so we should set the fixture definition. First we create a box shape: b2BodyTypeat construction time to make the b2PolygonShape dynamicBox; dynamicBox.SetAsBox(1.0f, 1.0f); body dynamic. Next we create a fixture definition using the box. Notice that b2BodyDef bodyDef; we set density to 1.0. The default density is zero. Also, the bodyDef.type = b2_dynamicBody; friction on the shape is set to 0.3. bodyDef.position.Set(0.0f, 4.0f); b2Body* body = world.CreateBody(&bodyDef); b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f; 33 34 Create Fixture The Integrator We can now create the fixture using the fixture • An integratorsimulates the physics equation in discrete time. definition . This automatically updates the mass • Generally physics engines for games like a time step at of the body. You can add multiple fixtures to a least as fast as 60Hz or 1/60 seconds. body. Each one contributes to the total mass. • You can get away with larger time steps, but you will have to be more careful about setting up your world. body->CreateFixture(&fixtureDef); • A fixed time step means better convergence, and reproducible results (useful for debugging). • Don't tie the time step to the render frame rate. const float32 timeStep = 1.0f / 60.0f; 35 36 6 12/5/2011 The Constraint Solver Iteration Count • Theconstraint solver solves all the constraints in the • The position phase may exit early if errors are small. simulation, one at a time. • The suggested iteration count for Box2D is 8 for • The constraint solver has two phases: velocity and 3 for position. 1. In the velocity phase the solver computes the impulses necessary for the bodies to move correctly. int32 velocityIterations = 8; int32 positionIterations = 3; 2. In the position phase the solver adjusts the positions of the bodies to reduce overlap and joint detachment. • Note that the time step and the iteration count are • A single constraint can be solved perfectly. However, completely unrelated. An iteration is not a sub‐step. when we solve one constraint, we slightly disrupt other • One solver iteration is a single pass over all the constraints. To get a good solution, we need to iterate constraints within a time step. You can have multiple over all constraints a number of times. passes over the constraints within a single time step. 37 38 Simulation Loop Cleanup Here is the simulation loop that simulates 60time • When a world leaves scope or is deleted by steps for a total of 1 second of simulated time. calling delete on a pointer, all the memory reserved for bodies, fixtures, and joints is for(int32 i=0; i<60; i++){ world.Step(timeStep, velocityIterations, freed. This is done to improve performance positionIterations); and make your life easier. b2Vec2 p = body->GetPosition(); float32 a = body->GetAngle(); • However, you will need to nullify any body, //render body at (p.x, p.y) at angle a radians } fixture, or joint pointers you have because they will become invalid. 39 40 The Testbed The testbedis a unit‐testing framework and demo environment. Here are some of the features: • Camera with pan and zoom. • Mouse picking of shapes attached to dynamic bodies. • Extensible set of tests. • GUI for selecting tests, parameter tuning, and debug drawing. • Pause and single step simulation. • Text rendering. 41 42 7 12/5/2011 43 44 45 46 Adding Box2D to Your Game Summary • The process is a little hairy, beware! 1. Install Box2D Header Files • It’s a little idiosyncratic to Box2D. i. Copy Box2D folder from download ii. Paste into your devfolder • If you don’t follow these instructions carefully, iii. Add your devfolder to project include the compiler will not be able to find the directories (weird, but true) correct header files. iv. In your source code, • The alternative is editing a whole slew of #include <Box2D\Box2D.h> Box2D header files. 2. Change compiler code generation settings to Multi‐Threaded DLL 47 48 8 12/5/2011 Summary 1(i) Copy Box2D Folder From Download 3. Build and install the Box2D lib file Box2D.lib i. Open Box2D.slnfrom downloaded Box2D Build folder in Visual Studio Copy To ii. Build in Release mode (then close Visual Studio) iii. Copy Box2D.libfrom Build\vs10\bin\ Release iv. Make new lib folder in your devfolder v. Paste Box2D.libthere vi. Add that folder to compiler lib directories vii. Add Box2D.libto devproject 49 50 1(ii) Paste Into Your Dev Folder 1(iii) Add Your DevFolder to Include Directories (Yes, it sounds weird to add “.” here, but trust me.) 51 52 1(iv) #include Box2D.hLike This 2. Choose Multi‐Threaded DLL 53 54 9 12/5/2011 3(i) In Box2D Build Folder 3(ii) Build in Release Mode (If you didn’t already do this before when building the Testbed.) 55 56 3(iii) Copy Box2D.lib 3(iv) Make Lib Folder in Your DevFolder 57 58 3(v) Paste Box2D.lib There 3(vi) Add Folder to Library Directories 59 60 10
Description: