summaryrefslogtreecommitdiff
path: root/Client/ThirdParty/Box2D/docs/hello.md
diff options
context:
space:
mode:
Diffstat (limited to 'Client/ThirdParty/Box2D/docs/hello.md')
-rw-r--r--Client/ThirdParty/Box2D/docs/hello.md246
1 files changed, 246 insertions, 0 deletions
diff --git a/Client/ThirdParty/Box2D/docs/hello.md b/Client/ThirdParty/Box2D/docs/hello.md
new file mode 100644
index 0000000..40d8de6
--- /dev/null
+++ b/Client/ThirdParty/Box2D/docs/hello.md
@@ -0,0 +1,246 @@
+# Hello Box2D
+In the distribution of Box2D is a Hello World project. The program
+creates a large ground box and a small dynamic box. This code does not
+contain any graphics. All you will see is text output in the console of
+the box's position over time.
+
+This is a good example of how to get up and running with Box2D.
+
+## Creating a World
+Every Box2D program begins with the creation of a b2World object.
+b2World is the physics hub that manages memory, objects, and simulation.
+You can allocate the physics world on the stack, heap, or data section.
+
+It is easy to create a Box2D world. First, we define the gravity vector.
+
+```cpp
+b2Vec2 gravity(0.0f, -10.0f);
+```
+
+Now we create the world object. Note that we are creating the world on
+the stack, so the world must remain in scope.
+
+```cpp
+b2World world(gravity);
+```
+
+So now we have our physics world, let's start adding some stuff to it.
+
+## Creating a Ground Box
+Bodies are built using the following steps:
+1. Define a body with position, damping, etc.
+2. Use the world object to create the body.
+3. Define fixtures with a shape, friction, density, etc.
+4. Create fixtures on the body.
+
+For step 1 we create the ground body. For this we need a body
+definition. With the body definition we specify the initial position of
+the ground body.
+
+```cpp
+b2BodyDef groundBodyDef;
+groundBodyDef.position.Set(0.0f, -10.0f);
+```
+
+For step 2 the body definition is passed to the world object to create
+the ground body. The world object does not keep a reference to the body
+definition. Bodies are static by default. Static bodies don't collide
+with other static bodies and are immovable.
+
+```cpp
+b2Body* groundBody = world.CreateBody(&groundBodyDef);
+```
+
+For step 3 we create a ground polygon. We use the SetAsBox shortcut to
+form the ground polygon into a box shape, with the box centered on the
+origin of the parent body.
+
+```cpp
+b2PolygonShape groundBox;
+groundBox.SetAsBox(50.0f, 10.0f);
+```
+
+The SetAsBox function takes the **half**-**width** and
+**half**-**height** (extents). So in this case the ground box is 100
+units wide (x-axis) and 20 units tall (y-axis). Box2D is tuned for
+meters, kilograms, and seconds. So you can consider the extents to be in
+meters. Box2D generally works best when objects are the size of typical
+real world objects. For example, a barrel is about 1 meter tall. Due to
+the limitations of floating point arithmetic, using Box2D to model the
+movement of glaciers or dust particles is not a good idea.
+
+We finish the ground body in step 4 by creating the shape fixture. For
+this step we have a shortcut. We do not have a need to alter the default
+fixture material properties, so we can pass the shape directly to the
+body without creating a fixture definition. Later we will see how to use
+a fixture definition for customized material properties. The second
+parameter is the shape density in kilograms per meter squared. A static
+body has zero mass by definition, so the density is not used in this
+case.
+
+```cpp
+groundBody->CreateFixture(&groundBox, 0.0f);
+```
+
+Box2D does not keep a reference to the shape. It clones the data into a
+new b2Shape object.
+
+Note that every fixture must have a parent body, even fixtures that are
+static. However, you can attach all static fixtures to a single static
+body.
+
+When you attach a shape to a body using a fixture, the shape's
+coordinates become local to the body. So when the body moves, so does
+the shape. A fixture's world transform is inherited from the parent
+body. A fixture does not have a transform independent of the body. So we
+don't move a shape around on the body. Moving or modifying a shape that
+is on a body is not supported. The reason is simple: a body with
+morphing shapes is not a rigid body, but Box2D is a rigid body engine.
+Many of the assumptions made in Box2D are based on the rigid body model.
+If this is violated many things will break
+
+## Creating a Dynamic Body
+So now we have a ground body. We can use the same technique to create a
+dynamic body. The main difference, besides dimensions, is that we must
+establish the dynamic body's mass properties.
+
+First we create the body using CreateBody. By default bodies are static,
+so we should set the b2BodyType at construction time to make the body
+dynamic.
+
+```cpp
+b2BodyDef bodyDef;
+bodyDef.type = b2_dynamicBody;
+bodyDef.position.Set(0.0f, 4.0f);
+b2Body* body = world.CreateBody(&bodyDef);
+```
+
+> **Caution**:
+> You must set the body type to b2_dynamicBody if you want the body to
+> move in response to forces.
+
+Next we create and attach a polygon shape using a fixture definition.
+First we create a box shape:
+
+```cpp
+b2PolygonShape dynamicBox;
+dynamicBox.SetAsBox(1.0f, 1.0f);
+```
+
+Next we create a fixture definition using the box. Notice that we set
+density to 1. The default density is zero. Also, the friction on the
+shape is set to 0.3.
+
+```cpp
+b2FixtureDef fixtureDef;
+fixtureDef.shape = &dynamicBox;
+fixtureDef.density = 1.0f;
+fixtureDef.friction = 0.3f;
+```
+
+> **Caution**:
+> A dynamic body should have at least one fixture with a non-zero density.
+> Otherwise you will get strange behavior.
+
+Using the fixture definition we can now create the fixture. This
+automatically updates the mass of the body. You can add as many fixtures
+as you like to a body. Each one contributes to the total mass.
+
+```cpp
+body->CreateFixture(&fixtureDef);
+```
+
+That's it for initialization. We are now ready to begin simulating.
+
+## Simulating the World
+So we have initialized the ground box and a dynamic box. Now we are
+ready to set Newton loose to do his thing. We just have a couple more
+issues to consider.
+
+Box2D uses a computational algorithm called an integrator. Integrators
+simulate the physics equations at discrete points of time. This goes
+along with the traditional game loop where we essentially have a flip
+book of movement on the screen. So we need to pick a time step for
+Box2D. Generally physics engines for games like a time step at least as
+fast as 60Hz or 1/60 seconds. You can get away with larger time steps,
+but you will have to be more careful about setting up the definitions
+for your world. We also don't like the time step to change much. A
+variable time step produces variable results, which makes it difficult
+to debug. So don't tie the time step to your frame rate (unless you
+really, really have to). Without further ado, here is the time step.
+
+```cpp
+float timeStep = 1.0f / 60.0f;
+```
+
+In addition to the integrator, Box2D also uses a larger bit of code
+called a constraint solver. The constraint solver solves all the
+constraints in the simulation, one at a time. A single constraint can be
+solved perfectly. However, when we solve one constraint, we slightly
+disrupt other constraints. To get a good solution, we need to iterate
+over all constraints a number of times.
+
+There are two phases in the constraint solver: a velocity phase and a
+position phase. In the velocity phase the solver computes the impulses
+necessary for the bodies to move correctly. In the position phase the
+solver adjusts the positions of the bodies to reduce overlap and joint
+detachment. Each phase has its own iteration count. In addition, the
+position phase may exit iterations early if the errors are small.
+
+The suggested iteration count for Box2D is 8 for velocity and 3 for
+position. You can tune this number to your liking, just keep in mind
+that this has a trade-off between performance and accuracy. Using fewer
+iterations increases performance but accuracy suffers. Likewise, using
+more iterations decreases performance but improves the quality of your
+simulation. For this simple example, we don't need much iteration. Here
+are our chosen iteration counts.
+
+```cpp
+int32 velocityIterations = 6;
+int32 positionIterations = 2;
+```
+
+Note that the time step and the iteration count are completely
+unrelated. An iteration is not a sub-step. One solver iteration is a
+single pass over all the constraints within a time step. You can have
+multiple passes over the constraints within a single time step.
+
+We are now ready to begin the simulation loop. In your game the
+simulation loop can be merged with your game loop. In each pass through
+your game loop you call b2World::Step. Just one call is usually enough,
+depending on your frame rate and your physics time step.
+
+The Hello World program was designed to be simple, so it has no
+graphical output. The code prints out the position and rotation of the
+dynamic body. Here is the simulation loop that simulates 60 time steps
+for a total of 1 second of simulated time.
+
+```cpp
+for (int32 i = 0; i < 60; ++i)
+{
+ world.Step(timeStep, velocityIterations, positionIterations);
+ b2Vec2 position = body->GetPosition();
+ float angle = body->GetAngle();
+ printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
+}
+```
+
+The output shows the box falling and landing on the ground box. Your
+output should look like this:
+
+```
+0.00 4.00 0.00
+0.00 3.99 0.00
+0.00 3.98 0.00
+...
+0.00 1.25 0.00
+0.00 1.13 0.00
+0.00 1.01 0.00
+```
+
+## Cleanup
+When a world leaves scope or is deleted by calling delete on a pointer,
+all the memory reserved for bodies, fixtures, and joints is freed. This
+is done to improve performance and make your life easier. However, you
+will need to nullify any body, fixture, or joint pointers you have
+because they will become invalid.