960 likes | 1.16k Views
PBox2D. 2013.5.16 lbg@dongseo.ac.kr. This presentation is based on the underline ppt file http ://pds21.egloos.com/ pds /201304/09/15/Class4-PhysicalLibrary.pptx. http://en.wikipedia.org/wiki/ Box2D. https:/ /box2d.org/. https://code.google.com/p/box2d /.
E N D
PBox2D 2013.5.16 lbg@dongseo.ac.kr This presentation is based on the underline ppt file http://pds21.egloos.com/pds/201304/09/15/Class4-PhysicalLibrary.pptx
iforce2d advanced topics http://www.iforce2d.net/b2dtut/
http://www.mrdoob.com/projects/chromeexperiments/google-gravity/http://www.mrdoob.com/projects/chromeexperiments/google-gravity/
What is the Box2D? • Open-Source 2D Physics Engine • C++ by Erin Catto for the Game Developer’s Conference in 2006. • Box2D site (http://www.box2d.org/) for reference • Crayon Physics • Angry Birds • JBox2D : Java Wrapper • Box2D site (http://www.jbox2d.org//) for reference. • Can be directly used in Processing • PBox2D : Processing Wrapper • Make it easy to use JBox2D • A layer library between JBox2D and Processing • a Processing Box2D “helper” library • PBox2D is not a Processing wrapper for all of Box2D • https://github.com/shiffman/PBox2D
Box2D Basics • In old physical simulation • SETUP: Create all the objects in our world. • DRAW: Calculate all the forces in our world. Apply all the forces to our objects (F = M * A). Update the locations of all the objects based on their acceleration. Draw all of our objects. • In Box2D • SETUP: Create all the objects in our world. • DRAW: Draw all of our objects.
Five core parts for using Box2D World: Manages the physics simulation. It knows everything about the overall coordinate space and also stores lists of every element in the world Body: Serves as the primary element in the Box2D world. It has a location. It has a velocity. Sound familiar? The Body is essentially the class we’ve been writing on our own in our vectors and forces examples. Shape: Keeps track of all the necessary collision geometry attached to a body. Fixture: Attaches a shape to a body and sets properties such as density, friction, and restitution. Joint: Acts as a connection between two bodies (or between one body and the world itself).
Box2D worlds How can we convert between them?
Set up the world PBox2D box2d; void setup() { box2d = new PBox2D(this); //Initializes a Box2D world with default settings box2d.createWorld(); }
Set up the Body //define the properties of the body we intend to make BodyDefbd = new BodyDef(); • Step 2: Configure the body definition. Vec2 center = box2d.coordPixelsToWorld(width/2,height/2)); bd.position.set(center); bd.fixedRotation = true; //Fixed, never rotating objects bd.linearDamping = 0.8; //Friction bd.angularDamping = 0.9; bd.bullet = true; //if it is FAST moving objects bd.type = BodyType.DYNAMIC; // body type Step 1: Define a body.
Damping A Damping node can be used to slow down a body (a Solid node with Physics). The speed of each body is reduced by the specified amount (between 0.0 and 1.0) every second. A value of 0.0 means "no slowing down" and value of 1.0 means a "complete stop", a value of 0.1 means that the speed should be decreased by 10 percent every second. A damped body will possibly come to rest and become disabled depending on the values specified in WorldInfo. Damping does not add any force in the simulation, it directly affects the velocity of the body. The damping effect is applied after all forces have been applied to the bodies. Damping can be used to reduce simulation instability.
Body types • Dynamic (BodyType.DYNAMIC) a “fully simulated” body. A dynamic body moves around the world, collides with other bodies, and responds to the forces in its environment. • Static (BodyType.STATIC) cannot move (as if it had an infinite mass). We’ll use static bodies for fixed platforms and boundaries. • Kinematic(BodyType.KINEMATIC) can be moved manually by setting its velocity directly. If you have a user-controlled object in your world, you can use a kinematic body. Note that kinematic bodies collide only with dynamic bodies and not with other static or kinematic ones.
Set up the Body • Step 3: Create the body. Body body = box2d.createBody(bd); • Step 4: Set any other conditions for the body’s starting state. body.setLinearVelocity(new Vec2(0,3)); body.setAngularVelocity(1.2);
Linking Shape with Body PolygonShapeps = new PolygonShape(); float box2Dw = box2d.scalarPixelsToWorld(150); float box2Dh = box2d.scalarPixelsToWorld(100); ps.setAsBox(box2Dw, box2Dh); Body does not have geometry We have to attach geometry shape to body with a Fixture We can attach multiple shapes to a single body in order to create more complex forms. Step 1: Define a shape
Width & Height height height width width Processing BOX2D
Step 2: Create a fixture. FixtureDeffd = new FixtureDef(); //The fixture is assigned the PolygonShape we just made. fd.shape = ps; fd.friction = 0.3; //The coefficient of friction for the shape, typically between 0 and 1 fd.restitution = 0.5; //The Shape’s restitution (i.e. elasticity), typically between 0 and 1 fd.density = 1.0; //The Shape’s density, measured in kilograms per meter squared • Step 3: Attach the shape to the body with the fixture. body.createFixture(fd); Or you can use the default fixture body.createFixture(ps,1); // Creates the Fixture and attaches the Shape with a density of 1
In summary Define a body using a BodyDefobject (set any properties, such as location). Create the Body object from the body definition. Define a Shape object using PolygonShape, CircleShape, or any other shape class. Define a fixture using FixtureDef and assign the fixture a shape (set any properties, such as friction, density, and restitution). Attach the shape to the body.
Shapes b2CircleShape circle; circle.m_p.Set(2.0f, 3.0f); circle.m_radius = 0.5f; // This defines a triangle in CCW order. b2Vec2 vertices[3]; vertices[0].Set(0.0f, 0.0f); vertices[1].Set(1.0f, 0.0f); vertices[2].Set(0.0f, 1.0f); int32 count = 3; b2PolygonShape polygon; polygon.Set(vertices, count); Circle Shapes Polygon Shapes
Shapes // This an edge shape with ghost vertices. b2Vec2 v0(1.7f, 0.0f); b2Vec2 v1(1.0f, 0.25f); b2Vec2 v2(0.0f, 0.0f); b2Vec2 v3(-1.7f, 0.4f); b2EdgeShape edge; edge.Set(v1, v2); edge.m_hasVertex0 = true; edge.m_hasVertex3 = true; edge.m_vertex0 = v0; edge.m_vertex3 = v3; Edge Shapes
Shapes // This a chain shape with isolated vertices b2Vec2 vs[4]; vs[0].Set(1.7f, 0.0f); vs[1].Set(1.0f, 0.25f); vs[2].Set(0.0f, 0.0f); vs[3].(-1.7f, 0.4f); b2ChainShape chain; chain.CreateChain(vs, 4); Chain Shapes
In processing term. //Step 1. Define the body. BodyDefbd = new BodyDef(); bd.position.set(box2d.coordPixelsToWorld(width/2,height/2)); //Step 2. Create the body. Body body = box2d.createBody(bd); //Step 3. Define the shape. PolygonShapeps = new PolygonShape(); float w = box2d.scalarPixelsToWorld(150); float h = box2d.scalarPixelsToWorld(100); ps.setAsBox(w, h) //Step 4. Define the fixture. FixtureDeffd = new FixtureDef(); fd.shape= ps; fd.density= 1; fd.friction= 0.3; fd.restitution= 0.5; //Step 5. Attach the shape to the body with the Fixture. body.createFixture(fd);
How can we keep tracking objects? • Use the arrayList (Dynamic array) • Exercise Making boxes on the fly whenever we move the box and put it on an arrayList.
Class Design // A rectangular box class Box { float x,y; float w,h; // Constructor Box(float x_, float y_) { x = x_; y = y_; w = 16; h = 16; } // Drawing the box void display() { fill(127); stroke(0); strokeWeight(2); rectMode(CENTER); rect(x,y,w,h); } } // A list for all of our rectangles ArrayList<Box> boxes; void setup() { size(800,200); smooth(); // Create ArrayLists boxes = new ArrayList<Box>(); } void draw() { background(255); // When the mouse is clicked, add a new Box object if (mousePressed) { Box p = new Box(mouseX,mouseY); boxes.add(p); } // Display all the boxes for (Box b: boxes) { b.display(); } }
Let’s put those boxes on the Box2D world class Box { Body body; float w,h; Box(float x, float y) { //initial position w = 16; h = 16; } display() { Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); pushMatrix(); translate(pos.x,pos.y); // Box2D coordinate system considers rotation in the opposite direction from Processing rotate(-a); fill(127); stroke(0); strokeWeight(2); rectMode(CENTER); rect(0,0,w,h); popMatrix(); } } // following the steps // Step 1. Define the body. // Step 2. Create the body.(bodyType=DYNAMIC) // Step 3. Define the shape. // Step 4. Define the fixture. // Step 5. Attach the shape to the body with the Fixture • Revise the Box class • Box size (8,8) • fd.density = 1; • fd.friction= 0.3; • fd.restitution= 0.5;
Main function • import pbox2d.*; • import org.jbox2d.collision.shapes.*; • import org.jbox2d.common.*; • import org.jbox2d.dynamics.*; • // A list for all of our rectangles • ArrayList<Box> boxes; • PBox2D box2d; • void setup() { • size(800, 200); • smooth(); • // Initialize and create the Box2D world • box2d = new PBox2D(this); • box2d.createWorld(); • // Create ArrayLists • boxes = new ArrayList<Box>(); • } • void draw() { • background(255); • // We must always step through time! • box2d.step(); • // When the mouse is clicked, add a new Box object • Box p = new Box(mouseX, mouseY); • boxes.add(p); • // Display all the boxes • for (Box b: boxes) { • b.display(); • } • }
Let’s put some boundaries. To create boundaries, we need to set BodyDef object’s type to STATIC.