Skip to content

Commit 3e96863

Browse files
authored
Update documentation for 3.1 release (#898)
enable more warnings release notes improve character sample onGround logic
1 parent 9f3c5c9 commit 3e96863

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1363
-616
lines changed

.clang-format

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
Language: Cpp
88
BasedOnStyle: Microsoft
99

10-
# BreakBeforeBraces: Allman
1110
BreakBeforeBraces: Custom
1211
BraceWrapping:
1312
AfterCaseLabel: true
1413
AfterUnion: true
1514
BeforeWhile: true
16-
# BreakBeforeBinaryOperators: All
1715

1816
ColumnLimit: 130
1917
PointerAlignment: Left
@@ -33,13 +31,9 @@ IncludeCategories:
3331

3432
IndentExternBlock: NoIndent
3533
IndentCaseLabels: true
36-
#IndentPPDirectives: None
3734
IndentAccessModifiers: false
3835
AccessModifierOffset: -4
3936

40-
# AlignArrayOfStructures: Left
41-
# AlignAfterOpenBracket: BlockIndent
42-
4337
SpacesInParens: Custom
4438
SpacesInParensOptions:
4539
Other: true

docs/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ doxygen_add_docs(doc
4545
"collision.md"
4646
"simulation.md"
4747
"loose_ends.md"
48+
"character.md"
4849
"reading.md"
4950
"faq.md"
5051
"migration.md"
52+
"release_notes_v310.md"
5153
ALL
5254
COMMENT "Generate HTML documentation")

docs/FAQ.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@ should be included if possible. Support is [appreciated](https://github.com/spon
99
Box2D [logo](https://box2d.org/images/logo.svg).
1010

1111
## What platforms does Box2D support?
12-
Box2D is developed using C17. Ports and bindings are likely available for most languages and platforms.
12+
Box2D is developed using C. Ports and bindings are likely available for most languages and platforms.
1313

14-
Erin Catto maintains the C17 version, but provides no support for other languages. Other languages are supported
14+
Erin Catto maintains the C version, but provides no support for other languages. Other languages are supported
1515
by the community and possibly by the authors of those ports.
1616

1717
## Who makes it?
18-
Erin Catto is the creator and sole contributor of the C17 version of Box2D, with various others supporting the ports. Box2D is an open source project, and accepts community feedback.
18+
Erin Catto is the creator and sole contributor of the C version of Box2D, with various others supporting the ports. Box2D is an open source project, and accepts community feedback.
1919

2020
## How do I get help?
2121
You should read the documentation and the rest of this FAQ first. Also, you should study the examples included in the source distribution. Then you can visit the [Discord](https://discord.gg/aM4mRKxW) to ask any remaining questions.
2222

23-
Please to not message or email Erin Catto for support. It is best to ask questions on the Discord server so that everyone can benefit from the discussion.
23+
Please to not message or email Erin Catto directly for support. It is best to ask questions on the Discord server so that everyone can benefit from the discussion.
2424

2525
## Documentation
2626

2727
### Why isn't a feature documented?
28-
If you grab the latest code from the git master branch you will likely find features that are not documented in the manual. New features are added to the manual after they are mature and a new point release is imminent. However, all major features added to Box2D are accompanied by example code in the samples application to test the feature and show the intended usage.
28+
If you grab the latest code from the git main branch you will likely find features that are not documented in the manual. New features are added to the manual after they are mature and a new point release is imminent. However, all major features added to Box2D are accompanied by example code in the samples application to test the feature and show the intended usage.
2929

3030
## Prerequisites
3131

@@ -106,9 +106,9 @@ For the same input, and same binary, Box2D will reproduce any simulation. Box2D
106106

107107
Box2D is also deterministic under multithreading. A simulation using two threads will give the same result as eight threads.
108108

109-
However, people often want more stringent determinism. People often want to know if Box2D can produce identical results on different binaries and on different platforms. Currently this is not provided, but the situation may improve in a future update.
109+
Box2D has cross-platform determinism as of version 3.1.
110110

111-
todo update here on cross-platform determinism
111+
However, Box2D does not have rollback determinism.
112112

113113
### But I really want determinism
114114
This naturally leads to the question of fixed-point math. Box2D does not support fixed-point math. In the past Box2D was ported to the NDS in fixed-point and apparently it worked okay. Fixed-point math is slower and more tedious to develop, so I have chosen not to use fixed-point for the development of Box2D.

docs/character.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Character mover
2+
3+
> **Caution**:
4+
> The character mover feature is new to version 3.1 and should be considered experimental.
5+
6+
Box2D provides a few structures and functions you can use to build a character mover.
7+
8+
These features support a `geometric` character mover. This is like
9+
a `kinematic` mover except the character mover is not a rigid body and does
10+
not exist in the simulation world. This is done to achieve features that
11+
would be difficult with a kinematic body.
12+
13+
This type of mover may not be suitable for your game. It is less physical than a rigid body, but
14+
it gives you more control over the movement. It is the type of mover you might find
15+
in a first-person shooter or a game with platforming elements.
16+
17+
The mover is assumed to be a capsule. Using a capsule helps keep movement smooth. The capsule should
18+
have a significant radius. It does not have to be a vertical capsule, but that is likely
19+
to be the easiest setup. There is no explicit handling of rotation. But slow rotation can
20+
work with this system.
21+
22+
Let's review the features. First there are a couple world query functions.
23+
24+
`b2World_CastMover()` is a custom shape cast that tries to avoid getting stuck when shapes start out touching.
25+
The feature is called _encroachment_. Since the capsule has a significant radius it can move closer
26+
to a surface it is touching without the inner line segment generating an overlap, which would cause
27+
the shape cast to fail. Due to the internal use of GJK, encroachment has little cost. The idea with encroachment is that
28+
the mover is trying to slide along a surface and we don't want to stop that even if there is some small movement into the surface.
29+
30+
`b2World_CollideMover()` complements the cast function. This function generates collision planes for touching and/or overlapped surfaces. The character mover is assumed to have a fixed rotation, so it doesn't need contact manifolds or contact points. It just needs collision planes. Each plane is returned with the `b2Plane` and a `b2ShapeId` for each shape the mover is touching.
31+
32+
Once you have some collision planes from `b2World_CollideMover()`, you can process and filter them to generate an array of `b2CollisionPlane`. These collision planes can then be sent to `b2SolvePlanes()` to generate a new position for the mover
33+
that attempts to find the optimal new position given the current position.
34+
35+
These collision planes support *soft collision* using a `pushLimit`. This push limit is a distance value. A rigid surface will have a push limit of `FLT_MAX`. However, you may want some surfaces to have a limited effect on the character. For example, you may want the mover to push through other players or enemies yet still resolve the collision so they are not overlapped. Another example is a door or elevator that could otherwise push the mover through the floor.
36+
37+
Finally after calling `b2SolverPlanes()` you can call `b2ClipVector()` to clip your velocity vector so the mover will not keep trying to push into a wall, which could lead to a huge velocity accumulation otherwise.
38+
39+
The `Mover` sample shows all these functions being used together. It also includes other common character features such as acceleration and friction, jumping, and a pogo stick.
40+
41+
![Character Mover](images/mover.png)

docs/collision.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Collision
22
Box2D provides geometric types and functions. These include:
3-
- raw geometry: circles, capsules, segments, and convex polygons
3+
- primitives: circles, capsules, segments, and convex polygons
44
- convex hull and related helper functions
55
- mass and bounding box computation
66
- local ray and shape casts
77
- contact manifolds
88
- shape distance
9-
- generic shape cast
109
- time of impact
1110
- dynamic bounding volume tree
11+
- character movement solver
1212

1313
The collision interface is designed to be usable outside of rigid body simulation.
1414
For example, you can use the dynamic tree for other aspects of your game besides physics.
@@ -25,7 +25,7 @@ primitives that can be later attached to rigid bodies.
2525
Box2D shape primitives support several operations:
2626
- Test a point for overlap with the primitive
2727
- Perform a ray cast against the primitive
28-
- Compute the primitive's AABB
28+
- Compute the primitive's bounding box
2929
- Compute the mass properties of the primitive
3030

3131
### Circles
@@ -78,7 +78,7 @@ The polygon members are public, but you should use initialization
7878
functions to create a polygon. The initialization functions create
7979
normal vectors and perform validation.
8080
81-
Polygons in Box2D have a maximum of 8 vertices, as controlled by #b2_maxPolygonVertices.
81+
Polygons in Box2D have a maximum of 8 vertices, as controlled by #B2_MAX_POLYGON_VERTICES.
8282
If you have more complex shapes, I recommend to use multiple polygons.
8383
8484
There are a few ways to create polygons. You can attempt to create them manually,
@@ -97,19 +97,21 @@ This corresponds with circles and capsules using radii instead of diameters.
9797
Box2D also supports rounded polygons. These are convex polygons with a thick rounded skin.
9898

9999
```c
100-
b2Polygon roundedBox = b2MakeRoundedBox(0.5f, 1.0f, 0.25f);
100+
float radius = 0.25f;
101+
b2Polygon roundedBox = b2MakeRoundedBox(0.5f, 1.0f, radius);
101102
```
102103

103104
If you want a box that is not centered on the body origin, you can use an offset box.
104105

105106
```c
106107
b2Vec2 center = {1.0f, 0.0f};
107108
float angle = b2_pi / 4.0f;
108-
b2Polygon offsetBox = b2MakeOffsetBox(0.5f, 1.0f, center, angle);
109+
b2Rot rotation = b2MakeRot(angle);
110+
b2Polygon offsetBox = b2MakeOffsetBox(0.5f, 1.0f, center, rotation);
109111
```
110112
111113
If you want a more general convex polygon, you can compute the hull using `b2ComputeHull()`. Then you can
112-
create a polygon from the hull. You can make this rounded or not.
114+
create a polygon from the hull. You can make this rounded as well.
113115
114116
```c
115117
b2Vec2 points[] = {{-1.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}};
@@ -210,7 +212,7 @@ You can cast a ray at a shape to get the point of first intersection and normal
210212
> consistent with Box2D treating convex shapes as solid.
211213
212214
```c
213-
b2RayCastInput input;
215+
b2RayCastInput input = {0};
214216
input.origin = (b2Vec2){0.0f, 0.0f};
215217
input.translation = (b2Vec2){1.0f, 0.0f};
216218
input.maxFraction = 1.0f;
@@ -226,7 +228,7 @@ if (output.hit == true)
226228
You can also cast a shape at another shape. This uses an abstract way of describing the moving shape. It is represented as a point cloud with a radius. This implies a convex shape even if the input data is not convex. The internal algorithm (GJK) will essentially only use the convex portion.
227229

228230
```c
229-
b2ShapeCastInput input;
231+
b2ShapeCastInput input = {0};
230232
input.points[0] = (b2Vec2){1.0f, 0.0f};
231233
input.points[1] = (b2Vec2){2.0f, -3.0f};
232234
input.radius = 0.2f;

docs/extra.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ body {
2020
}
2121

2222
div.contents {
23-
max-width: 900px;
23+
max-width: 1000px;
2424
}
2525

2626
/* this works with doxygen /image */

docs/foundation.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,18 @@ So when you design your game loop, you should let Box2D *go wide* and use multip
5454
In a multithreaded environment you must be careful to avoid [race conditions](https://en.wikipedia.org/wiki/Race_condition). Modifying the world while it is simulating will lead to unpredictable behavior and this is never safe. It is also not safe to read data from a Box2D world while it is simulating. Box2D may move data structures to improve cache performance. So it is very likely that you will read garbage data.
5555
5656
> **Caution**:
57-
> Do not read or write the Box2D world during `b2World_Step()`
57+
> Do not perform read or write operations on a Box2D world during `b2World_Step()`
5858
5959
> **Caution**:
6060
> Do not write to the Box2D world from multiple threads
6161
6262
It *is safe* to do ray-casts, shape-casts, and overlap tests from multiple threads outside of `b2World_Step()`. Generally, any read-only operation is safe to do multithreaded outside of `b2World_Step()`. This can be very useful if you have multithreaded game logic.
63+
64+
## Multithreading Multiple Worlds
65+
Some applications may wish to create multiple Box2D worlds and simulate them on different threads. This works fine because Box2D has very limited use of globals.
66+
67+
There are a few caveats:
68+
- You will get a race condition if you create or destroy Box2D worlds from multiple threads. You should use a mutex to guard this.
69+
- If you will simulate multiple Box2D worlds simultaneously, then they should probably not use a task system. Otherwise you're likely to get preemption.
70+
- Any callbacks you hook up to Box2D must be thread-safe, such as memory allocators.
71+
- All of the limitations for single world simulation still apply.

docs/hello.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ meters, kilograms, and seconds. So you can consider the extents to be in
8080
meters. Box2D generally works best when objects are the size of typical
8181
real world objects. For example, a barrel is about 1 meter tall. Due to
8282
the limitations of floating point arithmetic, using Box2D to model the
83-
movement of glaciers or dust particles is not a good idea.
83+
movement of glaciers or dust particles might not work well.
8484

8585
I'll finish the ground body in step 4 by creating the shape. For this step
8686
I need to create a shape definition which works fine with the default value.
@@ -104,8 +104,8 @@ don't move a shape around on the body. Moving or modifying a shape that
104104
is on a body is possible with certain functions, but it should not be part
105105
of normal simulation. The reason is simple: a body with
106106
morphing shapes is not a rigid body, but Box2D is a rigid body engine.
107-
Many of the algorithms in Box2D are based on the rigid body model.
108-
If this is violated you may get unexpected behavior.
107+
Many of the algorithms in Box2D are based on the rigid body model and optimized with
108+
that in mind. If this is violated you may get unexpected behavior.
109109
110110
## Creating a Dynamic Body
111111
I can use the same technique to create a
@@ -139,12 +139,12 @@ b2Polygon dynamicBox = b2MakeBox(1.0f, 1.0f);
139139

140140
Next I create a shape definition for the box. Notice that I set
141141
density to 1. The default density is 1, so this is unnecessary. Also,
142-
the friction on the shape is set to 0.3.
142+
the friction on the surface material is set to 0.3.
143143

144144
```c
145145
b2ShapeDef shapeDef = b2DefaultShapeDef();
146146
shapeDef.density = 1.0f;
147-
shapeDef.friction = 0.3f;
147+
shapeDef.material.friction = 0.3f;
148148
```
149149

150150
> **Caution**:
@@ -204,10 +204,10 @@ simulation. For this example, I will use 4 sub-steps.
204204
int subStepCount = 4;
205205
```
206206

207-
Note that the time step and the sub-step count are related. As the time-step
207+
Note that the time step and the sub-step count are related. As the time step
208208
decreases, the size of the sub-steps also decreases. For example, at 60Hz
209209
time step and 4 sub-steps, the sub-steps operate at 240Hz. With 8 sub-steps
210-
the sub-step is 480Hz!
210+
the sub-step is 480Hz.
211211

212212
We are now ready to begin the simulation loop. In your game the
213213
simulation loop can be merged with your game loop. In each pass through
@@ -231,6 +231,10 @@ for (int i = 0; i < 90; ++i)
231231
}
232232
```
233233

234+
Notice that the rotation of the body is returned in a `b2Rot` struct (short for rotation). This
235+
struct holds the rotation in a format that is fast for simulation. You may use `b2Rot_GetAngle`
236+
to get the rotation in radians.
237+
234238
The output shows the box falling and landing on the ground box. Your
235239
output should look like this:
236240

docs/images/mover.png

71.3 KB
Loading

0 commit comments

Comments
 (0)